|
Boost-Commit : |
From: chintanraoh_at_[hidden]
Date: 2008-06-19 13:52:26
Author: chintanraoh
Date: 2008-06-19 13:52:25 EDT (Thu, 19 Jun 2008)
New Revision: 46530
URL: http://svn.boost.org/trac/boost/changeset/46530
Log:
size(), rbegin(), rend(), erase(iterator), iterator find() for patricia.
Text files modified:
sandbox/SOC/2008/digital_searching/dsearch/boost/dsearch/patricia.hpp | 263 ++++++++++++++++++++++++++++-----------
1 files changed, 187 insertions(+), 76 deletions(-)
Modified: sandbox/SOC/2008/digital_searching/dsearch/boost/dsearch/patricia.hpp
==============================================================================
--- sandbox/SOC/2008/digital_searching/dsearch/boost/dsearch/patricia.hpp (original)
+++ sandbox/SOC/2008/digital_searching/dsearch/boost/dsearch/patricia.hpp 2008-06-19 13:52:25 EDT (Thu, 19 Jun 2008)
@@ -12,14 +12,18 @@
#include<boost/iterator/iterator_traits.hpp>
#include<boost/dsearch/patricia_iterator.hpp>
-//replace all key assignement operations with key_copy
-//replace all key.size() with key_traits::size();
+//replace all key assignement operations with key_copy.
+//replace all key.size() with key_traits::size().
+//remove key.size() calculation where not needed.
namespace boost{
namespace dsearch{
+
template<class Key,class Mapped,class Key_traits,class Alloc=std::allocator<char> >
class patricia{
- private:
+ private:
+ template<class V_t, class N_t, class A>
+ friend class patricia_iterator;
typedef patricia<Key,Mapped,Key_traits,Alloc> self;
typedef typename Key_traits::const_iterator key_iterator;
typedef typename Key_traits::element_type key_element_type;
@@ -37,7 +41,6 @@
typedef typename std::iterator_traits<typename Key_traits::const_iterator>::iterator_category iterator_cat;
typedef typename std::random_access_iterator_tag rand_tag;
-
class patricia_node {
typedef patricia_node self;
public:
@@ -67,11 +70,13 @@
public:
typedef patricia_iterator<value_type, patricia_node, Alloc> iterator;
typedef patricia_iterator<const value_type, const patricia_node, Alloc> const_iterator;
+ typedef patricia_reverse_iterator<value_type, patricia_node, Alloc> reverse_iterator;
+ typedef patricia_reverse_iterator<const value_type, const patricia_node, Alloc> const_reverse_iterator;
patricia(): root(0)
{
}
-
+
patricia(const self &other)
{
copy_patricia(other.root);
@@ -100,8 +105,38 @@
{
return iterator ( root, false );
}
+
+ const_iterator begin() const
+ {
+ return const_iterator (root, true);
+ }
+
+ const_iterator end() const
+ {
+ return const_iterator ( root, false );
+ }
+
+ reverse_iterator rbegin()
+ {
+ return reverse_iterator(root,true);
+ }
+
+ reverse_iterator rend()
+ {
+ return reverse_iterator(root,false);
+ }
+
+ const_reverse_iterator rbegin() const
+ {
+ return const_reverse_iterator(root,true);
+ }
+
+ const_reverse_iterator rend() const
+ {
+ return const_reverse_iterator(root,false);
+ }
- bool find(const key_type &k)
+ bool exists(const key_type &k)
{
std::pair<std::size_t,int> common;
patricia_node *node;
@@ -113,7 +148,23 @@
if(node==0) return 0;
common=get_common_bits(node->value.first,k);
return (common.second==2);
- return true;
+ }
+
+ iterator find(const key_type &k)
+ {
+ std::pair<patricia_node*,patricia_node*> node_pair;
+ #ifndef FORWARD
+ node_pair=find_node_prev(root,k,iterator_cat());
+ #else
+ node_pair=find_node_prev(root,k,0);
+ #endif
+ if ( node_pair.first==0) return end();
+ return iterator(node_pair.first,node_pair.second);
+ }
+
+ const_iterator find(const key_type &k) const
+ {
+ return const_cast<patricia *>(this)->find(k);
}
void erase(const key_type &k)
@@ -124,11 +175,14 @@
erase(k,0);
#endif
}
+
+ void erase(const iterator &it)
+ {
+ erase(it.next,it.cur);
+ }
bool empty() const
{
- //if(root)
- // std::cout<<"NOT EMPTY "<<root->value.first<<std::endl;
return root==0;
}
@@ -166,6 +220,45 @@
}
}
+ std::size_t size() const
+ {
+ patricia_node *cur,*prev;
+ std::size_t ret_size=0;
+
+ prev=cur=root;
+ while(cur)
+ {
+ if(cur->left==prev && cur->left->par==cur)
+ {
+ prev=cur;
+ cur=(cur->right && cur->right->par==cur)?cur->right:cur->par;
+ }
+ else
+ if(cur->right==prev && cur->right->par==cur)
+ {
+ prev=cur;
+ cur=cur->par;
+ }
+ else
+ {
+ ret_size++;
+ std::cout<<cur->value.first<<std::endl;
+ prev=cur;
+ assert(cur!=cur->par);
+ //assert(cur->right!=cur);
+ //assert(cur->right->par==cur);
+ //std::cout<<"RIGHT: "<<cur->right->value.first<<std::endl;
+ cur=(cur->left && cur->left->par==cur)? cur->left
+ : ( (cur->right && cur->right->par==cur)? cur->right
+ : cur->par );
+ }
+ //std::cout<<((prev->left==cur)?"GOING LEFT":(prev->right==cur)?
+ //"GOING RIGHT":"GOING UP")<<std::endl;
+ assert(ret_size!=10);
+ }
+ return ret_size;
+ }
+
~patricia()
{
this->clear();
@@ -401,8 +494,9 @@
return n==0? 1 : ( ( element&(1<<(bit_width - n )) ) !=0 );
}
- //returns inclusive of end bit after each pos and the not(un) common bit in k1;
- //returns not common bit as two if both keys are equal.
+ /* returns inclusive of end bit after each pos and the not(un) common bit in k1;
+ * returns not common bit as two if both keys are equal.
+ */
inline std::pair<std::size_t,int> get_common_bits(const key_type &k1,const key_type &k2) const
{
key_iterator k1_it,k2_it,k1_end,k2_end;
@@ -619,51 +713,27 @@
return std::make_pair(next,cur);
}
- template<class T>
- void erase(const key_type& key,T)
+ /* The node pointed to by found. where prev is the found
+ * has a uplink from prev.
+ * Used by erase(key) and erase(iterator);
+ */
+ void erase(patricia_node*found,patricia_node *prev)
{
- if(root==0) return;
- patricia_node *cur,*next=0,*found;
- key_iterator it, end_it;
- it=Key_traits::begin(key);
-
- std::size_t key_size=key.size();
- std::pair<patricia_node*,patricia_node*> temp_pair,check_pair;
+ if(root==0 || found==0) return;
- if(root==0) return;
- assert(root->par==0);
- std::cout<< ((root->left!=0)?" \"\" exists":"\"\" does not exists")<<std::endl;
-
- assert( (root->left!=0 && root->left!=root)? root->left->par==root: 1 );
-
- std::cout<<(root->par==0)<<" root key:"<<root->value.first<<std::endl;
- cur=root;
- next=root;
-
-
- temp_pair=find_node_prev(root,key,T(),key_size);
- found=next=temp_pair.first;
- cur=temp_pair.second;
- if(found==0) return;
- check_pair=find_node_prev(root,key,rand_tag(),key_size);
- std::cout<<"KEY=="<<key<<";Next key=="<<temp_pair.first->value.first
- <<";Cur key=="<<temp_pair.second->value.first<<std::endl;
-
- assert(check_pair==temp_pair);
-
- std::cout<<"in erase: found "<<found->value.first<<" and prev "<<cur->value.first<<std::endl;
+ std::cout<<"in erase: found "<<found->value.first<<" and prev "<<prev->value.first<<std::endl;
if ( found-> par == 0 ) { //root node
std::cout<<"par"<<std::endl;
assert(root==found);
- if( (found->right==0 || found->left==0) && found==cur){ //only root or only ""
+ if( (found->right==0 || found->left==0) && found==prev){ //only root or only ""
deallocate_node(found);
root=0;
return;
}
std::cout<<"wrong place"<<std::endl;
- if(cur==found){ //also takes care of "" at the root
+ if(prev==found){ //also takes care of "" at the root
root=(found->right==found)?found->left:found->right;
if(root) root->par=0;
deallocate_node(found);
@@ -672,18 +742,24 @@
}
else
if ( found->right==0 || found->left==0 )
- cur=found;
+ prev=found;
std::cout<<"here"<<std::endl;
- if ( cur == found ) { //deleting the leaf node. //this case for root node is handled before
+ if ( prev == found ) { //deleting the leaf node. //this case for root node is handled before
if ( found->par->right == found )
+ {
found->par->right = (found->right==found)?found->left:found->right;
+ if( found->par->right && found==found->par->right->par ) found->par->right->par=found->par;
+ }
else
if ( found->par->left == found )
+ {
found->par->left = (found->right==found)?found->left:found->right;
+ if( found->par->left && found==found->par->left->par ) found->par->left->par=found->par;
+ }
else
assert(false);
- std::cout<<"cur==found with key="<<key<<std::endl;
+ //std::cout<<"prev==found with key="<<key<<std::endl;
if ( found->right==0 || found->left==0 )
{
assert(found->par==root);
@@ -693,35 +769,47 @@
return;
}
- temp_pair=find_node_prev(cur,cur->value.first,T(),cur->value.first.size());
- /*check_pair=find_node_prev(cur,cur->value.first,rand_tag(),cur->value.first.size());
-
- std::cout<<"KEY=="<<cur->value.first<<";Next key=="<<temp_pair.first->value.first
- <<";Cur key=="<<temp_pair.second->value.first<<std::endl;
- std::cout<<"KEY=="<<cur->value.first<<";Next key=="<<check_pair.first->value.first
- <<";Cur key=="<<check_pair.second->value.first<<std::endl;
- assert(check_pair==temp_pair);*/
-
- next=temp_pair.first;
- cur=temp_pair.second;
- assert(next->par);
-
- if(next->par->right==next) {
- next->par->right=(next->right==found)?next->left:next->right;
- if( next->right!=next && next->left!=next && next->par->right ) next->par->right->par=next->par;
+ if(prev->par->right==prev) {
+ prev->par->right=(prev->right==found)?prev->left:prev->right;
+ if( prev->right!=prev && prev->left!=prev && prev->par->right ) prev->par->right->par=prev->par;
}
else {
std::cout<<"far away here"<<std::endl;
- next->par->left=(next->right==found)?next->left:next->right;
- if( next->right!=next && next->left!=next && next->par->left) next->par->left->par=next->par;
+ prev->par->left=(prev->right==found)?prev->left:prev->right;
+ if( prev->right!=prev && prev->left!=prev && prev->par->left) prev->par->left->par=prev->par;
}
if(found->par==0)
- root=next;
- copy_node_ptr(next,found);
+ root=prev;
+ copy_node_ptr(prev,found);
deallocate_node(found);
}
+ template<class T>
+ void erase(const key_type& key,T)
+ {
+ patricia_node *cur,*found;
+ std::pair<patricia_node*,patricia_node*> temp_pair,check_pair;
+
+ if(root==0) return;
+
+ assert(root->par==0);
+
+ std::cout<< ((root->left!=0)?" \"\" exists":"\"\" does not exists")<<std::endl;
+
+ assert( (root->left!=0 && root->left!=root)? root->left->par==root: 1 );
+
+ temp_pair=find_node_prev(root,key,T());
+ found=temp_pair.first;
+ cur=temp_pair.second;
+ if(found==0) return;
+
+ //check_pair=find_node_prev(root,key,rand_tag());
+ //assert(check_pair==temp_pair);
+
+ erase(found,cur);
+ }
+
void inline deallocate_node(patricia_node *&found)
{
node_allocator.destroy(found);
@@ -780,27 +868,27 @@
}
cur=&root;
- std::cout<<"OTHER ROOT:"<<other_root<<std::endl;
+ //std::cout<<"OTHER ROOT:"<<other_root<<std::endl;
other_cur=&other_root;
other_prev=0;
prev=0;
while(true)
{
- assert(prev!=other_root);
+ //assert(prev!=other_root);
if( (*other_cur) && (*other_cur)->par==other_prev)
{
(*cur)=node_allocator.allocate(1);
new(*cur) patricia_node(**other_cur);
- assert((*cur)!=other_root);
- assert(other_root);
- assert((*cur)->right!=other_root);
+ //assert((*cur)!=other_root);
+ //assert(other_root);
+ //assert((*cur)->right!=other_root);
(*cur)->par = prev;
- std::cout<<(**cur).value.first<<" "<<(prev==0?"NULL":prev->value.first)<<std::endl;
+ //std::cout<<(**cur).value.first<<" "<<(prev==0?"NULL":prev->value.first)<<std::endl;
other_prev=*other_cur;
other_cur=&(other_prev->left);
prev=*cur;
cur=&(prev->left);
- std::cout<<"copy:here1"<<std::endl;
+ //std::cout<<"copy:here1"<<std::endl;
continue;
}
std::cout<<"copy:here2"<<std::endl;
@@ -815,7 +903,7 @@
cur=&(prev->right);
std::cout<<prev->value.first<<std::endl;
std::cout<<( (*other_cur)?(*other_cur)->value.first:"HOW NULL" )<<std::endl;
- assert((*cur)!=other_root);
+ //assert((*cur)!=other_root);
}
else
{
@@ -827,7 +915,7 @@
prev=prev->par;
if(other_prev==0)
{
- std::cout<<"ROOT:"<<root<<std::endl;
+ //std::cout<<"ROOT:"<<root<<std::endl;
return;
}
}
@@ -836,8 +924,31 @@
}
}
}
+
};
+template<class Key,class Mapped,class Key_traits,class Alloc >
+bool operator == (const patricia<Key,Mapped,Key_traits,Alloc> & p1,
+ const patricia<Key,Mapped,Key_traits,Alloc>& p2)
+{
+ typedef typename patricia<Key,Mapped,Key_traits,Alloc>::const_iterator const_iterator;
+ const_iterator it_1, it_2, end_it_1, end_it_2;
+
+ it_1=p1.begin();
+ it_2=p2.begin();
+
+ while ( it_1 != p1.end() && it_2 != p2.end()
+ && (*it_1).first == (*it_2).first && (*it_1).second == (*it_2).second )
+ {
+ it_1++;
+ it_2++;
+ }
+
+ if( it_1 == p1.end() && it_2 == p2.end() )
+ return true;
+ return false;
+}
+
}//namespace dsearch
}//namespace boost
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk