67 template <
typename KeyType>
68 inline int GetBit(
const KeyType & key,
int bit)
72 if ((
unsigned int)bit <
sizeof(KeyType) * 8) {
73 const uint8_t *p = (
const uint8_t *)(&key);
74 return(((p[bit >> 3]) >> (7 - (bit & 0x7))) & 0x1);
82 template <
typename KeyType>
83 inline int BitFirstDifferent(
const KeyType & key1,
const KeyType & key2)
87 const uint8_t *p1 = (
const uint8_t *)&key1;
88 const uint8_t *p2 = (
const uint8_t *)&key2;
89 for ( ; n <
sizeof(KeyType); ++n) {
93 if (n ==
sizeof(KeyType)) {
94 return(
sizeof(KeyType) * 8);
97 while (GetBit<uint8_t>(p1[n], d) == GetBit<uint8_t>(p2[n], d) && d < 8)
99 return ((n << 3) + d);
103 template <
typename KeyType>
104 inline bool IsMatch(
const KeyType & key1,
const KeyType & key2)
106 return(key2 == key1);
112 template <
typename KeyType,
typename ValueType,
119 template <
typename KeyType,
typename ValueType>
127 : _bitIndex(-1), _key(), _data()
137 _bitIndex = pn._bitIndex;
138 if (pn._left != & pn)
153 _bitIndex = pn._bitIndex;
154 if (pn._left != & pn)
172 : _bitIndex(bitIdx), _key(key), _data(data), _left(left), _right(right)
187 const ValueType & data,
243 uint32_t StreamedLength()
const 253 return((_key == n._key) && (_data == n._data));
257 friend class Patricia<KeyType, ValueType, std::equal_to<KeyType> >;
266 class __PatriciaIterator__
273 template <
typename KeyType,
typename ValueType,
274 typename KeyEqual = std::equal_to<KeyType> >
298 RecursiveRemove(_head);
305 uint32_t Size()
const 315 RecursiveRemove(_head);
316 _head->_left = _head;
317 _head->_right = _head;
325 Insert(
const KeyType & key,
const ValueType & data)
332 while (prev->_bitIndex < last->_bitIndex) {
334 last = (bit_get(key, last->_bitIndex) ? last->_right : last->_left);
337 if (key_compare(key, last->_key))
341 int i = BitFirstDifferent<KeyType>(key, last->_key);
346 while ((prev->_bitIndex < last->_bitIndex) && (last->_bitIndex < i)) {
348 last = (bit_get(key, last->_bitIndex) ? last->_right : last->_left);
355 (bit_get(key, i) ? last : node),
356 (bit_get(key, i) ? node : last));
359 if (bit_get(key, prev->_bitIndex))
374 bool Lookup(
const KeyType & key, ValueType & value)
const 397 while (prev->_bitIndex < last->_bitIndex) {
399 last = (bit_get(key, last->_bitIndex) ? last->_right : last->_left);
402 if (key_compare(key, last->_key))
409 LongestMatchNode(
const KeyType & key)
const 418 while (prev->_bitIndex < last->_bitIndex) {
419 if (IsMatch<KeyType>(prev->_key, key))
422 if (IsMatch<KeyType>(prev->_key, key))
424 last = (bit_get(key, last->_bitIndex) ? last->_right : last->_left);
427 if (IsMatch<KeyType>(last->_key, key))
429 else if (save != _head)
450 while (prev->_bitIndex < last->_bitIndex) {
452 last = (bit_get(key, last->_bitIndex) ? last->_right : last->_left);
455 if (key_compare(key, last->_key))
460 std::cerr <<
"last->left: " << last->_left->_key
461 <<
" last->_right: " << last->_right->_key
465 int i = BitFirstDifferent<KeyType>(key, last->_key);
470 last = (bit_get(key, prev->_bitIndex) ? last->_right : last->_left);
471 while ((prev->_bitIndex < last->_bitIndex) && (last->_bitIndex < i)) {
472 std::cerr <<
"prev: " << prev->_key <<
" last: " << last->_key
475 last = (bit_get(key, last->_bitIndex) ? last->_right : last->_left);
477 std::cerr <<
"last->left: " << last->_left->_key
478 <<
" last->_right: " << last->_right->_key
481 if (IsMatch<KeyType>(last->_key, key))
483 else if (prev != _head)
503 while (p->_bitIndex < t->_bitIndex) {
506 t = bit_get(key, t->_bitIndex) ? t->_right : t->_left;
519 if (! key_compare(key, t->_key)) {
528 if ((p->_left->_bitIndex > p->_bitIndex) ||
529 (p->_right->_bitIndex > p->_bitIndex)) {
535 KeyType newkey = p->_key;
538 x = bit_get(newkey, p->_bitIndex) ? p->_right : p->_left;
540 while (lp->_bitIndex < x->_bitIndex) {
542 x = bit_get(newkey, x->_bitIndex) ? x->_right : x->_left;
546 if (! key_compare(newkey, x->_key)) {
551 if (bit_get(newkey, lp->_bitIndex))
561 bit_get(key, p->_bitIndex) ? p->_left : p->_right;
562 if (bit_get(key, pp->_bitIndex))
575 if (bit_get(key, pp->_bitIndex))
576 pp->_right = (((p->_left == p->_right) && (p->_left == p)) ?
577 pp : ((p->_left == p) ? p->_right : p->_left));
579 pp->_left = (((p->_left == p->_right) && (p->_left == p)) ?
580 pp : ((p->_left == p) ? p->_right : p->_left));
597 void RecursivePrint()
const 599 RecursivePrint(_head);
608 RecursiveStreamedLength(_head, rc);
615 std::istream &
Read(std::istream & is)
621 for (uint32_t i = 0; i < numEntries; ++i) {
641 std::ostream &
Write(std::ostream & os)
const 645 RecursiveWrite(_head, os);
657 ssize_t totalBytes = 0;
660 uint32_t bytesRead =
IO::Read(fd, numEntries);
663 totalBytes = bytesRead;
664 for (uint32_t i = 0; i < numEntries; ++i) {
668 totalBytes += bytesRead;
672 totalBytes += bytesRead;
692 ssize_t totalBytes = 0;
694 ssize_t bytesWritten =
IO::Write(fd, _size);
695 if (bytesWritten > 0) {
696 totalBytes += bytesWritten;
698 bytesWritten = RecursiveWrite(_head, fd);
699 if (bytesWritten > 0) {
700 totalBytes += bytesWritten;
719 assert(
"Patricia::Read(FILE *)" == 0);
728 assert(
"Patricia::Write(FILE *)" == 0);
737 assert(
"Patricia::Read(gzFile)" == 0);
746 assert(
"Patricia::Write(gzFile)" == 0);
755 assert(
"Patricia::BZRead(BZFILE *)" == 0);
764 assert(
"Patricia::BZWrite(BZFILE *)" == 0);
770 if (_size != pt._size)
772 return(RecursiveEqual(_head, pt));
783 if ((l->_bitIndex >= root->_bitIndex) && (l != root) && (l != _head)) {
784 if (! RecursiveEqual(l, pt)) {
790 if ((r->_bitIndex >= root->_bitIndex) && (r != root) && (r != _head)) {
791 if (! RecursiveEqual(r, pt)) {
814 if ((r->_bitIndex > root->_bitIndex) && (r != root) && (r != _head))
818 if ((l->_bitIndex > root->_bitIndex) && (l != root) && (l != _head))
822 std::cout << root->_key <<
" " << root->_data << std::endl;
829 uint32_t & len)
const 835 if ( (l->_bitIndex >= root->_bitIndex) && (l != root) && (l != _head) )
836 RecursiveStreamedLength(l, len);
839 if ( (r->_bitIndex >= root->_bitIndex) && (r != root) && (r != _head) )
840 RecursiveStreamedLength(r, len);
843 len += root->StreamedLength();
850 std::ostream & os)
const 857 if ((l->_bitIndex >= root->_bitIndex) && (l != root) && (l != _head))
858 if (! RecursiveWrite(l, os))
862 if ((r->_bitIndex >= root->_bitIndex) && (r != root) && (r != _head))
863 if (! RecursiveWrite(r, os))
886 if ((l->_bitIndex >= root->_bitIndex) && (l != root) && (l != _head)) {
887 ssize_t bytesWritten = RecursiveWrite(l, fd);
888 if (bytesWritten < 0)
894 if ((r->_bitIndex >= root->_bitIndex) && (r != root) && (r != _head)) {
895 ssize_t bytesWritten = RecursiveWrite(r, fd);
896 if (bytesWritten < 0)
902 ssize_t bytesWritten =
IO::Write(fd, root->_key);
903 if (bytesWritten <= 0)
906 bytesWritten =
IO::Write(fd, root->_data);
907 if (bytesWritten <= 0)
924 && (l->_bitIndex >= node->_bitIndex)
932 && (r->_bitIndex >= node->_bitIndex)
939 if (node && (node != _head)) {
948 inline int bit_get(
const KeyType & k,
int n)
const 952 rc = GetBit<KeyType>(k, n);
959 inline int bit_first_different(
const KeyType & k1,
const KeyType & k2)
961 return(BitFirstDifferent<KeyType>(k1, k2));
974 dest->_key = src->_key;
977 dest->_data = src->_data;
983 KeyEqual key_compare;
992 #endif // _PATRICIA_HH_ PatriciaNode()
Constructor.
Definition: DwmPatricia.hh:126
This class is a pure virtual class, defining an interface for classes that can write their contents t...
Definition: DwmGZWritable.hh:57
Dwm::Writable pure virtual class definition.
int BZWrite(BZFILE *bzf) const
NOT YET IMPLEMENTED.
Definition: DwmPatricia.hh:762
PatriciaNode< KeyType, ValueType > * LongestMatchNode2(const KeyType &key) const
DOESN'T WORK PROPERLY.
Definition: DwmPatricia.hh:439
Dwm::BZ2Readable pure virtual class definition.
size_t Write(FILE *f) const
NOT YET IMPLEMENTED.
Definition: DwmPatricia.hh:726
PatriciaNode< KeyType, ValueType > * GetRight()
Returns the right branch.
Definition: DwmPatricia.hh:235
uint32_t StreamedLength() const
Returns the number of bytes that should be written if one of the Write() members is called...
Definition: DwmPatricia.hh:605
Dwm::GZReadable pure virtual class definition.
Dwm::Readable pure virtual class definition.
ssize_t Write(int fd) const
Write to a file descriptor.
Definition: DwmPatricia.hh:690
void Initialize(const KeyType &key, const ValueType &data, int bitIdx, PatriciaNode< KeyType, ValueType > *left, PatriciaNode< KeyType, ValueType > *right)
Initialize this node with the given data.
Definition: DwmPatricia.hh:186
std::ostream & Write(std::ostream &os) const
Write to an ostream. Return the ostream.
Definition: DwmPatricia.hh:641
ssize_t Read(int fd)
Read from a file descriptor.
Definition: DwmPatricia.hh:654
This class is a pure virtual class, defining an interface for classes that can read their contents fr...
Definition: DwmBZ2Readable.hh:57
A node in a Patricia trie.
Definition: DwmPatricia.hh:120
Pre-declare the Patricia class template.
Definition: DwmPatricia.hh:113
~PatriciaNode()
Destructor.
Definition: DwmPatricia.hh:179
PatriciaNode< KeyType, ValueType > * GetLeft()
Returns the left branch.
Definition: DwmPatricia.hh:227
static std::ostream & Write(std::ostream &os, char c)
Writes c to os. Returns os.
int Write(gzFile gzf) const
NOT YET IMPLEMENTED.
Definition: DwmPatricia.hh:744
Dwm::BZ2Writable pure virtual class definition.
int Read(gzFile gzf)
NOT YET IMPLEMENTED.
Definition: DwmPatricia.hh:735
static std::istream & Read(std::istream &is, char &c)
Reads c from is. Returns is.
bool Lookup(const KeyType &key, ValueType &value) const
Searches for the given key.
Definition: DwmPatricia.hh:374
Definition: DwmBZ2IO.hh:67
Patricia()
Constructor.
Definition: DwmPatricia.hh:284
This class is a pure virtual class, defining an interface for classes that can read their contents fr...
Definition: DwmGZReadable.hh:57
PatriciaNode(const KeyType &key, const ValueType &data, int bitIdx, PatriciaNode< KeyType, ValueType > *left, PatriciaNode< KeyType, ValueType > *right)
Constructor.
Definition: DwmPatricia.hh:169
Dwm::IO class definition.
std::istream & Read(std::istream &is)
Read from an istream. Return the istream.
Definition: DwmPatricia.hh:615
~Patricia()
Destructor.
Definition: DwmPatricia.hh:296
This class defines an interface for classes that can write their contents to an ostream, file descriptor or FILE pointer.
Definition: DwmWritable.hh:58
bool Delete(const KeyType &key)
Remove the node containing the given key.
Definition: DwmPatricia.hh:493
static uint32_t StreamedLength(char c)
Returns the number of bytes that would be written if we called Write() for a char.
Definition: DwmIO.hh:92
This class is a pure virtual class, defining an interface for classes that can write their contents t...
Definition: DwmBZ2Writable.hh:57
PatriciaNode< KeyType, ValueType > * Insert(const KeyType &key, const ValueType &data)
Inserts a new (key, data) pair in the Patricia trie, and returns the new node.
Definition: DwmPatricia.hh:325
Dwm::GZWritable pure virtual class definition.
This class defines an interface for classes that can read their contents from an istream, file descriptor or FILE pointer.
Definition: DwmReadable.hh:58
ValueType & GetData()
Returns the data field.
Definition: DwmPatricia.hh:202
PatriciaNode< KeyType, ValueType > * LookupNode(const KeyType &key) const
Search for the given key, and returns the node that contains it (or NULL).
Definition: DwmPatricia.hh:389
int BZRead(BZFILE *bzf)
NOT YET IMPLEMENTED.
Definition: DwmPatricia.hh:753
bool SetData(const ValueType &data)
Sets the data field.
Definition: DwmPatricia.hh:210
size_t Read(FILE *f)
NOT YET IMPLEMENTED.
Definition: DwmPatricia.hh:717
KeyType GetKey() const
Returns the key field.
Definition: DwmPatricia.hh:219