summaryrefslogtreecommitdiff
path: root/plugins/Dbx_kyoto/src/kyotocabinet/kcmap.h
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/Dbx_kyoto/src/kyotocabinet/kcmap.h')
-rw-r--r--plugins/Dbx_kyoto/src/kyotocabinet/kcmap.h1379
1 files changed, 0 insertions, 1379 deletions
diff --git a/plugins/Dbx_kyoto/src/kyotocabinet/kcmap.h b/plugins/Dbx_kyoto/src/kyotocabinet/kcmap.h
deleted file mode 100644
index 7729c6504a..0000000000
--- a/plugins/Dbx_kyoto/src/kyotocabinet/kcmap.h
+++ /dev/null
@@ -1,1379 +0,0 @@
-/*************************************************************************************************
- * Data mapping structures
- * Copyright (C) 2009-2012 FAL Labs
- * This file is part of Kyoto Cabinet.
- * This program is free software: you can redistribute it and/or modify it under the terms of
- * the GNU General Public License as published by the Free Software Foundation, either version
- * 3 of the License, or any later version.
- * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License along with this program.
- * If not, see <http://www.gnu.org/licenses/>.
- *************************************************************************************************/
-
-
-#ifndef _KCMAP_H // duplication check
-#define _KCMAP_H
-
-#include <kccommon.h>
-#include <kcutil.h>
-
-namespace kyotocabinet { // common namespace
-
-
-/**
- * Doubly-linked hash map.
- * @param KEY the key type.
- * @param VALUE the value type.
- * @param HASH the hash functor.
- * @param EQUALTO the equality checking functor.
- */
-template <class KEY, class VALUE,
- class HASH = std::hash<KEY>, class EQUALTO = std::equal_to<KEY> >
-class LinkedHashMap {
- public:
- class Iterator;
- private:
- struct Record;
- /** The default bucket number of hash table. */
- static const size_t MAPDEFBNUM = 31;
- /** The mininum number of buckets to use mmap. */
- static const size_t MAPZMAPBNUM = 32768;
- public:
- /**
- * Iterator of records.
- */
- class Iterator {
- friend class LinkedHashMap;
- public:
- /**
- * Copy constructor.
- * @param src the source object.
- */
- Iterator(const Iterator& src) : map_(src.map_), rec_(src.rec_) {
- _assert_(true);
- }
- /**
- * Get the key.
- */
- const KEY& key() {
- _assert_(true);
- return rec_->key;
- }
- /**
- * Get the value.
- */
- VALUE& value() {
- _assert_(true);
- return rec_->value;
- }
- /**
- * Assignment operator from the self type.
- * @param right the right operand.
- * @return the reference to itself.
- */
- Iterator& operator =(const Iterator& right) {
- _assert_(true);
- if (&right == this) return *this;
- map_ = right.map_;
- rec_ = right.rec_;
- return *this;
- }
- /**
- * Equality operator with the self type.
- * @param right the right operand.
- * @return true if the both are equal, or false if not.
- */
- bool operator ==(const Iterator& right) const {
- _assert_(true);
- return map_ == right.map_ && rec_ == right.rec_;
- }
- /**
- * Non-equality operator with the self type.
- * @param right the right operand.
- * @return false if the both are equal, or true if not.
- */
- bool operator !=(const Iterator& right) const {
- _assert_(true);
- return map_ != right.map_ || rec_ != right.rec_;
- }
- /**
- * Preposting increment operator.
- * @return the iterator itself.
- */
- Iterator& operator ++() {
- _assert_(true);
- rec_ = rec_->next;
- return *this;
- }
- /**
- * Postpositive increment operator.
- * @return an iterator of the old position.
- */
- Iterator operator ++(int) {
- _assert_(true);
- Iterator old(*this);
- rec_ = rec_->next;
- return old;
- }
- /**
- * Preposting decrement operator.
- * @return the iterator itself.
- */
- Iterator& operator --() {
- _assert_(true);
- if (rec_) {
- rec_ = rec_->prev;
- } else {
- rec_ = map_->last_;
- }
- return *this;
- }
- /**
- * Postpositive decrement operator.
- * @return an iterator of the old position.
- */
- Iterator operator --(int) {
- _assert_(true);
- Iterator old(*this);
- if (rec_) {
- rec_ = rec_->prev;
- } else {
- rec_ = map_->last_;
- }
- return old;
- }
- private:
- /**
- * Constructor.
- * @param map the container.
- * @param rec the pointer to the current record.
- */
- explicit Iterator(LinkedHashMap* map, Record* rec) : map_(map), rec_(rec) {
- _assert_(map);
- }
- /** The container. */
- LinkedHashMap* map_;
- /** The current record. */
- Record* rec_;
- };
- /**
- * Moving Modes.
- */
- enum MoveMode {
- MCURRENT, ///< keep the current position
- MFIRST, ///< move to the first
- MLAST ///< move to the last
- };
- /**
- * Default constructor.
- */
- explicit LinkedHashMap() :
- buckets_(NULL), bnum_(MAPDEFBNUM), first_(NULL), last_(NULL), count_(0) {
- _assert_(true);
- initialize();
- }
- /**
- * Constructor.
- * @param bnum the number of buckets of the hash table.
- */
- explicit LinkedHashMap(size_t bnum) :
- buckets_(NULL), bnum_(bnum), first_(NULL), last_(NULL), count_(0) {
- _assert_(true);
- if (bnum_ < 1) bnum_ = MAPDEFBNUM;
- initialize();
- }
- /**
- * Destructor.
- */
- ~LinkedHashMap() {
- _assert_(true);
- destroy();
- }
- /**
- * Store a record.
- * @param key the key.
- * @param value the value.
- * @param mode the moving mode.
- * @return the pointer to the value of the stored record.
- */
- VALUE *set(const KEY& key, const VALUE& value, MoveMode mode) {
- _assert_(true);
- size_t bidx = hash_(key) % bnum_;
- Record* rec = buckets_[bidx];
- Record** entp = buckets_ + bidx;
- while (rec) {
- if (equalto_(rec->key, key)) {
- rec->value = value;
- switch (mode) {
- default: {
- break;
- }
- case MFIRST: {
- if (first_ != rec) {
- if (last_ == rec) last_ = rec->prev;
- if (rec->prev) rec->prev->next = rec->next;
- if (rec->next) rec->next->prev = rec->prev;
- rec->prev = NULL;
- rec->next = first_;
- first_->prev = rec;
- first_ = rec;
- }
- break;
- }
- case MLAST: {
- if (last_ != rec) {
- if (first_ == rec) first_ = rec->next;
- if (rec->prev) rec->prev->next = rec->next;
- if (rec->next) rec->next->prev = rec->prev;
- rec->prev = last_;
- rec->next = NULL;
- last_->next = rec;
- last_ = rec;
- }
- break;
- }
- }
- return &rec->value;
- } else {
- entp = &rec->child;
- rec = rec->child;
- }
- }
- rec = new Record(key, value);
- switch (mode) {
- default: {
- rec->prev = last_;
- if (!first_) first_ = rec;
- if (last_) last_->next = rec;
- last_ = rec;
- break;
- }
- case MFIRST: {
- rec->next = first_;
- if (!last_) last_ = rec;
- if (first_) first_->prev = rec;
- first_ = rec;
- break;
- }
- }
- *entp = rec;
- count_++;
- return &rec->value;
- }
- /**
- * Remove a record.
- * @param key the key.
- * @return true on success, or false on failure.
- */
- bool remove(const KEY& key) {
- _assert_(true);
- size_t bidx = hash_(key) % bnum_;
- Record* rec = buckets_[bidx];
- Record** entp = buckets_ + bidx;
- while (rec) {
- if (equalto_(rec->key, key)) {
- if (rec->prev) rec->prev->next = rec->next;
- if (rec->next) rec->next->prev = rec->prev;
- if (rec == first_) first_ = rec->next;
- if (rec == last_) last_ = rec->prev;
- *entp = rec->child;
- count_--;
- delete rec;
- return true;
- } else {
- entp = &rec->child;
- rec = rec->child;
- }
- }
- return false;
- }
- /**
- * Migrate a record to another map.
- * @param key the key.
- * @param dist the destination map.
- * @param mode the moving mode.
- * @return the pointer to the value of the migrated record, or NULL on failure.
- */
- VALUE* migrate(const KEY& key, LinkedHashMap* dist, MoveMode mode) {
- _assert_(dist);
- size_t hash = hash_(key);
- size_t bidx = hash % bnum_;
- Record* rec = buckets_[bidx];
- Record** entp = buckets_ + bidx;
- while (rec) {
- if (equalto_(rec->key, key)) {
- if (rec->prev) rec->prev->next = rec->next;
- if (rec->next) rec->next->prev = rec->prev;
- if (rec == first_) first_ = rec->next;
- if (rec == last_) last_ = rec->prev;
- *entp = rec->child;
- count_--;
- rec->child = NULL;
- rec->prev = NULL;
- rec->next = NULL;
- bidx = hash % dist->bnum_;
- Record* drec = dist->buckets_[bidx];
- entp = dist->buckets_ + bidx;
- while (drec) {
- if (dist->equalto_(drec->key, key)) {
- if (drec->child) rec->child = drec->child;
- if (drec->prev) {
- rec->prev = drec->prev;
- rec->prev->next = rec;
- }
- if (drec->next) {
- rec->next = drec->next;
- rec->next->prev = rec;
- }
- if (dist->first_ == drec) dist->first_ = rec;
- if (dist->last_ == drec) dist->last_ = rec;
- *entp = rec;
- delete drec;
- switch (mode) {
- default: {
- break;
- }
- case MFIRST: {
- if (dist->first_ != rec) {
- if (dist->last_ == rec) dist->last_ = rec->prev;
- if (rec->prev) rec->prev->next = rec->next;
- if (rec->next) rec->next->prev = rec->prev;
- rec->prev = NULL;
- rec->next = dist->first_;
- dist->first_->prev = rec;
- dist->first_ = rec;
- }
- break;
- }
- case MLAST: {
- if (dist->last_ != rec) {
- if (dist->first_ == rec) dist->first_ = rec->next;
- if (rec->prev) rec->prev->next = rec->next;
- if (rec->next) rec->next->prev = rec->prev;
- rec->prev = dist->last_;
- rec->next = NULL;
- dist->last_->next = rec;
- dist->last_ = rec;
- }
- break;
- }
- }
- return &rec->value;
- } else {
- entp = &drec->child;
- drec = drec->child;
- }
- }
- switch (mode) {
- default: {
- rec->prev = dist->last_;
- if (!dist->first_) dist->first_ = rec;
- if (dist->last_) dist->last_->next = rec;
- dist->last_ = rec;
- break;
- }
- case MFIRST: {
- rec->next = dist->first_;
- if (!dist->last_) dist->last_ = rec;
- if (dist->first_) dist->first_->prev = rec;
- dist->first_ = rec;
- break;
- }
- }
- *entp = rec;
- dist->count_++;
- return &rec->value;
- } else {
- entp = &rec->child;
- rec = rec->child;
- }
- }
- return NULL;
- }
- /**
- * Retrieve a record.
- * @param key the key.
- * @param mode the moving mode.
- * @return the pointer to the value of the corresponding record, or NULL on failure.
- */
- VALUE* get(const KEY& key, MoveMode mode) {
- _assert_(true);
- size_t bidx = hash_(key) % bnum_;
- Record* rec = buckets_[bidx];
- while (rec) {
- if (equalto_(rec->key, key)) {
- switch (mode) {
- default: {
- break;
- }
- case MFIRST: {
- if (first_ != rec) {
- if (last_ == rec) last_ = rec->prev;
- if (rec->prev) rec->prev->next = rec->next;
- if (rec->next) rec->next->prev = rec->prev;
- rec->prev = NULL;
- rec->next = first_;
- first_->prev = rec;
- first_ = rec;
- }
- break;
- }
- case MLAST: {
- if (last_ != rec) {
- if (first_ == rec) first_ = rec->next;
- if (rec->prev) rec->prev->next = rec->next;
- if (rec->next) rec->next->prev = rec->prev;
- rec->prev = last_;
- rec->next = NULL;
- last_->next = rec;
- last_ = rec;
- }
- break;
- }
- }
- return &rec->value;
- } else {
- rec = rec->child;
- }
- }
- return NULL;
- }
- /**
- * Remove all records.
- */
- void clear() {
- _assert_(true);
- if (count_ < 1) return;
- Record* rec = last_;
- while (rec) {
- Record* prev = rec->prev;
- delete rec;
- rec = prev;
- }
- for (size_t i = 0; i < bnum_; i++) {
- buckets_[i] = NULL;
- }
- first_ = NULL;
- last_ = NULL;
- count_ = 0;
- }
- /**
- * Get the number of records.
- */
- size_t count() {
- _assert_(true);
- return count_;
- }
- /**
- * Get an iterator at the first record.
- */
- Iterator begin() {
- _assert_(true);
- return Iterator(this, first_);
- }
- /**
- * Get an iterator of the end sentry.
- */
- Iterator end() {
- _assert_(true);
- return Iterator(this, NULL);
- }
- /**
- * Get an iterator at a record.
- * @param key the key.
- * @return the pointer to the value of the corresponding record, or NULL on failure.
- */
- Iterator find(const KEY& key) {
- _assert_(true);
- size_t bidx = hash_(key) % bnum_;
- Record* rec = buckets_[bidx];
- while (rec) {
- if (equalto_(rec->key, key)) {
- return Iterator(this, rec);
- } else {
- rec = rec->child;
- }
- }
- return Iterator(this, NULL);
- }
- /**
- * Get the reference of the key of the first record.
- * @return the reference of the key of the first record.
- */
- const KEY& first_key() {
- _assert_(true);
- return first_->key;
- }
- /**
- * Get the reference of the value of the first record.
- * @return the reference of the value of the first record.
- */
- VALUE& first_value() {
- _assert_(true);
- return first_->value;
- }
- /**
- * Get the reference of the key of the last record.
- * @return the reference of the key of the last record.
- */
- const KEY& last_key() {
- _assert_(true);
- return last_->key;
- }
- /**
- * Get the reference of the value of the last record.
- * @return the reference of the value of the last record.
- */
- VALUE& last_value() {
- _assert_(true);
- return last_->value;
- }
- private:
- /**
- * Record data.
- */
- struct Record {
- KEY key; ///< key
- VALUE value; ///< value
- Record* child; ///< child record
- Record* prev; ///< previous record
- Record* next; ///< next record
- /** constructor */
- explicit Record(const KEY& k, const VALUE& v) :
- key(k), value(v), child(NULL), prev(NULL), next(NULL) {
- _assert_(true);
- }
- };
- /**
- * Initialize fields.
- */
- void initialize() {
- _assert_(true);
- if (bnum_ >= MAPZMAPBNUM) {
- buckets_ = (Record**)mapalloc(sizeof(*buckets_) * bnum_);
- } else {
- buckets_ = new Record*[bnum_];
- for (size_t i = 0; i < bnum_; i++) {
- buckets_[i] = NULL;
- }
- }
- }
- /**
- * Clean up fields.
- */
- void destroy() {
- _assert_(true);
- Record* rec = last_;
- while (rec) {
- Record* prev = rec->prev;
- delete rec;
- rec = prev;
- }
- if (bnum_ >= MAPZMAPBNUM) {
- mapfree(buckets_);
- } else {
- delete[] buckets_;
- }
- }
- /** Dummy constructor to forbid the use. */
- LinkedHashMap(const LinkedHashMap&);
- /** Dummy Operator to forbid the use. */
- LinkedHashMap& operator =(const LinkedHashMap&);
- /** The functor of the hash function. */
- HASH hash_;
- /** The functor of the equalto function. */
- EQUALTO equalto_;
- /** The bucket array. */
- Record** buckets_;
- /** The number of buckets. */
- size_t bnum_;
- /** The first record. */
- Record* first_;
- /** The last record. */
- Record* last_;
- /** The number of records. */
- size_t count_;
-};
-
-
-/**
- * Memory-saving string hash map.
- */
-class TinyHashMap {
- public:
- class Iterator;
- private:
- struct Record;
- struct RecordComparator;
- /** The default bucket number of hash table. */
- static const size_t MAPDEFBNUM = 31;
- /** The mininum number of buckets to use mmap. */
- static const size_t MAPZMAPBNUM = 32768;
- public:
- /**
- * Iterator of records.
- */
- class Iterator {
- friend class TinyHashMap;
- public:
- /**
- * Constructor.
- * @param map the container.
- * @note This object will not be invalidated even when the map object is updated once.
- * However, phantom records may be retrieved if they are removed after creation of each
- * iterator.
- */
- explicit Iterator(TinyHashMap* map) : map_(map), bidx_(-1), ridx_(0), recs_() {
- _assert_(map);
- step();
- }
- /**
- * Destructor.
- */
- ~Iterator() {
- _assert_(true);
- free_records();
- }
- /**
- * Get the key of the current record.
- * @param sp the pointer to the variable into which the size of the region of the return
- * value is assigned.
- * @return the pointer to the key region of the current record, or NULL on failure.
- */
- const char* get_key(size_t* sp) {
- _assert_(sp);
- if (ridx_ >= recs_.size()) return NULL;
- Record rec(recs_[ridx_]);
- *sp = rec.ksiz_;
- return rec.kbuf_;
- }
- /**
- * Get the value of the current record.
- * @param sp the pointer to the variable into which the size of the region of the return
- * value is assigned.
- * @return the pointer to the value region of the current record, or NULL on failure.
- */
- const char* get_value(size_t* sp) {
- _assert_(sp);
- if (ridx_ >= recs_.size()) return NULL;
- Record rec(recs_[ridx_]);
- *sp = rec.vsiz_;
- return rec.vbuf_;
- }
- /**
- * Get a pair of the key and the value of the current record.
- * @param ksp the pointer to the variable into which the size of the region of the return
- * value is assigned.
- * @param vbp the pointer to the variable into which the pointer to the value region is
- * assigned.
- * @param vsp the pointer to the variable into which the size of the value region is
- * assigned.
- * @return the pointer to the key region, or NULL on failure.
- */
- const char* get(size_t* ksp, const char** vbp, size_t* vsp) {
- _assert_(ksp && vbp && vsp);
- if (ridx_ >= recs_.size()) return NULL;
- Record rec(recs_[ridx_]);
- *ksp = rec.ksiz_;
- *vbp = rec.vbuf_;
- *vsp = rec.vsiz_;
- return rec.kbuf_;
- }
- /**
- * Step the cursor to the next record.
- */
- void step() {
- _assert_(true);
- if (++ridx_ >= recs_.size()) {
- ridx_ = 0;
- free_records();
- while (true) {
- bidx_++;
- if (bidx_ >= (int64_t)map_->bnum_) return;
- read_records();
- if (recs_.size() > 0) break;
- }
- }
- }
- private:
- /**
- * Read records of the current bucket.
- */
- void read_records() {
- char* rbuf = map_->buckets_[bidx_];
- while (rbuf) {
- Record rec(rbuf);
- size_t rsiz = sizeof(rec.child_) + sizevarnum(rec.ksiz_) + rec.ksiz_ +
- sizevarnum(rec.vsiz_) + rec.vsiz_ + sizevarnum(rec.psiz_);
- char* nbuf = new char[rsiz];
- std::memcpy(nbuf, rbuf, rsiz);
- recs_.push_back(nbuf);
- rbuf = rec.child_;
- }
- }
- /**
- * Release recources of the current records.
- */
- void free_records() {
- std::vector<char*>::iterator it = recs_.begin();
- std::vector<char*>::iterator itend = recs_.end();
- while (it != itend) {
- char* rbuf = *it;
- delete[] rbuf;
- ++it;
- }
- recs_.clear();
- }
- /** Dummy constructor to forbid the use. */
- Iterator(const Iterator&);
- /** Dummy Operator to forbid the use. */
- Iterator& operator =(const Iterator&);
- /** The container. */
- TinyHashMap* map_;
- /** The current bucket index. */
- int64_t bidx_;
- /** The current record index. */
- size_t ridx_;
- /** The current records. */
- std::vector<char*> recs_;
- };
- /**
- * Sorter of records.
- */
- class Sorter {
- public:
- /**
- * Constructor.
- * @param map the container.
- * @note This object will be invalidated when the map object is updated once.
- */
- explicit Sorter(TinyHashMap* map) : map_(map), ridx_(0), recs_() {
- _assert_(map);
- char** buckets = map_->buckets_;
- size_t bnum = map_->bnum_;
- for (size_t i = 0; i < bnum; i++) {
- char* rbuf = buckets[i];
- while (rbuf) {
- Record rec(rbuf);
- recs_.push_back(rbuf);
- rbuf = *(char**)rbuf;
- }
- }
- std::sort(recs_.begin(), recs_.end(), RecordComparator());
- }
- /**
- * Destructor.
- */
- ~Sorter() {
- _assert_(true);
- }
- /**
- * Get the key of the current record.
- * @param sp the pointer to the variable into which the size of the region of the return
- * value is assigned.
- * @return the pointer to the key region of the current record, or NULL on failure.
- */
- const char* get_key(size_t* sp) {
- _assert_(sp);
- if (ridx_ >= recs_.size()) return NULL;
- Record rec(recs_[ridx_]);
- *sp = rec.ksiz_;
- return rec.kbuf_;
- }
- /**
- * Get the value of the current record.
- * @param sp the pointer to the variable into which the size of the region of the return
- * value is assigned.
- * @return the pointer to the value region of the current record, or NULL on failure.
- */
- const char* get_value(size_t* sp) {
- _assert_(sp);
- if (ridx_ >= recs_.size()) return NULL;
- Record rec(recs_[ridx_]);
- *sp = rec.vsiz_;
- return rec.vbuf_;
- }
- /**
- * Get a pair of the key and the value of the current record.
- * @param ksp the pointer to the variable into which the size of the region of the return
- * value is assigned.
- * @param vbp the pointer to the variable into which the pointer to the value region is
- * assigned.
- * @param vsp the pointer to the variable into which the size of the value region is
- * assigned.
- * @return the pointer to the key region, or NULL on failure.
- */
- const char* get(size_t* ksp, const char** vbp, size_t* vsp) {
- _assert_(ksp && vbp && vsp);
- if (ridx_ >= recs_.size()) return NULL;
- Record rec(recs_[ridx_]);
- *ksp = rec.ksiz_;
- *vbp = rec.vbuf_;
- *vsp = rec.vsiz_;
- return rec.kbuf_;
- }
- /**
- * Step the cursor to the next record.
- */
- void step() {
- _assert_(true);
- ridx_++;
- }
- /** The container. */
- TinyHashMap* map_;
- /** The current record index. */
- size_t ridx_;
- /** The current records. */
- std::vector<char*> recs_;
- };
- /**
- * Default constructor.
- */
- explicit TinyHashMap() : buckets_(NULL), bnum_(MAPDEFBNUM), count_(0) {
- _assert_(true);
- initialize();
- }
- /**
- * Constructor.
- * @param bnum the number of buckets of the hash table.
- */
- explicit TinyHashMap(size_t bnum) : buckets_(NULL), bnum_(bnum), count_(0) {
- _assert_(true);
- if (bnum_ < 1) bnum_ = MAPDEFBNUM;
- initialize();
- }
- /**
- * Destructor.
- */
- ~TinyHashMap() {
- _assert_(true);
- destroy();
- }
- /**
- * Set the value of a record.
- * @param kbuf the pointer to the key region.
- * @param ksiz the size of the key region.
- * @param vbuf the pointer to the value region.
- * @param vsiz the size of the value region.
- * @note If no record corresponds to the key, a new record is created. If the corresponding
- * record exists, the value is overwritten.
- */
- void set(const char* kbuf, size_t ksiz, const char* vbuf, size_t vsiz) {
- _assert_(kbuf && ksiz <= MEMMAXSIZ && vbuf && vsiz <= MEMMAXSIZ);
- size_t bidx = hash_record(kbuf, ksiz) % bnum_;
- char* rbuf = buckets_[bidx];
- char** entp = buckets_ + bidx;
- while (rbuf) {
- Record rec(rbuf);
- if (rec.ksiz_ == ksiz && !std::memcmp(rec.kbuf_, kbuf, ksiz)) {
- int32_t oh = (int32_t)sizevarnum(vsiz) - (int32_t)sizevarnum(rec.vsiz_);
- int64_t psiz = (int64_t)(rec.vsiz_ + rec.psiz_) - (int64_t)(vsiz + oh);
- if (psiz >= 0) {
- rec.overwrite(rbuf, vbuf, vsiz, psiz);
- } else {
- Record nrec(rec.child_, kbuf, ksiz, vbuf, vsiz, 0);
- delete[] rbuf;
- *entp = nrec.serialize();
- }
- return;
- }
- entp = (char**)rbuf;
- rbuf = rec.child_;
- }
- Record nrec(NULL, kbuf, ksiz, vbuf, vsiz, 0);
- *entp = nrec.serialize();
- count_++;
- }
- /**
- * Add a record.
- * @param kbuf the pointer to the key region.
- * @param ksiz the size of the key region.
- * @param vbuf the pointer to the value region.
- * @param vsiz the size of the value region.
- * @return true on success, or false on failure.
- * @note If no record corresponds to the key, a new record is created. If the corresponding
- * record exists, the record is not modified and false is returned.
- */
- bool add(const char* kbuf, size_t ksiz, const char* vbuf, size_t vsiz) {
- _assert_(kbuf && ksiz <= MEMMAXSIZ && vbuf && vsiz <= MEMMAXSIZ);
- size_t bidx = hash_record(kbuf, ksiz) % bnum_;
- char* rbuf = buckets_[bidx];
- char** entp = buckets_ + bidx;
- while (rbuf) {
- Record rec(rbuf);
- if (rec.ksiz_ == ksiz && !std::memcmp(rec.kbuf_, kbuf, ksiz)) return false;
- entp = (char**)rbuf;
- rbuf = rec.child_;
- }
- Record nrec(NULL, kbuf, ksiz, vbuf, vsiz, 0);
- *entp = nrec.serialize();
- count_++;
- return true;
- }
- /**
- * Replace the value of a record.
- * @param kbuf the pointer to the key region.
- * @param ksiz the size of the key region.
- * @param vbuf the pointer to the value region.
- * @param vsiz the size of the value region.
- * @return true on success, or false on failure.
- * @note If no record corresponds to the key, no new record is created and false is returned.
- * If the corresponding record exists, the value is modified.
- */
- bool replace(const char* kbuf, size_t ksiz, const char* vbuf, size_t vsiz) {
- _assert_(kbuf && ksiz <= MEMMAXSIZ && vbuf && vsiz <= MEMMAXSIZ);
- size_t bidx = hash_record(kbuf, ksiz) % bnum_;
- char* rbuf = buckets_[bidx];
- char** entp = buckets_ + bidx;
- while (rbuf) {
- Record rec(rbuf);
- if (rec.ksiz_ == ksiz && !std::memcmp(rec.kbuf_, kbuf, ksiz)) {
- int32_t oh = (int32_t)sizevarnum(vsiz) - (int32_t)sizevarnum(rec.vsiz_);
- int64_t psiz = (int64_t)(rec.vsiz_ + rec.psiz_) - (int64_t)(vsiz + oh);
- if (psiz >= 0) {
- rec.overwrite(rbuf, vbuf, vsiz, psiz);
- } else {
- Record nrec(rec.child_, kbuf, ksiz, vbuf, vsiz, 0);
- delete[] rbuf;
- *entp = nrec.serialize();
- }
- return true;
- }
- entp = (char**)rbuf;
- rbuf = rec.child_;
- }
- return false;
- }
- /**
- * Append the value of a record.
- * @param kbuf the pointer to the key region.
- * @param ksiz the size of the key region.
- * @param vbuf the pointer to the value region.
- * @param vsiz the size of the value region.
- * @note If no record corresponds to the key, a new record is created. If the corresponding
- * record exists, the given value is appended at the end of the existing value.
- */
- void append(const char* kbuf, size_t ksiz, const char* vbuf, size_t vsiz) {
- _assert_(kbuf && ksiz <= MEMMAXSIZ && vbuf && vsiz <= MEMMAXSIZ);
- size_t bidx = hash_record(kbuf, ksiz) % bnum_;
- char* rbuf = buckets_[bidx];
- char** entp = buckets_ + bidx;
- while (rbuf) {
- Record rec(rbuf);
- if (rec.ksiz_ == ksiz && !std::memcmp(rec.kbuf_, kbuf, ksiz)) {
- size_t nsiz = rec.vsiz_ + vsiz;
- int32_t oh = (int32_t)sizevarnum(nsiz) - (int32_t)sizevarnum(rec.vsiz_);
- int64_t psiz = (int64_t)(rec.vsiz_ + rec.psiz_) - (int64_t)(nsiz + oh);
- if (psiz >= 0) {
- rec.append(rbuf, oh, vbuf, vsiz, psiz);
- } else {
- psiz = nsiz + nsiz / 2;
- Record nrec(rec.child_, kbuf, ksiz, "", 0, psiz);
- char* nbuf = nrec.serialize();
- oh = (int32_t)sizevarnum(nsiz) - 1;
- psiz = (int64_t)psiz - (int64_t)(nsiz + oh);
- rec.concatenate(nbuf, rec.vbuf_, rec.vsiz_, vbuf, vsiz, psiz);
- delete[] rbuf;
- *entp = nbuf;
- }
- return;
- }
- entp = (char**)rbuf;
- rbuf = rec.child_;
- }
- Record nrec(NULL, kbuf, ksiz, vbuf, vsiz, 0);
- *entp = nrec.serialize();
- count_++;
- }
- /**
- * Remove a record.
- * @param kbuf the pointer to the key region.
- * @param ksiz the size of the key region.
- * @return true on success, or false on failure.
- * @note If no record corresponds to the key, false is returned.
- */
- bool remove(const char* kbuf, size_t ksiz) {
- _assert_(kbuf && ksiz <= MEMMAXSIZ);
- size_t bidx = hash_record(kbuf, ksiz) % bnum_;
- char* rbuf = buckets_[bidx];
- char** entp = buckets_ + bidx;
- while (rbuf) {
- Record rec(rbuf);
- if (rec.ksiz_ == ksiz && !std::memcmp(rec.kbuf_, kbuf, ksiz)) {
- *entp = rec.child_;
- delete[] rbuf;
- count_--;
- return true;
- }
- entp = (char**)rbuf;
- rbuf = rec.child_;
- }
- return false;
- }
- /**
- * Retrieve the value of a record.
- * @param kbuf the pointer to the key region.
- * @param ksiz the size of the key region.
- * @param sp the pointer to the variable into which the size of the region of the return
- * value is assigned.
- * @return the pointer to the value region of the corresponding record, or NULL on failure.
- */
- const char* get(const char* kbuf, size_t ksiz, size_t* sp) {
- _assert_(kbuf && ksiz <= MEMMAXSIZ && sp);
- size_t bidx = hash_record(kbuf, ksiz) % bnum_;
- char* rbuf = buckets_[bidx];
- while (rbuf) {
- Record rec(rbuf);
- if (rec.ksiz_ == ksiz && !std::memcmp(rec.kbuf_, kbuf, ksiz)) {
- *sp = rec.vsiz_;
- return rec.vbuf_;
- }
- rbuf = rec.child_;
- }
- return NULL;
- }
- /**
- * Remove all records.
- */
- void clear() {
- _assert_(true);
- if (count_ < 1) return;
- for (size_t i = 0; i < bnum_; i++) {
- char* rbuf = buckets_[i];
- while (rbuf) {
- Record rec(rbuf);
- char* child = rec.child_;
- delete[] rbuf;
- rbuf = child;
- }
- buckets_[i] = NULL;
- }
- count_ = 0;
- }
- /**
- * Get the number of records.
- * @return the number of records.
- */
- size_t count() {
- _assert_(true);
- return count_;
- }
- /**
- * Get the hash value of a record.
- * @param kbuf the pointer to the key region.
- * @param ksiz the size of the key region.
- * @return the hash value.
- */
- static size_t hash_record(const char* kbuf, size_t ksiz) {
- _assert_(kbuf && ksiz <= MEMMAXSIZ);
- return hashmurmur(kbuf, ksiz);
- }
- private:
- /**
- * Record data.
- */
- struct Record {
- /** constructor */
- Record(char* child, const char* kbuf, uint64_t ksiz,
- const char* vbuf, uint64_t vsiz, uint64_t psiz) :
- child_(child), kbuf_(kbuf), ksiz_(ksiz), vbuf_(vbuf), vsiz_(vsiz), psiz_(psiz) {
- _assert_(kbuf && ksiz <= MEMMAXSIZ && vbuf && vsiz <= MEMMAXSIZ && psiz <= MEMMAXSIZ);
- }
- /** constructor */
- Record(const char* rbuf) :
- child_(NULL), kbuf_(NULL), ksiz_(0), vbuf_(NULL), vsiz_(0), psiz_(0) {
- _assert_(rbuf);
- deserialize(rbuf);
- }
- /** overwrite the buffer */
- void overwrite(char* rbuf, const char* vbuf, size_t vsiz, size_t psiz) {
- _assert_(rbuf && vbuf && vsiz <= MEMMAXSIZ && psiz <= MEMMAXSIZ);
- char* wp = rbuf + sizeof(child_) + sizevarnum(ksiz_) + ksiz_;
- wp += writevarnum(wp, vsiz);
- std::memcpy(wp, vbuf, vsiz);
- wp += vsiz;
- writevarnum(wp, psiz);
- }
- /** append a value */
- void append(char* rbuf, int32_t oh, const char* vbuf, size_t vsiz, size_t psiz) {
- _assert_(rbuf && vbuf && vsiz <= MEMMAXSIZ && psiz <= MEMMAXSIZ);
- char* wp = rbuf + sizeof(child_) + sizevarnum(ksiz_) + ksiz_;
- if (oh > 0) {
- char* pv = wp + sizevarnum(vsiz_);
- std::memmove(pv + oh, pv, vsiz_);
- wp += writevarnum(wp, vsiz_ + vsiz);
- wp = pv + oh + vsiz_;
- } else {
- wp += writevarnum(wp, vsiz_ + vsiz);
- wp += vsiz_;
- }
- std::memcpy(wp, vbuf, vsiz);
- wp += vsiz;
- writevarnum(wp, psiz);
- }
- /** concatenate two values */
- void concatenate(char* rbuf, const char* ovbuf, size_t ovsiz,
- const char* nvbuf, size_t nvsiz, size_t psiz) {
- _assert_(rbuf && ovbuf && ovsiz <= MEMMAXSIZ && nvbuf && nvsiz <= MEMMAXSIZ);
- char* wp = rbuf + sizeof(child_) + sizevarnum(ksiz_) + ksiz_;
- wp += writevarnum(wp, ovsiz + nvsiz);
- std::memcpy(wp, ovbuf, ovsiz);
- wp += ovsiz;
- std::memcpy(wp, nvbuf, nvsiz);
- wp += nvsiz;
- writevarnum(wp, psiz);
- }
- /** serialize data into a buffer */
- char* serialize() {
- _assert_(true);
- uint64_t rsiz = sizeof(child_) + sizevarnum(ksiz_) + ksiz_ + sizevarnum(vsiz_) + vsiz_ +
- sizevarnum(psiz_) + psiz_;
- char* rbuf = new char[rsiz];
- char* wp = rbuf;
- *(char**)wp = child_;
- wp += sizeof(child_);
- wp += writevarnum(wp, ksiz_);
- std::memcpy(wp, kbuf_, ksiz_);
- wp += ksiz_;
- wp += writevarnum(wp, vsiz_);
- std::memcpy(wp, vbuf_, vsiz_);
- wp += vsiz_;
- writevarnum(wp, psiz_);
- return rbuf;
- }
- /** deserialize a buffer into object */
- void deserialize(const char* rbuf) {
- _assert_(rbuf);
- const char* rp = rbuf;
- child_ = *(char**)rp;
- rp += sizeof(child_);
- rp += readvarnum(rp, sizeof(ksiz_), &ksiz_);
- kbuf_ = rp;
- rp += ksiz_;
- rp += readvarnum(rp, sizeof(vsiz_), &vsiz_);
- vbuf_ = rp;
- rp += vsiz_;
- readvarnum(rp, sizeof(psiz_), &psiz_);
- }
- char* child_; ///< region of the child
- const char* kbuf_; ///< region of the key
- uint64_t ksiz_; ///< size of the key
- const char* vbuf_; ///< region of the value
- uint64_t vsiz_; ///< size of the key
- uint64_t psiz_; ///< size of the padding
- };
- /**
- * Comparator for records.
- */
- struct RecordComparator {
- /** comparing operator */
- bool operator ()(char* const& abuf, char* const& bbuf) {
- const char* akbuf = abuf + sizeof(char**);
- uint64_t aksiz;
- akbuf += readvarnum(akbuf, sizeof(aksiz), &aksiz);
- const char* bkbuf = bbuf + sizeof(char**);
- uint64_t bksiz;
- bkbuf += readvarnum(bkbuf, sizeof(bksiz), &bksiz);
- uint64_t msiz = aksiz < bksiz ? aksiz : bksiz;
- for (uint64_t i = 0; i < msiz; i++) {
- if (((uint8_t*)akbuf)[i] != ((uint8_t*)bkbuf)[i])
- return ((uint8_t*)akbuf)[i] < ((uint8_t*)bkbuf)[i];
- }
- return (int32_t)aksiz < (int32_t)bksiz;
- }
- };
- /**
- * Initialize fields.
- */
- void initialize() {
- _assert_(true);
- if (bnum_ >= MAPZMAPBNUM) {
- buckets_ = (char**)mapalloc(sizeof(*buckets_) * bnum_);
- } else {
- buckets_ = new char*[bnum_];
- for (size_t i = 0; i < bnum_; i++) {
- buckets_[i] = NULL;
- }
- }
- }
- /**
- * Clean up fields.
- */
- void destroy() {
- _assert_(true);
- for (size_t i = 0; i < bnum_; i++) {
- char* rbuf = buckets_[i];
- while (rbuf) {
- Record rec(rbuf);
- char* child = rec.child_;
- delete[] rbuf;
- rbuf = child;
- }
- }
- if (bnum_ >= MAPZMAPBNUM) {
- mapfree(buckets_);
- } else {
- delete[] buckets_;
- }
- }
- /** Dummy constructor to forbid the use. */
- TinyHashMap(const TinyHashMap&);
- /** Dummy Operator to forbid the use. */
- TinyHashMap& operator =(const TinyHashMap&);
- /** The bucket array. */
- char** buckets_;
- /** The number of buckets. */
- size_t bnum_;
- /** The number of records. */
- size_t count_;
-};
-
-
-/**
- * Memory-saving string array list.
- */
-class TinyArrayList {
- public:
- /**
- * Default constructor.
- */
- explicit TinyArrayList() : recs_() {
- _assert_(true);
- }
- /**
- * Destructor.
- */
- ~TinyArrayList() {
- _assert_(true);
- std::deque<char*>::iterator it = recs_.begin();
- std::deque<char*>::iterator itend = recs_.end();
- while (it != itend) {
- delete[] *it;
- ++it;
- }
- }
- /**
- * Insert a record at the bottom of the list.
- * @param buf the pointer to the record region.
- * @param size the size of the record region.
- */
- void push(const char* buf, size_t size) {
- _assert_(buf && size <= MEMMAXSIZ);
- size_t rsiz = sizevarnum(size) + size;
- char* rbuf = new char[rsiz];
- char* wp = rbuf + writevarnum(rbuf, size);
- std::memcpy(wp, buf, size);
- recs_.push_back(rbuf);
- }
- /**
- * Remove a record at the bottom of the list.
- * @return true if the operation success, or false if there is no record in the list.
- */
- bool pop() {
- _assert_(true);
- if (recs_.empty()) return false;
- delete[] recs_.back();
- recs_.pop_back();
- return true;
- }
- /**
- * Insert a record at the top of the list.
- * @param buf the pointer to the record region.
- * @param size the size of the record region.
- */
- void unshift(const char* buf, size_t size) {
- _assert_(buf && size <= MEMMAXSIZ);
- size_t rsiz = sizevarnum(size) + size;
- char* rbuf = new char[rsiz];
- char* wp = rbuf + writevarnum(rbuf, size);
- std::memcpy(wp, buf, size);
- recs_.push_front(rbuf);
- }
- /**
- * Remove a record at the top of the list.
- * @return true if the operation success, or false if there is no record in the list.
- */
- bool shift() {
- _assert_(true);
- if (recs_.empty()) return false;
- delete[] recs_.front();
- recs_.pop_front();
- return true;
- }
- /**
- * Insert a record at the position of the given index of the list.
- * @param buf the pointer to the record region.
- * @param size the size of the record region.
- * @param idx the index of the position. It must be equal to or less than the number of
- * records.
- */
- void insert(const char* buf, size_t size, size_t idx) {
- size_t rsiz = sizevarnum(size) + size;
- char* rbuf = new char[rsiz];
- char* wp = rbuf + writevarnum(rbuf, size);
- std::memcpy(wp, buf, size);
- recs_.insert(recs_.begin() + idx, rbuf);
- }
- /**
- * Remove a record at the position of the given index of the list.
- * @param idx the index of the position. It must be less than the number of records.
- */
- void remove(size_t idx) {
- _assert_(true);
- std::deque<char*>::iterator it = recs_.begin() + idx;
- delete[] *it;
- recs_.erase(it);
- }
- /**
- * Retrieve a record at the position of the given index of the list.
- * @param idx the index of the position. It must be less than the number of records.
- * @param sp the pointer to the variable into which the size of the region of the return
- * value is assigned.
- * @return the pointer to the region of the retrieved record.
- */
- const char* get(size_t idx, size_t* sp) {
- _assert_(sp);
- const char* rbuf = recs_[idx];
- uint64_t rsiz;
- const char* rp = rbuf + readvarnum(rbuf, sizeof(uint64_t), &rsiz);
- *sp = rsiz;
- return rp;
- }
- /**
- * Remove all records.
- */
- void clear() {
- _assert_(true);
- std::deque<char*>::iterator it = recs_.begin();
- std::deque<char*>::iterator itend = recs_.end();
- while (it != itend) {
- delete[] *it;
- ++it;
- }
- recs_.clear();
- }
- /**
- * Get the number of records.
- * @return the number of records.
- */
- size_t count() {
- _assert_(true);
- return recs_.size();
- }
- private:
- /** Dummy constructor to forbid the use. */
- TinyArrayList(const TinyArrayList&);
- /** Dummy Operator to forbid the use. */
- TinyArrayList& operator =(const TinyArrayList&);
- /** The record list. */
- std::deque<char*> recs_;
-};
-
-
-} // common namespace
-
-#endif // duplication check
-
-// END OF FILE