00001
#ifndef __IntervalSequenceTree_h__
00002
#define __IntervalSequenceTree_h__
00003
00004
#include <vector>
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
template <
bool Condition,
class If,
class Then>
00016 class type_select
00017 {
00018
public:
00019 typedef If
type;
00020 };
00021
00022
template <
class If,
class Then>
00023 class type_select<false, If, Then>
00024 {
00025
public:
00026 typedef Then
type;
00027 };
00028
00029 static const uint64 IST_END = ((0xFFFFFFFF << 31) << 1 ) + 0xFFFFFFFF;
00030
00040
template<
class Key,
class Allocator = allocator<Key> >
00041 class IntervalSequenceTree
00042 {
00043
public:
00044 typedef Key
value_type;
00045
00046
00047 typedef Allocator
allocator_type;
00048 typedef typename Allocator::reference
reference;
00049 typedef typename Allocator::const_reference
const_reference;
00050 typedef typename Allocator::size_type
size_type;
00051 typedef typename Allocator::difference_type
difference_type;
00052 typedef typename Allocator::pointer
pointer;
00053 typedef typename Allocator::const_pointer
const_pointer;
00054
00055
00056
protected:
00065 class IstNode {
00066
public:
00067 IstNode*
parent;
00068 IstNode*
left;
00069 IstNode*
right;
00070 size_type subtree_size;
00071 size_type length;
00072 Key*
key;
00073
00074 IstNode() :
00075
parent( NULL ),
00076
left( NULL ),
00077
right( NULL ),
00078
subtree_size( 0 ),
00079
length( 0 ),
00080
key( NULL ) {}
00081 };
00082 typedef typename Allocator::template rebind<IstNode>::other
node_allocator_type;
00083
00084 typedef typename node_allocator_type::pointer
node_pointer;
00085 typedef typename node_allocator_type::const_pointer
const_node_pointer;
00086
00087
00088
00089
00090
public:
00091
00092
00093
template <
bool is_const>
00094 class __generic_iterator
00095 {
00096
public:
00097 typedef typename IntervalSequenceTree::value_type value_type;
00098
00099
typedef typename type_select<is_const,
typename IntervalSequenceTree::const_pointer,
00100 typename IntervalSequenceTree::pointer>::type
pointer;
00101
typedef typename type_select<is_const,
typename IntervalSequenceTree::const_reference,
00102 typename IntervalSequenceTree::reference>::type
reference;
00103 typedef bidirectional_iterator_tag
iterator_category;
00104
00105 __generic_iterator() {}
00106 __generic_iterator(
const __generic_iterator<false>& i) :
ptr_(i.
ptr_) {}
00107 reference operator * ()
const {
return ptr_->data_;}
00108 pointer operator -> ()
const {
return &
ptr_->data_;}
00109 __generic_iterator&
operator ++ () {
increment((
const IstNode*&)
ptr_);
return *
this;}
00110 __generic_iterator operator ++ (
int) {
__generic_iterator tmp(*
this); ++(*this);
return tmp;}
00111 __generic_iterator&
operator -- () {
decrement((
const IstNode*&)
ptr_);
return *
this;}
00112 __generic_iterator operator -- (
int) {
__generic_iterator tmp(*
this); --(*this);
return tmp;}
00113 friend bool operator ==(
const __generic_iterator& x,
const __generic_iterator& y) {
return x.
ptr_ == y.
ptr_;}
00114 friend bool operator !=(
const __generic_iterator& x,
const __generic_iterator& y) {
return x.
ptr_ != y.
ptr_;}
00115
private:
00116
typedef typename type_select<is_const,
typename IntervalSequenceTree::node_pointer,
00117 typename IntervalSequenceTree::const_node_pointer>::type
node_pointer;
00118
00119 node_pointer ptr_;
00120
00121 explicit __generic_iterator(
node_pointer n) :
ptr_(n) {}
00122
00123 friend class __generic_iterator<true>;
00124
friend class IntervalSequenceTree;
00125 };
00126
00127 friend class __generic_iterator<false>;
00128 friend class __generic_iterator<true>;
00129 typedef __generic_iterator<false> iterator;
00130 typedef __generic_iterator<true> const_iterator;
00131 typedef std::reverse_iterator< iterator >
reverse_iterator;
00132 typedef std::reverse_iterator< const_iterator >
const_reverse_iterator;
00133
00134
00135
00136
IntervalSequenceTree();
00137
template<
class InputIterator >
00138
IntervalSequenceTree( InputIterator first, InputIterator last );
00139
IntervalSequenceTree(
const IntervalSequenceTree& ist );
00140
IntervalSequenceTree&
operator=(
const IntervalSequenceTree& ist );
00141
~IntervalSequenceTree();
00142
00143
00144
iterator begin();
00145
const_iterator begin() const;
00146
iterator end();
00147
const_iterator end() const;
00148
reverse_iterator rbegin();
00149
const_reverse_iterator rbegin() const;
00150
reverse_iterator rend();
00151
const_reverse_iterator rend() const;
00152
size_type max_size() const;
00153
bool empty() const;
00154
00155
00156
iterator insert( const
value_type& val,
size_type point = IST_END );
00157 template <class InputIterator>
00158
void insert(InputIterator first, InputIterator last,
size_type point = IST_END );
00159
00160
size_type erase(
size_type point,
size_type length );
00161
void erase(
iterator first,
iterator last );
00162
00163
00164
iterator find(
size_type point );
00165
const_iterator find(
size_type point ) const;
00166
00167
00171
size_type length() const;
00172
size_type nodeCount() const;
00173
size_type countNodes(
IstNode* x = NULL ) const;
00174
00175 protected:
00176 IstNode *root;
00177 IstNode *leftmost;
00178 IstNode *rightmost;
00180 static
void propogateChanges(
IstNode* cur_node,
int64 length_diff,
int64 subtree_diff );
00181 static
IstNode* recursiveFind(
size_type& point,
IstNode* node );
00182 static
void increment(
IstNode*& x);
00183
void decrement(
IstNode*& x) const;
00184 static
void deleteSubtree(
IstNode*& istn );
00185 static
void checkTree(
IstNode* cur_node );
00186 };
00187
00188
00189
00190
00191
00192
00193 template< class Key, class Allocator >
00194 inline
00195 IntervalSequenceTree< Key, Allocator >::
IntervalSequenceTree(){
00196 root = NULL;
00197 leftmost = NULL;
00198 rightmost = NULL;
00199
00200 }
00201
00202
template<
class Key,
class Allocator >
00203
template<
class InputIterator >
00204 IntervalSequenceTree< Key, Allocator >::IntervalSequenceTree( InputIterator first, InputIterator last ){
00205
insert( first, last );
00206 }
00207
00208
template<
class Key,
class Allocator >
00209 IntervalSequenceTree< Key, Allocator >::IntervalSequenceTree(
const IntervalSequenceTree& ist ){
00210
insert( ist.
begin(), ist.
end() );
00211 }
00212
00213
template<
class Key,
class Allocator >
00214 IntervalSequenceTree< Key, Allocator >&
IntervalSequenceTree< Key, Allocator >::operator=(
const IntervalSequenceTree& ist ){
00215
insert( ist.
begin(), ist.
end() );
00216 }
00217
00218
template<
class Key,
class Allocator >
00219 IntervalSequenceTree< Key, Allocator >::~IntervalSequenceTree(){
00220
deleteSubtree(
root );
00221 }
00222
00223
template<
class Key,
class Allocator >
00224
typename IntervalSequenceTree< Key, Allocator >::iterator
00225 IntervalSequenceTree< Key, Allocator >::begin(){
00226
return iterator(
leftmost );
00227 }
00228
00229
template<
class Key,
class Allocator >
00230
typename IntervalSequenceTree< Key, Allocator >::const_iterator
00231 IntervalSequenceTree< Key, Allocator >::begin()
const{
00232
return const_iterator(
leftmost );
00233 }
00234
00235
template<
class Key,
class Allocator >
00236
typename IntervalSequenceTree< Key, Allocator >::iterator
00237 IntervalSequenceTree< Key, Allocator >::end(){
00238
return iterator( NULL );
00239 }
00240
00241
template<
class Key,
class Allocator >
00242
typename IntervalSequenceTree< Key, Allocator >::const_iterator
00243 IntervalSequenceTree< Key, Allocator >::end()
const{
00244
return const_iterator( NULL );
00245 }
00246
00247
template<
class Key,
class Allocator >
00248
typename IntervalSequenceTree< Key, Allocator >::reverse_iterator
00249 IntervalSequenceTree< Key, Allocator >::rbegin(){
00250
return reverse_iterator(
end() );
00251 }
00252
00253
template<
class Key,
class Allocator >
00254
typename IntervalSequenceTree< Key, Allocator >::const_reverse_iterator
00255 IntervalSequenceTree< Key, Allocator >::rbegin()
const{
00256
return const_reverse_iterator(
end() );
00257 }
00258
00259
template<
class Key,
class Allocator >
00260
typename IntervalSequenceTree< Key, Allocator >::reverse_iterator
00261 IntervalSequenceTree< Key, Allocator >::rend(){
00262
return reverse_iterator(
begin() );
00263 }
00264
00265
template<
class Key,
class Allocator >
00266
typename IntervalSequenceTree< Key, Allocator >::const_reverse_iterator
00267 IntervalSequenceTree< Key, Allocator >::rend()
const{
00268
return const_reverse_iterator(
begin() );
00269 }
00270
00271
template<
class Key,
class Allocator >
00272
typename IntervalSequenceTree< Key, Allocator >::size_type
00273 IntervalSequenceTree< Key, Allocator >::max_size()
const{
00274
return IST_END - 1;
00275 }
00276
00277
template<
class Key,
class Allocator >
00278 bool IntervalSequenceTree< Key, Allocator >::empty()
const{
00279
return root == NULL ?
true :
false;
00280 }
00281
00282
template<
class Key,
class Allocator >
00283 void IntervalSequenceTree< Key, Allocator >::checkTree(
00284
IntervalSequenceTree< Key, Allocator >::
IstNode* cur_node ){
00285
if( cur_node ){
00286
if( cur_node->parent == cur_node )
00287 cerr <<
"freakout\n";
00288
checkTree( cur_node->left );
00289
checkTree( cur_node->right );
00290 }
00291 }
00292
00293
template<
class Key,
class Allocator >
00294
typename IntervalSequenceTree< Key, Allocator >::iterator
00295
IntervalSequenceTree< Key, Allocator >::insert(
00296
const Key& val,
00297
IntervalSequenceTree< Key, Allocator >::size_type point )
00298 {
00299 size_type iv_offset = point;
00300 IstNode* ins_node =
recursiveFind( iv_offset, root );
00301 IstNode* new_node =
new IstNode();
00302 new_node->key =
new Key( val );
00303 new_node->length = val.GetLength();
00304 new_node->subtree_size = 0;
00305
if( ins_node == NULL ){
00306
00307 rightmost = new_node;
00308
if( root == NULL ){
00309 root = new_node;
00310 leftmost = new_node;
00311
return iterator( new_node );
00312 }
00313
00314 ins_node = NULL;
00315
decrement( ins_node );
00316
00317 IstNode* new_parent =
new IstNode();
00318 new_parent->left = ins_node;
00319 new_parent->right = new_node;
00320 new_parent->parent = ins_node->parent;
00321
if( new_parent->parent == NULL )
00322
root = new_parent;
00323
else
00324 new_parent->
parent->
right = new_parent;
00325 ins_node->
parent = new_parent;
00326 new_parent->
length = ins_node->length;
00327
00328
00329
00330
00331
00332
propogateChanges( new_parent, new_node->length, 2 );
00333
return iterator( new_node );
00334 }
00335
00336
00337
00338
if( iv_offset == 0 ){
00339 IstNode* new_parent =
new IstNode();
00340 new_parent->left = new_node;
00341 new_parent->right = ins_node;
00342 new_parent->parent = ins_node->parent;
00343
if( new_parent->parent->right == ins_node )
00344 new_parent->parent->right = new_parent;
00345
else
00346 new_parent->parent->left = new_parent;
00347 new_parent->length = ins_node->length;
00348
00349 ins_node->parent = new_parent;
00350 new_node->parent = new_parent;
00351
00352
if( point == 0 )
00353
leftmost = new_node;
00354
00355
00356
00357
00358
propogateChanges( new_parent, new_node->length, 2 );
00359 }
else{
00360
00361 IstNode* new_gp =
new IstNode();
00362 IstNode* new_parent =
new IstNode();
00363 new_gp->parent = ins_node->parent;
00364 new_gp->right = new_parent;
00365 new_gp->left =
new IstNode();
00366 new_gp->left->key =
new Key( *ins_node->key );
00367 new_gp->left->key->CropEnd( ins_node->length - iv_offset );
00368 new_gp->left->length = new_gp->left->key->GetLength();
00369 new_gp->left->parent = new_gp;
00370
00371 ins_node->key->CropStart( iv_offset );
00372 ins_node->length = ins_node->key->GetLength();
00373 ins_node->parent = new_parent;
00374 new_node->parent = new_parent;
00375 new_parent->left = new_node;
00376 new_parent->right = ins_node;
00377 new_parent->parent = new_gp;
00378 new_parent->length = new_node->length + ins_node->length;
00379 new_parent->subtree_size = 2;
00380
00381 new_gp->length = ins_node->length + new_gp->left->length;
00382 new_gp->subtree_size = 1;
00383
if( new_gp->parent == NULL ){
00384
root = new_gp;
00385
leftmost = new_gp->
left;
00386
rightmost = ins_node;
00387 }
else if( new_gp->parent->right == ins_node )
00388 new_gp->
parent->
right = new_gp;
00389
else
00390 new_gp->
parent->
left = new_gp;
00391
00392
00393
00394
00395
00396
00397
00398 new_gp->
subtree_size = -1;
00399
propogateChanges( new_gp, new_node->length, 4 );
00400 }
00401
return iterator( new_node );
00402 }
00403
00404
template<
class Key,
class Allocator >
00405
template <
class InputIterator>
00406 void IntervalSequenceTree< Key, Allocator >::insert(
00407 InputIterator first,
00408 InputIterator last,
00409
IntervalSequenceTree< Key, Allocator >::
size_type point )
00410 {
00411
00412 }
00413
00414
template<
class Key,
class Allocator >
00415
typename IntervalSequenceTree< Key, Allocator >::size_type
00416 IntervalSequenceTree< Key, Allocator >::erase(
00417
IntervalSequenceTree< Key, Allocator >::
size_type point,
00418
IntervalSequenceTree< Key, Allocator >::
size_type length )
00419 {
00420
size_type iv_offset = point;
00421
IstNode* ins_node =
recursiveFind( iv_offset,
root );
00422
00423
00424
00425
size_type deleted_nodes = 0;
00426
while( length > 0 ){
00427
if( ins_node == NULL ){
00428
00429
return deleted_nodes;
00430 }
00431
if( iv_offset == 0 ){
00432
if( length >= ins_node->
length ){
00433
00434 length -= ins_node->
length;
00435
if( ins_node->
parent == NULL ){
00436
00437
delete ins_node;
00438
root = NULL;
00439
leftmost = NULL;
00440
rightmost = NULL;
00441
return deleted_nodes + 1;
00442 }
00443
00444
IstNode* other_child, *del_node;
00445
if( ins_node->
parent->
left == ins_node ){
00446 other_child = ins_node->
parent->
right;
00447 }
else if( ins_node->
parent->
right == ins_node ){
00448 other_child = ins_node->
parent->
left;
00449 }
00450 del_node = ins_node;
00451
increment( ins_node );
00452
00453
00454
IstNode* tmp_parent = other_child->
parent;
00455
IstNode* tmp_gp = tmp_parent->
parent;
00456 *tmp_parent = *other_child;
00457 tmp_parent->
parent = tmp_gp;
00458
if( tmp_parent->
left )
00459 tmp_parent->
left->
parent = tmp_parent;
00460
if( tmp_parent->
right )
00461 tmp_parent->
right->
parent = tmp_parent;
00462
if( ins_node == other_child )
00463 ins_node = tmp_parent;
00464
delete other_child;
00465
00466
00467 tmp_parent = tmp_parent->
parent;
00468
00469
propogateChanges( tmp_parent, -del_node->
length, -2 );
00470
00471
00472
delete del_node;
00473 ++deleted_nodes;
00474 }
else{
00475
00476 ins_node->
key->CropStart( length );
00477
00478
propogateChanges( ins_node, -length, 0 );
00479
return deleted_nodes;
00480 }
00481 }
else if( length >= ins_node->
length - iv_offset ){
00482
00483 ins_node->
key->CropEnd( ins_node->
length - iv_offset );
00484 length -= ins_node->
length - iv_offset;
00485
00486
propogateChanges( ins_node, -(ins_node->
length - iv_offset), 0 );
00487
increment( ins_node );
00488 iv_offset = 0;
00489 }
else{
00490
00491
IstNode* new_parent =
new IstNode();
00492 new_parent->
left = ins_node;
00493 new_parent->
length = ins_node->
length;
00494 new_parent->
right =
new IstNode();
00495 new_parent->
right->
key =
new Key( *ins_node->
key );
00496 new_parent->
right->
length = ins_node->
length - length - iv_offset;
00497 new_parent->
right->
key->CropStart( length + iv_offset );
00498 new_parent->
left->
key->CropEnd( ins_node->
length - iv_offset );
00499 new_parent->
left->
length = iv_offset;
00500 new_parent->
parent = ins_node->
parent;
00501
if( new_parent->
parent == NULL ){
00502
root = new_parent;
00503
rightmost = new_parent->
right;
00504 }
else if( new_parent->
parent->
left == ins_node )
00505 new_parent->
parent->
left = new_parent;
00506
else if( new_parent->
parent->
right == ins_node )
00507 new_parent->
parent->
right = new_parent;
00508
00509 ins_node->
parent = new_parent;
00510 new_parent->
right->
parent = new_parent;
00511
00512
00513
00514
propogateChanges( new_parent, -length, 2 );
00515
return deleted_nodes;
00516 }
00517 }
00518
return deleted_nodes;
00519 }
00520
00521
template<
class Key,
class Allocator >
00522 void IntervalSequenceTree< Key, Allocator >::propogateChanges(
00523
IstNode* cur_node,
00524
int64 length_diff,
00525
int64 subtree_diff )
00526 {
00527 vector< IstNode* > node_stack;
00528
while( cur_node != NULL ){
00529
if( cur_node->
parent == cur_node )
00530 cerr <<
"when I say oh, you say shit!";
00531 cur_node->
length += length_diff;
00532 cur_node->
subtree_size += subtree_diff;
00533 node_stack.push_back( cur_node );
00534 cur_node = cur_node->
parent;
00535 }
00536 }
00537
00538
template<
class Key,
class Allocator >
00539 void IntervalSequenceTree< Key, Allocator >::erase(
00540
IntervalSequenceTree< Key, Allocator >::
iterator first,
00541
IntervalSequenceTree< Key, Allocator >::
iterator last )
00542 {
00543
00544 }
00545
00546
template<
class Key,
class Allocator >
00547
typename IntervalSequenceTree< Key, Allocator >::iterator
00548 IntervalSequenceTree< Key, Allocator >::find(
00549
IntervalSequenceTree< Key, Allocator >::
size_type point )
00550 {
00551
return iterator(
IntervalSequenceTree< Key, Allocator >::
recursiveFind( point,
root ) );
00552 }
00553
00554
template<
class Key,
class Allocator >
00555
typename IntervalSequenceTree< Key, Allocator >::const_iterator
00556 IntervalSequenceTree< Key, Allocator >::find(
00557
IntervalSequenceTree< Key, Allocator >::
size_type point )
const
00558
{
00559
return const_iterator(
IntervalSequenceTree< Key, Allocator >::
recursiveFind( point,
root ) );
00560 }
00561
00562
template<
class Key,
class Allocator >
00563
typename IntervalSequenceTree< Key, Allocator >::IstNode*
00564 IntervalSequenceTree< Key, Allocator >::recursiveFind(
00565
IntervalSequenceTree< Key, Allocator >::
size_type& point,
00566
IstNode* node ) {
00567
00568
if( node == NULL )
00569
return NULL;
00570
00571
00572
if( node->
key != NULL )
00573
return node;
00574
00575
if( point < node->
length ){
00576
if( node->
left ){
00577
if( point < node->
left->
length )
00578
return recursiveFind( point, node->
left );
00579 point -= node->
left->
length;
00580 }
00581
return recursiveFind( point, node->
right );
00582 }
00583 point -= node->
length;
00584
00585
return NULL;
00586 }
00587
00588
template<
class Key,
class Allocator >
00589
typename IntervalSequenceTree< Key, Allocator >::size_type
00590 IntervalSequenceTree< Key, Allocator >::length()
const{
00591
return root == NULL ? 0 :
root->
length;
00592 }
00593
00594
template<
class Key,
class Allocator >
00595
typename IntervalSequenceTree< Key, Allocator >::size_type
00596 IntervalSequenceTree< Key, Allocator >::nodeCount()
const{
00597
return root == NULL ? 0 :
root->
subtree_size + 1;
00598 }
00599
00600
template<
class Key,
class Allocator >
00601
typename IntervalSequenceTree< Key, Allocator >::size_type
00602 IntervalSequenceTree< Key, Allocator >::countNodes(
IstNode* x )
const{
00603
if( x == NULL )
00604 x =
root;
00605
if( x->
key == NULL )
00606
return countNodes( x->
left ) +
countNodes( x->
right ) + 1;
00607
return 1;
00608 }
00609
00610
00611
template<
class Key,
class Allocator >
00612 void IntervalSequenceTree< Key, Allocator >::increment(
IstNode*& x) {
00613
00614
00615
while( x->
parent != NULL ){
00616
if( x == x->
parent->
left &&
00617 x->
parent->
right != NULL ){
00618 x = x->
parent->
right;
00619
break;
00620 }
else
00621 x = x->
parent;
00622 }
00623
00624
if( x->
parent == NULL ){
00625 x = NULL;
00626
return;
00627 }
00628
00629
00630
while( x->
key == NULL ){
00631
if( x->
left != NULL )
00632 x = x->
left;
00633
else if( x->
right != NULL )
00634 x = x->
right;
00635 }
00636 }
00637
00638
template<
class Key,
class Allocator >
00639 void IntervalSequenceTree< Key, Allocator >::decrement(
IstNode*& x)
const{
00640
if( x != NULL ){
00641
00642
00643
while( x->
parent != NULL ){
00644
if( x == x->
parent->
right &&
00645 x->
parent->
left != NULL){
00646 x = x->
parent->
left;
00647
break;
00648 }
else
00649 x = x->
parent;
00650 }
00651
00652
00653
if( x->
parent == NULL )
00654 x = NULL;
00655 }
else{
00656 x =
root;
00657 }
00658
00659
00660
while( x->
key == NULL ){
00661
if( x->
right != NULL )
00662 x = x->
right;
00663
else if( x->
left != NULL )
00664 x = x->
left;
00665 }
00666 }
00667
00668
template<
class Key,
class Allocator >
00669 void IntervalSequenceTree< Key, Allocator >::deleteSubtree(
IstNode*& istn ) {
00670
if( istn->
left != NULL )
00671
deleteSubtree( istn->
left );
00672
if( istn->
right != NULL )
00673
deleteSubtree( istn->
right );
00674
if( istn->
key != NULL )
00675
delete istn->
key;
00676
delete istn;
00677 }
00678
00679
00680
#endif // __IntervalSequenceTree_h__