00001 #ifndef PERSISTANCE_H
00002 #define PERSISTANCE_H
00003
00004
00005 #ifndef ENABLE_PERSISTANCE
00006
00007 # include "persistance-noop.h"
00008
00009 #else
00010
00011 #include <vector>
00012 #include <iterator>
00013 #include "hash_set.h"
00014 #include "hash_map.h"
00015 #include "iterator_wrapper.h"
00016 #include "assert.h"
00017 #include <limits>
00018
00019 class PersistantObject;
00020
00021 namespace hashers {
00022 template <> struct hash<PersistantObject*> {
00023 unsigned long operator() (const PersistantObject* obj) const {
00024 return (unsigned long)(obj);
00025 }
00026 };
00027 template <> struct hash<const PersistantObject*> {
00028 unsigned long operator() (const PersistantObject* obj) const {
00029 return (unsigned long)(obj);
00030 }
00031 };
00032 };
00033
00047 class PersistantStore {
00048 friend class PersistantObject;
00049 public:
00050 PersistantStore ();
00051 int add_checkpoint();
00052 void set_view(int);
00053 void set_view_current();
00054 void undo();
00055 void commit();
00056
00057 int get_time() const;
00058 bool viewing_current() const;
00059 bool logging() const;
00060 bool logging_after_pop() const;
00061
00062 private:
00068 void notify_access(PersistantObject* data);
00069
00076 void notify_born(PersistantObject* data);
00077
00083 void notify_died(PersistantObject* data);
00084
00091 typedef hashers::hash_set<PersistantObject*> ModifySet;
00092 std::vector<ModifySet> modifications_;
00093 std::vector<ModifySet> births_;
00094 ModifySet died_in_pop_;
00095
00096 int current_view_;
00097
00098
00099 bool popping_;
00100
00101
00102 PersistantStore(const PersistantStore&);
00103 PersistantStore& operator = (const PersistantStore&);
00104 };
00105
00110 class PersistantObject {
00111 public:
00112
00113 PersistantStore& get_store() const {
00114 return store_;
00115 }
00116
00117 protected:
00118 friend class PersistantStore;
00119
00120 PersistantObject(PersistantStore& store) : store_(store) {
00121 store_.notify_born(this);
00122 }
00123
00124 virtual ~PersistantObject() {
00125 store_.notify_died(this);
00126 }
00127
00129 virtual void undo() = 0;
00130
00132 virtual void commit() = 0;
00133
00136 virtual void preincarnate() = 0;
00137
00141 void notify_access() { store_.notify_access(this); }
00142
00144 int current_view() const { return store_.current_view_; }
00145
00147 int logging() const { return store_.logging(); }
00148
00151 int logging_after_pop() const { return store_.logging_after_pop(); }
00152
00153 private:
00154 PersistantStore& store_;
00155
00156
00157 PersistantObject(const PersistantObject&);
00158 PersistantObject& operator = (const PersistantObject&);
00159 };
00160
00165 template <class datum_type, bool copy_on_push> class StackPersistantObject
00166 : public PersistantObject
00167 {
00168 protected:
00169 struct timed_entry {
00170 int time;
00171 datum_type datum;
00172 timed_entry(int t, const datum_type& d) :
00173 time(t), datum(d) { }
00174 };
00175
00176 StackPersistantObject(PersistantStore& store,
00177 const datum_type& initial)
00178 : PersistantObject(store)
00179 {
00180 data_.push_back(timed_entry(store.get_time(), initial));
00181 }
00182 virtual ~StackPersistantObject() { }
00183
00184 datum_type& get_handle() {
00185 int time = current_view();
00186 if (data_.back().time != time) {
00187
00188
00189
00190 notify_access();
00191 assert(data_.back().time < time);
00192 if(copy_on_push) {
00193 data_.push_back(timed_entry(time, data_.back().datum));
00194 } else {
00195 data_.push_back(timed_entry(time, datum_type()));
00196 }
00197 }
00198 return data_.back().datum;
00199 }
00200
00201 int get_current_index() const {
00202 int time = current_view();
00203 for (int idx = data_.size() - 1; idx >= 0; idx--) {
00204 if (data_[idx].time <= time) {
00205 return idx;
00206 }
00207 }
00208 assert(0);
00209 return -1;
00210 }
00211
00217 virtual void merge_times(datum_type& older, const datum_type& newer) = 0;
00218
00219 private:
00226 virtual void commit() {
00227 assert(data_.size() >= 2);
00228 timed_entry& newer = data_[data_.size() - 1];
00229 timed_entry& older = data_[data_.size() - 2];
00230 int timestep_after_commit = newer.time - 1;
00231 if (older.time == timestep_after_commit) {
00232 merge_times(older.datum, newer.datum);
00233 data_.pop_back();
00234 } else {
00235 newer.time = timestep_after_commit;
00236 }
00237 }
00238
00239 virtual void preincarnate() {
00240
00241 assert(data_.size() == 1);
00242 data_[0].time--;
00243 }
00244
00245 protected:
00246 std::vector<timed_entry> data_;
00247
00248 private:
00249
00250 StackPersistantObject(const StackPersistantObject&);
00251 StackPersistantObject& operator = (const StackPersistantObject&);
00252 };
00253
00254
00260 template <class Datum> class PersistantData
00261 : public StackPersistantObject<Datum, true> {
00262 public:
00263 PersistantData (PersistantStore& store, const Datum& initial)
00264 : StackPersistantObject<Datum, true>(store, initial)
00265 { }
00266 virtual ~PersistantData() { }
00267
00268 const Datum& operator *() const {
00269 return this->data_[this->get_current_index()].datum;
00270 }
00271
00272 Datum& access() {
00273 return this->get_handle();
00274 }
00275
00276 protected:
00277 virtual void undo() {
00278 this->data_.pop_back();
00279 }
00280 virtual void merge_times(Datum& older, const Datum& newer) {
00281
00282 older = newer;
00283 }
00284
00285 private:
00286
00287 PersistantData(const PersistantData&);
00288 PersistantData& operator = (const PersistantData&);
00289 };
00290
00301 template <class Datum, int n> class PersistantArray {
00302 private:
00303 PersistantData<Datum> *data_[n];
00304
00305 public:
00306
00307
00308 PersistantArray(PersistantStore& store) {
00309 for(int i = 0; i < n; i++) {
00310 data_[i] = new PersistantData<Datum>(store, Datum());
00311 }
00312 }
00313
00314
00315 PersistantArray(PersistantStore& store, const Datum& initial) {
00316 for(int i = 0; i < n; i++) {
00317 data_[i] = new PersistantData<Datum>(store, initial);
00318 }
00319 }
00320
00321 ~PersistantArray() {
00322 for(int i = 0; i < n; i++) {
00323 delete data_[i];
00324 }
00325 }
00326
00327 const Datum& operator[] (int i) const {
00328 return **data_[i];
00329 }
00330 Datum& access (int i) {
00331 return data_[i]->access();
00332 }
00333
00334 class iterator : public Tumble::iterators::dedereferencer<PersistantData<Datum>**, Datum, const Datum&> {
00335 private:
00336 typedef Tumble::iterators::dedereferencer<PersistantData<Datum>**, Datum, const Datum&> super;
00337 public:
00338 iterator() { }
00339 iterator(PersistantData<Datum>** it) : super(it) { }
00340 iterator(PersistantArray& array) : super(array.begin()) { }
00341 };
00342 class const_iterator : public Tumble::iterators::dedereferencer<const PersistantData<Datum>* const *, const Datum> {
00343 private:
00344 typedef Tumble::iterators::dedereferencer<const PersistantData<Datum>*const *, const Datum> super;
00345 public:
00346 const_iterator() { }
00347 const_iterator(const PersistantData<Datum>* const * it) : super(it) { }
00348 const_iterator(const PersistantArray& array) : super(array.begin()) { }
00349 };
00350
00351 iterator begin() { return data_; }
00352 const_iterator begin() const { return data_; }
00353 iterator end() { return data_ + n; }
00354 const_iterator end() const { return data_ + n; }
00355
00356 iterator operator+ (int i) {
00357 assert(i <= n);
00358 return iterator(data_ + i);
00359 }
00360 const_iterator operator+ (int i) const {
00361 assert(i <= n);
00362 return const_iterator(data_ + i);
00363 }
00364
00365 private:
00366
00367 PersistantArray(const PersistantArray&);
00368 PersistantArray& operator = (const PersistantArray&);
00369 };
00370
00371 template <class Datum> class PersistantVector {
00372 public:
00373
00374 typedef typename std::vector<Datum>::value_type value_type;
00375 typedef typename std::vector<Datum>::pointer pointer;
00376 typedef typename std::vector<Datum>::reference reference;
00377 typedef typename std::vector<Datum>::const_reference const_reference;
00378 typedef typename std::vector<Datum>::size_type size_type;
00379 typedef typename std::vector<Datum>::difference_type difference_type;
00380
00381 typedef Tumble::iterators::dedereferencer<PersistantData<Datum>**, value_type, const_reference> iterator;
00382 typedef Tumble::iterators::dedereferencer<const PersistantData<Datum>*const *, value_type, const_reference> const_iterator;
00383
00384
00385
00386 iterator begin() { return iterator(data_); }
00387 iterator end() { return iterator(data_ + size()); }
00388
00389 const_iterator begin() const { return const_iterator(data_); }
00390 const_iterator end() const { return const_iterator(data_ + size()); }
00391
00392
00393
00394 size_type size() const { return *size_; }
00395 size_type max_size() const { return std::numeric_limits<int>::max(); }
00396 size_type capacity() const { return allocated_size_; }
00397 bool empty() const { return size() == 0; }
00398
00399
00400
00401 reference access(size_type i) {
00402 assert(i < size());
00403 if (data_[i] == NULL) {
00404 data_[i] = new PersistantData<value_type>(get_store(), Datum());
00405 }
00406 return data_[i]->access();
00407 }
00408
00409 const_reference operator[](size_type i) const {
00410 assert(i < size());
00411 return **(data_[i]);
00412 }
00413
00414 PersistantVector(PersistantStore& store) :
00415 size_(store, 0), data_(NULL), allocated_size_(0) { }
00416
00417 PersistantVector(PersistantStore& store, size_type n) :
00418 size_(store, 0), data_(NULL), allocated_size_(0) {
00419 reserve(n);
00420 for(size_type i = 0; i < n; i++) {
00421 data_[i] = new PersistantData<Datum>(get_store(), Datum());
00422 }
00423 size_.access() = n;
00424 }
00425
00426 PersistantVector(PersistantStore& store, size_type n, const Datum& t) :
00427 size_(store, 0), data_(NULL), allocated_size_(0) {
00428 reserve(n);
00429 for(size_type i = 0; i < n; i++) {
00430 data_[i] = new PersistantData<Datum>(get_store(), t);
00431 }
00432 size_.access() = n;
00433 }
00434
00435 template <class InputIterator>
00436 PersistantVector(PersistantStore& store, InputIterator begin,
00437 InputIterator end) :
00438 size_(store, 0), data_(NULL), allocated_size_(0) {
00439 for( ; begin != end; ++begin) {
00440 push_back(*begin);
00441 }
00442 }
00443
00444 ~PersistantVector() {
00445 for(size_type i = 0; i < allocated_size_; i++) {
00446 delete data_[i];
00447 }
00448 delete[] data_;
00449 }
00450
00451 void reserve(size_type sz) {
00452 if (sz <= allocated_size_) {
00453 return;
00454 }
00455 size_type oldalloc = allocated_size_;
00456 PersistantData<value_type> **olddata = data_;
00457
00458 allocated_size_ = sz;
00459 data_ = new PersistantData<value_type>* [sz];
00460 for(size_type i = 0; i < oldalloc; i++) {
00461 data_[i] = olddata[i];
00462 }
00463 for(size_type i = oldalloc; i < sz; i++) {
00464 data_[i] = NULL;
00465 }
00466 delete[] olddata;
00467 }
00468
00469 reference access_front() {
00470 return access(0);
00471 }
00472 const_reference front() const {
00473 return operator[] (0);
00474 }
00475
00476 reference access_back() {
00477 return access(size() - 1);
00478 }
00479
00480 const_reference back() const {
00481 return operator[] (size() - 1);
00482 }
00483
00484 void push_back(const Datum& d) {
00485 size_type sz = size();
00486 ensure_capacity(sz + 1);
00487 if (data_[sz] == NULL) {
00488 data_[sz] = new PersistantData<value_type> (get_store(), d);
00489 } else {
00490 data_[sz]->access() = d;
00491 }
00492 ++size_.access();
00493 }
00494
00495 void pop_back() {
00496 --size_.access();
00497 }
00498
00499 iterator insert(iterator pos, const Datum& x) {
00500 if (pos == end()) {
00501 push_back(x);
00502 }
00503 else {
00504 difference_type index = pos - begin();
00505 assert(index >= 0); assert(index < size());
00506 push_back(back());
00507 for(size_type i = size() - 1; i > index; i--) {
00508 access(i) = operator[](i - 1);
00509 }
00510 access(index) = x;
00511 }
00512 }
00513
00524 iterator erase(iterator pos) {
00525 difference_type index = pos - begin();
00526 assert(index >= 0); assert(size_type(index) < size());
00527 size_type sz = size();
00528 for(size_type i = index; i < sz - 1; i++) {
00529 access(i) = operator[](i + 1);
00530 }
00531 pop_back();
00532 }
00533
00538 void clear() {
00539 size_.access() = 0;
00540 }
00541
00547 PersistantStore& get_store() const {
00548 return size_.get_store();
00549 }
00550
00551 private:
00552 void ensure_capacity(size_type sz) {
00553 if (sz > allocated_size_) {
00554 if (allocated_size_ == 0) {
00555 reserve(sz);
00556 } else {
00557 reserve((allocated_size_ * 2 > sz) ? (allocated_size_ * 2) : sz);
00558 }
00559 }
00560 }
00561
00562 private:
00563
00564 PersistantVector(const PersistantVector&);
00565 PersistantVector& operator=(const PersistantVector&);
00566
00567 private:
00568
00569 PersistantData<size_type> size_;
00570 PersistantData<value_type> **data_;
00571 size_type allocated_size_;
00572 };
00573
00574 template <class Datum>
00575 bool operator==(const PersistantVector<Datum>& v1,
00576 const PersistantVector<Datum>& v2) {
00577 if (v1.size() != v2.size()) {
00578 return false;
00579 }
00580 typename PersistantVector<Datum>::const_iterator it1 = v1.begin();
00581 typename PersistantVector<Datum>::const_iterator it2 = v2.begin();
00582 while(it1 != v1.end()) {
00583 if (*it1 != *it2) {
00584 return false;
00585 }
00586 ++it1;
00587 ++it2;
00588 }
00589 return true;
00590 }
00591
00592 template <class Datum>
00593 bool operator< (const PersistantVector<Datum>& v1,
00594 const PersistantVector<Datum>& v2) {
00595 typename PersistantVector<Datum>::const_iterator it1 = v1.begin();
00596 typename PersistantVector<Datum>::const_iterator it2 = v2.begin();
00597 while(it1 != v1.end()) {
00598 if (it2 == v2.end()) {
00599 return true;
00600 }
00601 if (*it1 < *it2) {
00602 return true;
00603 } else if (*it2 < *it1) {
00604 return false;
00605 }
00606 ++it1;
00607 ++it2;
00608 }
00609 if (it2 == v2.end()) {
00610
00611 return false;
00612 } else {
00613
00614 return true;
00615 }
00616 }
00617
00618
00619
00620 template <class Datum> struct PMP_pair {
00621 struct PMP_hash {
00622 unsigned long operator() (const Datum& d) const {
00623 return (unsigned long)(d);
00624 }
00625 };
00626 hashers::hash_set<Datum, PMP_hash> allocated, deleted;
00627 typedef typename hashers::hash_set<Datum, PMP_hash>::iterator iterator;
00628 };
00629
00638 template <class Datum> class PersistantMemoryPool
00639 : public StackPersistantObject<PMP_pair<Datum*>, false> {
00640 public:
00641 PersistantMemoryPool(PersistantStore& store) :
00642 StackPersistantObject<PMP_pair<Datum*>, false>(store,PMP_pair<Datum*>())
00643 { }
00644
00645 virtual ~PersistantMemoryPool() {
00646
00647 for(int i = this->data_.size() - 1; i >= 0; i--) {
00648 typename PMP_pair<Datum*>::iterator it;
00649 for(it = this->data_[i].datum.allocated.begin();
00650 it != this->data_[i].datum.allocated.end(); ++it) {
00651 dofinaldelete(*it);
00652 }
00653 }
00654
00655 }
00656
00657 void mark_allocated(Datum *key) {
00658
00659 PMP_pair<Datum*>& handle = this->get_handle();
00660 handle.allocated.insert(key);
00661 assert(handle.deleted.count(key) == 0);
00662 }
00663
00664 void mark_deleted(Datum *key) {
00665
00666 PMP_pair<Datum*>& handle = this->get_handle();
00667 if (handle.allocated.count(key) != 0) {
00668
00669
00670 handle.allocated.erase(key);
00671 dodelete(key);
00672 } else {
00673 assert(this->logging());
00674 handle.deleted.insert(key);
00675 }
00676 }
00677
00678 protected:
00679 virtual void undo() {
00680 assert(this->logging());
00681
00682
00683 typename PMP_pair<Datum*>::iterator it;
00684 for(it = this->data_.back().datum.allocated.begin();
00685 it != this->data_.back().datum.allocated.end(); ++it) {
00686 dodelete(*it);
00687 }
00688 this->data_.pop_back();
00689 }
00690
00691 virtual void merge_times(PMP_pair<Datum*>& older,
00692 const PMP_pair<Datum*>& newer) {
00693 older.allocated.insert(newer.allocated.begin(), newer.allocated.end());
00694 for (typename PMP_pair<Datum*>::iterator it = newer.deleted.begin();
00695 it != newer.deleted.end(); ++it) {
00696 if (older.allocated.erase(*it)) {
00697
00698 dodelete(*it);
00699 } else {
00700
00701 assert(this->logging_after_pop());
00702 older.deleted.insert(*it);
00703 }
00704 }
00705 }
00706
00711 virtual void dodelete(Datum *d) {
00712 delete d;
00713 }
00714
00718 virtual void dofinaldelete(Datum *d) {
00719 delete d;
00720 }
00721
00722 private:
00723
00724 PersistantMemoryPool(const PersistantMemoryPool&);
00725 PersistantMemoryPool& operator = (const PersistantMemoryPool&);
00726 };
00727
00731 template <class Value>
00732 class PersistantList {
00733 private:
00734 struct node {
00735 PersistantData<node*> prev_;
00736 PersistantData<node*> next_;
00737 PersistantData<Value> value_;
00738 node(PersistantStore& store, node *prev, node *next, const Value& initial)
00739 : prev_(store, prev), next_(store, next), value_(store, initial)
00740 { }
00741 };
00742
00743 PersistantData<int> size_;
00744 PersistantData<node*> first_;
00745 PersistantData<node*> last_;
00746 PersistantMemoryPool<node> pool_;
00747
00748 node *do_insert(node *prev, node *next, const Value& v) {
00749 node *newnode = new node(get_store(), prev, next, v);
00750 pool_.mark_allocated(newnode);
00751 size_.access()++;
00752
00753 if (prev) {
00754 prev->next_.access() = newnode;
00755 } else {
00756 first_.access() = newnode;
00757 }
00758 if (next) {
00759 next->prev_.access() = newnode;
00760 } else {
00761 last_.access() = newnode;
00762 }
00763 return newnode;
00764 }
00765
00766 public:
00767 struct const_iterator {
00768 friend class PersistantList;
00769 protected:
00770 node *n_;
00771
00772 const_iterator(node *n) : n_(n) { }
00773 public:
00774 const_iterator() { }
00775
00776 const Value& operator*() const {
00777 return *n_->value_;
00778 }
00779 const Value *operator->() const {
00780 return &operator*();
00781 }
00782 Value& access() {
00783 return n_->value_.access();
00784 }
00785
00786 const_iterator& operator++() {
00787 n_ = *n_->next_; return *this;
00788 }
00789 const_iterator& operator--() {
00790 n_ = *n_->prev_; return *this;
00791 }
00792 bool operator== (const const_iterator& other) const {
00793 return n_ == other.n_;
00794 }
00795 bool operator!= (const const_iterator& other) const {
00796 return n_ != other.n_;
00797 }
00798
00799 unsigned long hashcode() const {
00800 return (unsigned long) n_;
00801 }
00802
00803
00804 typedef ptrdiff_t difference_type;
00805 typedef std::bidirectional_iterator_tag iterator_category;
00806 typedef Value value_type;
00807 typedef const Value & reference;
00808 typedef const Value * pointer;
00809 };
00810
00814 struct iterator : public const_iterator {
00815 friend class PersistantList;
00816 private:
00817 iterator(node *n) : const_iterator(n) { }
00818 public:
00819 iterator() { }
00820
00821 Value& access() const {
00822 return const_iterator::n_->value_.access();
00823 }
00824
00825 iterator& operator++() {
00826 const_iterator::operator++();
00827 return *this;
00828 }
00829 iterator& operator--() {
00830 const_iterator::operator--();
00831 return *this;
00832 }
00833 };
00834
00835 PersistantList(PersistantStore& store)
00836 : size_(store, 0), first_(store, NULL), last_(store, NULL), pool_(store)
00837 { }
00838
00839 iterator begin() const {
00840 return iterator(*first_);
00841 }
00842 iterator end() const {
00843 return iterator(NULL);
00844 }
00845 const Value& back() const {
00846 return *iterator(*last_);
00847 }
00848 const Value& first() const {
00849 return *iterator(*first_);
00850 }
00851 int size() const {
00852 return *size_;
00853 }
00854 bool empty() const {
00855 return size() == 0;
00856 }
00857
00858 iterator insert(iterator it, const Value& v) {
00859 node *prev = const_cast<node*>(*it.n_->prev_);
00860 node *next = const_cast<node*>(*it.n_->next_);
00861 return iterator(do_insert(prev, next, v));
00862 }
00863 iterator push_back(const Value& v) {
00864 return iterator(do_insert(const_cast<node*>(*last_), NULL, v));
00865 }
00866 iterator push_front(const Value& v) {
00867 return iterator(do_insert(NULL, const_cast<node*>(*first_), v));
00868 }
00869
00870 iterator erase(iterator it) {
00871 node *prev = const_cast<node*>(*it.n_->prev_);
00872 node *next = const_cast<node*>(*it.n_->next_);
00873 if (prev) {
00874 prev->next_.access() = next;
00875 } else {
00876 first_.access() = next;
00877 }
00878 if (next) {
00879 next->prev_.access() = prev;
00880 } else {
00881 last_.access() = prev;
00882 }
00883 size_.access()--;
00884 pool_.mark_deleted(it.n_);
00885 return iterator(next);
00886 }
00887 void pop_back() {
00888 return erase(iterator(*last_));
00889 }
00890 void pop_front() {
00891 return erase(begin());
00892 }
00893
00894 PersistantStore& get_store() const { return size_.get_store(); }
00895 };
00896
00908 template <class Key, class HashFcn = hashers::hash<Key>,
00909 class EqualKey = std::equal_to<Key> >
00910 class PersistantHashSet {
00911 private:
00921 struct map_data {
00922 private:
00923 PersistantData< bool > valid_;
00924 Key data_;
00925 PersistantData< map_data* > next_;
00926 PersistantData< map_data* > prev_;
00927
00928 public:
00929 map_data(PersistantStore& store, const Key& dat)
00930 : valid_(store, true)
00931 , data_(dat)
00932 , next_(store, NULL)
00933 , prev_(store, NULL) {
00934 }
00935
00936
00937 void unlink() {
00938 map_data *next = get_next();
00939 map_data *prev = get_prev();
00940 if (next) {
00941 set_next(NULL);
00942 next->set_prev(prev);
00943 }
00944 if (prev) {
00945 set_prev(NULL);
00946 prev->set_next(next);
00947 }
00948 }
00949
00950 bool has_data() const {
00951 return *valid_;
00952 }
00953
00954 void set_valid(bool valid = true) {
00955 valid_.access() = valid;
00956 }
00957
00958 const Key& get_data() const {
00959 assert(has_data());
00960 return data_;
00961 }
00962 const Key& unconditional_get_data() const {
00963 return data_;
00964 }
00965
00966 map_data *get_next() const {
00967 return *next_;
00968 }
00969
00970 map_data *get_prev() const {
00971 return *prev_;
00972 }
00973
00974 void set_next(map_data *next) {
00975 next_.access() = next;
00976 }
00977
00978 void set_prev(map_data *prev) {
00979 prev_.access() = prev;
00980 }
00981 };
00982
00983 struct deref_hasher {
00984 HashFcn hasher_;
00985 int operator()(const Key *key) const {
00986 return hasher_(*key);
00987 }
00988 };
00989
00990 struct deref_equal {
00991 EqualKey equal_;
00992 bool operator()(const Key *key1, const Key *key2) const {
00993 return equal_(*key1, *key2);
00994 }
00995 };
00996
00997 typedef hashers::hash_map<const Key*, map_data*, deref_hasher, deref_equal> map_type;
00998
01003 struct Reaper : public PersistantMemoryPool<map_data> {
01004 public:
01005 Reaper(PersistantStore& store, map_type& hashset)
01006 : PersistantMemoryPool<map_data>(store), hashset_(hashset) { }
01007
01008 protected:
01009
01010
01011 virtual void dodelete(map_data *data) {
01012 bool diderase;
01013
01014 diderase = hashset_.erase(& data->unconditional_get_data());
01015 assert(diderase);
01016 delete data;
01017 }
01018
01019
01020
01021 private:
01022 map_type& hashset_;
01023 };
01024
01025 map_data *internal_find(const Key& key) const {
01026 typename map_type::const_iterator it = datamap_.find(&key);
01027 if(it == datamap_.end()) {
01028 return NULL;
01029 } else {
01030 return (*it).second;
01031 }
01032 }
01033
01034 public:
01039 class iterator {
01040 private:
01041 friend class PersistantHashSet;
01042 iterator(map_data *data) : datap(data) { }
01043 public:
01044 iterator() { datap = NULL; }
01045
01046 const Key& operator *() const {
01047 assert(datap->has_data());
01048 return datap->get_data();
01049 }
01050 const Key *operator->() const {
01051 return &operator*();
01052 }
01053
01054 iterator& operator++() {
01055 assert(datap);
01056 datap = datap->get_next();
01057 return *this;
01058 }
01059 bool operator == (iterator other) const {
01060 return datap == other.datap;
01061 }
01062 bool operator != (iterator other) const {
01063 return ! (other == *this);
01064 }
01065
01066
01067 typedef ptrdiff_t difference_type;
01068 typedef std::forward_iterator_tag iterator_category;
01069 typedef Key value_type;
01070 typedef const Key & reference;
01071 typedef const Key * pointer;
01072
01073 private:
01074 map_data *datap;
01075 };
01076
01077 typedef iterator const_iterator;
01078
01082 PersistantHashSet(PersistantStore& store)
01083 : size_(store, 0), first_(store, NULL), reaper_(store, datamap_)
01084 { }
01085
01089 iterator find(const Key& key) const {
01090 map_data *datap = internal_find(key);
01091
01092 if(!datap || !datap->has_data()) {
01093 return end();
01094 } else {
01095 return iterator(datap);
01096 }
01097 }
01098
01103 size_t count(const Key& key) const {
01104 return (find(key) == end()) ? 0 : 1;
01105 }
01106
01110 bool operator[] (const Key& key) const {
01111 return find(key) != end();
01112 }
01113
01117 int size() const {
01118 return *size_;
01119 }
01120
01124 bool empty() const {
01125 return size() == 0;
01126 }
01127
01133 std::pair<iterator,bool> insert(const Key& key) {
01134 assert(get_store().viewing_current());
01135
01136 bool didinsert;
01137 map_data *founddata;
01138
01139 founddata = internal_find(key);
01140 if (founddata == NULL) {
01141 founddata = new map_data(get_store(), key);
01142 reaper_.mark_allocated(founddata);
01143 datamap_.insert(std::make_pair(&(founddata->get_data()), founddata));
01144 push_first(founddata);
01145 didinsert = true;
01146 } else if (!founddata->has_data()) {
01147 founddata->set_valid();
01148 push_first(founddata);
01149 didinsert = true;
01150 } else {
01151 didinsert = false;
01152 }
01153 return std::make_pair(iterator(founddata), didinsert);
01154 }
01155
01161 bool erase(iterator it) {
01162 assert(get_store().viewing_current());
01163 if(it == end()) {
01164 return false;
01165 }
01166
01167 map_data *datap = it.datap;
01168 assert(datap->has_data());
01169 unlink_data(datap);
01170 datap->set_valid(false);
01171 reaper_.mark_deleted(datap);
01172 return true;
01173 }
01174
01175 bool erase(const Key& key) {
01176 return erase(find(key));
01177 }
01178
01182 void clear() {
01183 while (!empty()) {
01184 erase(begin());
01185 }
01186 }
01187
01188 iterator begin() const {
01189 return iterator(*first_);
01190 }
01191 iterator end() const {
01192 return iterator(NULL);
01193 }
01194
01195 PersistantStore& get_store() const { return size_.get_store(); }
01196
01197 private:
01202 void push_first(map_data *newfirst) {
01203 map_data *oldfirst = *first_;
01204 assert(oldfirst == NULL || oldfirst->get_prev() == NULL);
01205 assert(newfirst->get_prev() == NULL);
01206 assert(newfirst->get_next() == NULL);
01207 if (oldfirst) {
01208 oldfirst->set_prev(newfirst);
01209 newfirst->set_next(oldfirst);
01210 }
01211 first_.access() = newfirst;
01212 size_.access()++;
01213 }
01214
01219 void unlink_data(map_data *tounlink) {
01220 if (tounlink == begin().datap) {
01221 first_.access() = tounlink->get_next();
01222 }
01223 tounlink->unlink();
01224 if (tounlink->has_data()) {
01225 size_.access()--;
01226 }
01227 }
01228
01229 map_type datamap_;
01230 PersistantData<int> size_;
01231 PersistantData<map_data*> first_;
01232 Reaper reaper_;
01233
01234 private:
01235
01236 PersistantHashSet(const PersistantHashSet&);
01237 PersistantHashSet& operator = (const PersistantHashSet&);
01238 };
01239
01245 template <class Key, class Value, class HashFcn = hashers::hash<Key>,
01246 class EqualKey = std::equal_to<Key> >
01247 class PersistantHashMap {
01248 public:
01249 class iterator;
01250 friend class iterator;
01251
01252 private:
01253 typedef PersistantData<Value> value_type;
01254
01255 struct hasher {
01256 HashFcn fn;
01257 unsigned long operator()(const std::pair<Key,value_type*>& p) const {
01258 return fn(p.first);
01259 }
01260 };
01261 struct equaler {
01262 EqualKey fn;
01263 unsigned long operator()(const std::pair<Key,value_type*>& p1,
01264 const std::pair<Key,value_type*>& p2) const {
01265 return fn(p1.first, p2.first);
01266 }
01267 };
01268
01270 static std::pair<Key, value_type*> search_key(const Key& k) {
01271 return std::make_pair(k, (value_type*)NULL);
01272 }
01273
01276 struct PHM_pair {
01277 friend class iterator;
01278 const Key& first;
01279 const Value& second;
01280 private:
01281 PHM_pair(const Key& k, value_type *vptr)
01282 : first(k), second(**vptr) { }
01283 };
01284
01286 typedef PersistantHashSet< std::pair<Key, value_type*>,
01287 hasher, equaler> set_type;
01288
01289
01290 set_type set_;
01291 PersistantMemoryPool<value_type> pool_;
01292
01293 public:
01294 class iterator {
01295 friend class PersistantHashMap;
01296 private:
01297 typename set_type::iterator it_;
01298 iterator(typename set_type::iterator it) : it_(it) { }
01299 public:
01300 iterator() { }
01301 PHM_pair operator*() const {
01302 return PHM_pair((*it_).first, (*it_).second);
01303 }
01304 iterator& operator++() {
01305 ++it_;
01306 return *this;
01307 }
01308 bool operator==(const iterator& other) const {
01309 return it_ == other.it_;
01310 }
01311 bool operator!=(const iterator& other) const {
01312 return it_ != other.it_;
01313 }
01314
01315
01316 typedef ptrdiff_t difference_type;
01317 typedef std::forward_iterator_tag iterator_category;
01318 typedef PHM_pair value_type;
01319 typedef const PHM_pair& reference;
01320 typedef const PHM_pair* pointer;
01321 };
01322
01323 typedef iterator const_iterator;
01324
01325
01326 PersistantHashMap(PersistantStore& store)
01327 : set_(store), pool_(store)
01328 { }
01329
01330 int size() const {
01331 return set_.size();
01332 }
01333 bool empty() const {
01334 return size() == 0;
01335 }
01336 iterator begin() const {
01337 return iterator(set_.begin());
01338 }
01339 iterator end() const {
01340 return iterator(set_.end());
01341 }
01342 iterator find(const Key& k) const {
01343 return iterator(set_.find(search_key(k)));
01344 }
01345 int count(const Key& k) const {
01346 if (find(k) == end()) {
01347 return 0;
01348 } else {
01349 return 1;
01350 }
01351 }
01352
01353 std::pair<iterator,bool> insert(const std::pair<Key,Value>& v) {
01354 return insert(v.first, v.second);
01355 }
01356
01357 std::pair<iterator,bool> insert(const Key& k, const Value& v) {
01358 std::pair<typename set_type::iterator,bool> p =
01359 set_.insert(search_key(k));
01360 typename set_type::iterator it = p.first;
01361
01362
01363 value_type*& storedval = const_cast<value_type*&>( (*it).second );
01364 if (storedval) {
01365 storedval->access() = v;
01366 return std::make_pair(iterator(it), p.second);
01367 } else {
01368 storedval = new PersistantData<Value>(get_store(), v);
01369 pool_.mark_allocated(storedval);
01370 return std::make_pair(iterator(it), true);
01371 }
01372 }
01373
01374 bool erase(iterator it) {
01375 return set_.erase(it.it_);
01376 }
01377 bool erase(const Key& k) {
01378 return erase(find(k));
01379 }
01380
01381
01382
01383 Value& operator[] (const Key& k) {
01384 iterator found = find(k);
01385 if (found == end()) {
01386 found = insert(k, Value()).first;
01387 }
01388
01389 value_type *storedval = const_cast<value_type*>((*found.it_).second);
01390 return storedval->access();
01391 }
01392
01393 PersistantStore& get_store() const { return set_.get_store(); }
01394
01395 private:
01396
01397 PersistantHashMap(const PersistantHashMap&);
01398 PersistantHashMap& operator = (const PersistantHashMap&);
01399 };
01400 #endif
01401
01402 #endif