MPQC 3.0.0-alpha
Loading...
Searching...
No Matches
avlmmap.h
1//
2// avlmmap.h --- definition for avl multimap class
3//
4// Copyright (C) 1996 Limit Point Systems, Inc.
5//
6// Author: Curtis Janssen <cljanss@ca.sandia.gov>
7// Maintainer: SNL
8//
9// This file is part of the SC Toolkit.
10//
11// The SC Toolkit is free software; you can redistribute it and/or modify
12// it under the terms of the GNU Library General Public License as published by
13// the Free Software Foundation; either version 2, or (at your option)
14// any later version.
15//
16// The SC Toolkit is distributed in the hope that it will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19// GNU Library General Public License for more details.
20//
21// You should have received a copy of the GNU Library General Public License
22// along with the SC Toolkit; see the file COPYING.LIB. If not, write to
23// the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24//
25// The U.S. Government is granted a limited license as per AL 91-7.
26//
27
28#ifndef _util_container_avlmmap_h
29#define _util_container_avlmmap_h
30
31#include <iostream>
32#include <functional>
33#include <vector>
34#include <stdexcept>
35
36#include <unistd.h> // for size_t on solaris
37#include <stdlib.h>
38
39namespace sc {
40
41template <class K, class T>
43 public:
44 std::pair<K,T> keyval;
48 int balance;
49 public:
50 AVLMMapNode(const std::pair<K,T> &kv): keyval(kv) {}
51 AVLMMapNode(const K& k, const T&v): keyval(std::make_pair(k,v)) {}
52 K& key() { return keyval.first; }
53 const K& key() const { return keyval.first; }
54 T& val() { return keyval.second; }
55 const T& val() const { return keyval.second; }
56};
57
58template <class T>
60 enum {default_chunksize = 4096};
61 struct chunk {
62 void *data;
63 chunk *next;
64 int current;
65 int chunksize;
66 chunk(int _chunksize, int datasize) {
67 data = new char[_chunksize*datasize];
68 next = 0;
69 current = 0;
70 chunksize = _chunksize;
71 }
72 ~chunk() {
73 delete[] (char*)data;
74 }
75 };
76 chunk *head;
77 long total;
78 public:
80 total = 0;
81 head = new chunk(default_chunksize, sizeof(T));
82 }
84 if (total != 0) {
85 std::cout << "chunks remain: " << total << std::endl;
86 abort();
87 }
88 for (chunk *i = head; i;) {
89 chunk *next = i->next;
90 delete i;
91 i = next;
92 }
93 }
94 void reinit() {
95 if (total != 0) {
96 std::cout << "reinit: chunks remain: " << total << std::endl;
97 abort();
98 }
99 for (chunk *i = head; i;) {
100 chunk *next = i->next;
101 delete i;
102 i = next;
103 }
104 head = new chunk(default_chunksize, sizeof(T));
105 }
106 void destroy(T*d) {
107 d->~T();
108 }
109 void deallocate(T*d,int n) {
110 // deallocated memory is not reclaimed until the chunk_allocator dtor
111 // is called
112 total -= n;
113 }
114 T *allocate(int n) {
115 if (n==1) {
116 if (head->current == head->chunksize) {
117 chunk *newhead = new chunk(default_chunksize, sizeof(T));
118 newhead->next = head;
119 head = newhead;
120 }
121 T *r = &((T*)head->data)[head->current];
122 head->current++;
123 total += n;
124 return r;
125 }
126 else if (n>0) {
127 chunk *newchunk = new chunk(n, sizeof(T));
128 newchunk->next = head->next;
129 head->next = newchunk;
130 total += n;
131 return (T*)newchunk->data;
132 }
133 else {
134 return 0;
135 }
136 }
137};
138
139template <class T>
141 public:
142 bool operator()(const T&a, const T&b) const {
143 return a < b;
144 }
145 int compare(const T&a, const T&b) const {
146 if (a < b) return -1;
147 else if (a > b) return 1;
148 return 0;
149 }
150};
151
152template <class K, class T, class C = tristate_less<K>,
153 class A = chunk_allocator<AVLMMapNode<K,T> > >
154// class A = std::allocator<AVLMMapNode<K,T> > >
155class AVLMMap {
156 private:
157 typedef AVLMMapNode<K,T> * link_type;
158 C key_comp_;
159 A alloc_;
160 size_t length_;
161 AVLMMapNode<K,T> *root_;
162 AVLMMapNode<K,T> *start_;
163 public:
164 static AVLMMapNode<K,T>*& rlink(AVLMMapNode<K,T>* n) { return n->rt; }
165 static AVLMMapNode<K,T>* rlink(const AVLMMapNode<K,T>* n) { return n->rt; }
166 static AVLMMapNode<K,T>*& llink(AVLMMapNode<K,T>* n) { return n->lt; }
167 static AVLMMapNode<K,T>* llink(const AVLMMapNode<K,T>* n) { return n->lt; }
168 static AVLMMapNode<K,T>*& uplink(AVLMMapNode<K,T>* n) { return n->up; }
169 static AVLMMapNode<K,T>* uplink(const AVLMMapNode<K,T>* n) { return n->up; }
170 static int& balance(AVLMMapNode<K,T>* n) { return n->balance; }
171 static int balance(const AVLMMapNode<K,T>* n) { return n->balance; }
172 static const K& key(const AVLMMapNode<K,T>* n) { return n->key(); }
173 int compare(const K&n,const K&m) const {
174 return key_comp_.compare(n,m);
175// This is for a standard boolean comparision operation
176// if (key_comp_(n, m)) return -1;
177// else if (key_comp_(m, n)) return 1;
178// return 0;
179 }
180 private:
181 void adjust_balance_insert(AVLMMapNode<K,T>* _A, AVLMMapNode<K,T>* child);
182 void adjust_balance_remove(AVLMMapNode<K,T>* _A, AVLMMapNode<K,T>* child);
183 void clear(AVLMMapNode<K,T>*);
184 public:
185 typedef C key_compare;
186 typedef std::pair<K,T> value_type;
187 class iterator {
188 friend class AVLMMap<K,T,C,A>;
189 public:
190 AVLMMapNode<K,T> *node;
191 public:
192 iterator(AVLMMapNode<K,T> *n = 0):node(n){}
193 iterator(const typename AVLMMap<K,T,C>::iterator &i) { node=i.node; }
194 void operator++() { AVLMMap<K,T,C>::next(node); }
195 void operator++(int) { operator++(); }
196 int operator == (const typename AVLMMap<K,T,C>::iterator &i) const
197 { return node == i.node; }
198 int operator != (const typename AVLMMap<K,T,C>::iterator &i) const
199 { return node != i.node; }
200 void operator = (const typename AVLMMap<K,T,C>::iterator &i)
201 { node = i.node; }
202 const K &key() const { return node->key(); }
203 std::pair<K,T> & operator *() { return node->keyval; }
204 std::pair<K,T> * operator->() { return &node->keyval; }
205 };
207 friend class AVLMMap<K,T,C,A>;
208 private:
209 const AVLMMapNode<K,T> *node;
210 public:
211 const_iterator(const AVLMMapNode<K,T> *n = 0):node(n){}
212 const_iterator(const typename AVLMMap<K,T,C>::const_iterator &i) { node=i.node; }
213 const_iterator(const typename AVLMMap<K,T,C>::iterator &i) { node=i.node; }
214 void operator++() { AVLMMap<K,T,C>::next(node); }
215 void operator++(int) { operator++(); }
216 int operator == (const typename AVLMMap<K,T,C>::const_iterator &i) const
217 { return node == i.node; }
218 int operator != (const typename AVLMMap<K,T,C>::const_iterator &i) const
219 { return node != i.node; }
220 void operator = (const typename AVLMMap<K,T,C>::const_iterator &i)
221 { node = i.node; }
222 const K &key() const { return node->key(); }
223 const std::pair<K,T> & operator *() { return node->keyval; }
224 const std::pair<K,T> * operator->() { return &node->keyval; }
225 };
226 private:
227 iterator subtree_insert_new_(AVLMMapNode<K,T> *root, AVLMMapNode<K,T> *node);
228 iterator subtree_insert_equal_(AVLMMapNode<K,T> *root, AVLMMapNode<K,T> *node);
229 iterator subtree_insert_unique_(AVLMMapNode<K,T> *root,
230 const std::pair<K,T> &ipair);
231 iterator subtree_find_(AVLMMapNode<K,T> *root, const K&);
232 const_iterator subtree_find_(const AVLMMapNode<K,T> *root, const K&) const;
233 public:
234 AVLMMap();
235 AVLMMap(const C& c);
236 AVLMMap(const AVLMMap<K,T,C,A>&m);
237 ~AVLMMap() { clear(); }
238 key_compare key_comp() const { return key_comp_; }
239 void initialize();
240 void clear() {
241 clear(root_);
242 length_ = 0;
243 root_ = 0;
244 start_ = 0;
245 // destroy the allocator
246 // this is needed to force deletion of all data if the chunk_allocator is used
247 alloc_.~A();
248 // reconstruct the allocator
249 new((void*)&alloc_)A;
250// alloc_.reinit();
251 }
252 // Insert an element. The element must not already exist.
253 iterator insert_new(const iterator &hint, const std::pair<K,T> &ipair);
254// // Insert an element. If an element with the same key already exists
255// // then a duplicate element will be added.
256// iterator insert_equal(const iterator &hint, const std::pair<K,T> &ipair);
257// // Insert an element. If an entry with the key already exists then
258// // this will do nothing and return the iterator for the pre-existing
259// // element.
260// iterator insert_unique(const iterator &hint, const std::pair<K,T> &ipair);
261 // slow; do not use:
262 iterator insert_equal(const iterator &hint, const std::pair<K,T> &ipair);
263 // Insert an element. The element must not already exist.
264 iterator insert_new(const std::pair<K,T> &ipair);
265 // Insert an element. If an element with the same key already exists
266 // then a duplicate element will be added.
267 iterator insert_equal(const std::pair<K,T> &ipair);
268 // Insert an element. If an entry with the key already exists then
269 // this will do nothing and return the iterator for the pre-existing
270 // element.
271 iterator insert_unique(const std::pair<K,T> &ipair);
272 // This is equivalent to insert_equal.
273 iterator insert(const std::pair<K,T> &ipair) { return insert_equal(ipair); }
274 // This is equivalent to insert_equal with a hint.
275 iterator insert(const iterator &hint, const std::pair<K,T> &ipair) { return insert_equal(hint, ipair); }
276
277 // Insert elements in the given range.
278 void insert(const const_iterator &b, const const_iterator &e) {
279 for (const_iterator i = b; i != e; i++) insert(*i);
280 }
281
282 void remove(AVLMMapNode<K,T>*);
283 iterator find(const K&);
284 const_iterator find(const K&) const;
285 iterator find(const iterator &hint, const K&);
286 const_iterator find(const const_iterator &hint, const K&) const;
287
288 void erase(const iterator &i) { remove(i.node); }
289
290 int height(AVLMMapNode<K,T>* node);
291 int height() { return height(root_); }
292 void check();
293 void check_node(AVLMMapNode<K,T>*) const;
294
295 AVLMMapNode<K,T>* start() const { return start_; }
296 static void next(const AVLMMapNode<K,T>*&);
297 static void next(AVLMMapNode<K,T>*&);
298
299 iterator begin() { return iterator(start()); }
300 const_iterator begin() const { return const_iterator(start()); }
301
302 iterator end() { return iterator(0); }
303 const_iterator end() const { return const_iterator(0); }
304
305 const_iterator lower_bound(const K& k) const;
306 const_iterator upper_bound(const K& k) const;
307 std::pair<const_iterator,const_iterator> equal_range(const K& k) const;
308
309 void print(std::ostream &o = std::cout) const;
310 size_t size() const { return length_; }
311 int depth(AVLMMapNode<K,T>*) const;
312};
313
314template <class K, class T, class C, class A>
315std::pair<typename AVLMMap<K,T,C,A>::const_iterator,
316 typename AVLMMap<K,T,C,A>::const_iterator>
317AVLMMap<K,T,C,A>::equal_range(const K& __k) const
318{
319 link_type __lb = 0; /* Last node which is not less than __k. */
320 link_type __ub = 0; /* Last node which is greater than __k. */
321 link_type __x = root_; /* Current node. */
322
323 while (__x != 0) {
324 int cmp = compare(key(__x), __k);
325 if (cmp == 1) {
326 __lb = __x;
327 __ub = __x;
328 __x = llink(__x);
329 }
330 else if (cmp == -1) {
331 __x = rlink(__x);
332 }
333 else {
334 // behaviours of lower_bound and upper_bound diverge here
335 link_type __saved_x = __x;
336 // find the lowerbound
337 __lb = __x, __x = llink(__x);
338 while (__x != 0)
339 if (!key_comp_(key(__x), __k))
340 __lb = __x, __x = llink(__x);
341 else
342 __x = rlink(__x);
343 // find the upperbound
344 __x = __saved_x;
345 __x = rlink(__x);
346 while (__x != 0)
347 if (key_comp_(__k, key(__x)))
348 __ub = __x, __x = llink(__x);
349 else
350 __x = rlink(__x);
351 }
352 }
353
354 typedef typename AVLMMap<K,T,C,A>::const_iterator iterator;
355 return std::pair<iterator,iterator>(__lb, __ub);
356}
357
358template <class K, class T, class C, class A>
359typename AVLMMap<K,T,C,A>::const_iterator
360AVLMMap<K,T,C,A>::lower_bound(const K& __k) const
361{
362 // this is the GNU STL RB tree algorithm
363 link_type __y = 0; /* Last node which is not less than __k. */
364 link_type __x = root_; /* Current node. */
365
366 while (__x != 0)
367 if (!key_comp_(key(__x), __k))
368 __y = __x, __x = llink(__x);
369 else
370 __x = rlink(__x);
371
372 return const_iterator(__y);
373}
374
375template <class K, class T, class C, class A>
376typename AVLMMap<K,T,C,A>::const_iterator
377AVLMMap<K,T,C,A>::upper_bound(const K& __k) const
378{
379 // this the GNU STL RB tree algorithm
380 link_type __y = 0; /* Last node which is greater than __k. */
381 link_type __x = root_; /* Current node. */
382
383 while (__x != 0)
384 if (key_comp_(__k, key(__x)))
385 __y = __x, __x = llink(__x);
386 else
387 __x = rlink(__x);
388
389 return const_iterator(__y);
390}
391
392template <class K, class T, class C, class A>
393inline typename AVLMMap<K,T,C,A>::iterator
394AVLMMap<K,T,C,A>::find(const K& k)
395{
396 return subtree_find_(root_,k);
397}
398
399template <class K, class T, class C, class A>
400inline typename AVLMMap<K,T,C,A>::const_iterator
401AVLMMap<K,T,C,A>::find(const K& k) const
402{
403 return subtree_find_(root_,k);
404}
405
406template <class K, class T, class C, class A>
407inline typename AVLMMap<K,T,C,A>::iterator
408AVLMMap<K,T,C,A>::find(const iterator &hint, const K& k)
409{
410 AVLMMapNode<K,T> *x = hint.node;
411 if (x == 0) return subtree_find_(root_,k);
412 AVLMMapNode<K,T> *y = uplink(x);
413 while (y != 0) {
414 int cmp = compare(k, key(x));
415 if (cmp == 0) return x;
416 int cmp2 = compare(k, key(y));
417 if (cmp2 == 0) return y;
418 if (cmp == -1 && cmp2 == 1) {
419 return subtree_find_(llink(x), k);
420 }
421 else if (cmp == 1 && cmp2 == -1) {
422 return subtree_find_(rlink(x), k);
423 }
424 x = y;
425 cmp = cmp2;
426 y = uplink(x);
427 }
428 return subtree_find_(x,k);
429}
430
431template <class K, class T, class C, class A>
432inline typename AVLMMap<K,T,C,A>::const_iterator
433AVLMMap<K,T,C,A>::find(const const_iterator &hint, const K& k) const
434{
435 const AVLMMapNode<K,T> *x = hint.node;
436 if (x == 0) return subtree_find_(root_,k);
437 const AVLMMapNode<K,T> *y = uplink(x);
438 while (y != 0) {
439 int cmp = compare(k, key(x));
440 if (cmp == 0) return x;
441 int cmp2 = compare(k, key(y));
442 if (cmp2 == 0) return y;
443 if (cmp == -1 && cmp2 == 1) {
444 return subtree_find_(llink(x), k);
445 }
446 else if (cmp == 1 && cmp2 == -1) {
447 return subtree_find_(rlink(x), k);
448 }
449 x = y;
450 cmp = cmp2;
451 y = uplink(x);
452 }
453 return subtree_find_(x,k);
454}
455
456template <class K, class T, class C, class A>
457typename AVLMMap<K,T,C,A>::iterator
458AVLMMap<K,T,C,A>::subtree_find_(AVLMMapNode<K,T> *root, const K& k)
459{
460 AVLMMapNode<K,T>* n = root;
461
462 while (n) {
463 int cmp = compare(key(n), k);
464 if (cmp < 0) n = rlink(n);
465 else if (cmp > 0) n = llink(n);
466 else return iterator(n);
467 }
468
469 return iterator(0);
470}
471
472template <class K, class T, class C, class A>
473typename AVLMMap<K,T,C,A>::const_iterator
474AVLMMap<K,T,C,A>::subtree_find_(const AVLMMapNode<K,T> *root, const K& k) const
475{
476 const AVLMMapNode<K,T>* n = root;
477
478 while (n) {
479 int cmp = compare(key(n), k);
480 if (cmp < 0) n = rlink(n);
481 else if (cmp > 0) n = llink(n);
482 else return const_iterator(n);
483 }
484
485 return const_iterator(0);
486}
487
488template <class K, class T, class C, class A>
489void
490AVLMMap<K,T,C,A>::remove(AVLMMapNode<K,T>* node)
491{
492 if (!node) return;
493
494 length_--;
495
496 if (node == start_) {
497 next(start_);
498 }
499
500 AVLMMapNode<K,T> *rebalance_point;
501 AVLMMapNode<K,T> *q;
502
503 if (llink(node) == 0) {
504 q = rlink(node);
505 rebalance_point = uplink(node);
506
507 if (q) uplink(q) = rebalance_point;
508
509 if (rebalance_point) {
510 if (rlink(rebalance_point) == node) rlink(rebalance_point) = q;
511 else llink(rebalance_point) = q;
512 }
513 else root_ = q;
514 }
515 else if (rlink(node) == 0) {
516 q = llink(node);
517 rebalance_point = uplink(node);
518
519 if (q) uplink(q) = rebalance_point;
520
521 if (rebalance_point) {
522 if (rlink(rebalance_point) == node) rlink(rebalance_point) = q;
523 else llink(rebalance_point) = q;
524 }
525 else root_ = q;
526 }
527 else {
528 AVLMMapNode<K,T> *r = node;
529 next(r);
530
531 if (r == 0 || llink(r) != 0) {
532 throw std::runtime_error("AVLMMap::remove: inconsistency");
533 }
534
535 if (r == rlink(node)) {
536 llink(r) = llink(node);
537 if (llink(r)) uplink(llink(r)) = r;
538 balance(r) = balance(node);
539 rebalance_point = r;
540 q = rlink(r);
541 }
542 else {
543 q = rlink(r);
544
545 rebalance_point = uplink(r);
546
547 if (llink(rebalance_point) == r) llink(rebalance_point) = q;
548 else rlink(rebalance_point) = q;
549
550 if (q) uplink(q) = rebalance_point;
551
552 balance(r) = balance(node);
553 rlink(r) = rlink(node);
554 llink(r) = llink(node);
555 if (rlink(r)) uplink(rlink(r)) = r;
556 if (llink(r)) uplink(llink(r)) = r;
557 }
558 if (r) {
559 AVLMMapNode<K,T>* up = uplink(node);
560 uplink(r) = up;
561 if (up) {
562 if (rlink(up) == node) rlink(up) = r;
563 else llink(up) = r;
564 }
565 if (up == 0) root_ = r;
566 }
567 }
568
569 // adjust balance won't work if both children are null,
570 // so handle this special case here
571 if (rebalance_point &&
572 llink(rebalance_point) == 0 && rlink(rebalance_point) == 0) {
573 balance(rebalance_point) = 0;
574 q = rebalance_point;
575 rebalance_point = uplink(rebalance_point);
576 }
577 adjust_balance_remove(rebalance_point, q);
578
579 alloc_.destroy(node);
580 alloc_.deallocate(node,1);
581}
582
583template <class K, class T, class C, class A>
584void
585AVLMMap<K,T,C,A>::print(std::ostream &o) const
586{
587 std::cout << "--------------------------" << std::endl;
588 for (AVLMMapNode<K,T>*n=start(); n; next(n)) {
589 int d = depth(n) + 1;
590 for (int i=0; i<d; i++) o << " ";
591 if (balance(n) == 1) o << " (+) " << key(n) << std::endl;
592 else if (balance(n) == -1) o << " (-) " << key(n) << std::endl;
593 else if (balance(n) == 0) o << " (.) " << key(n) << std::endl;
594 else o << " (" << balance(n) << ") " << key(n) << std::endl;
595 }
596}
597
598template <class K, class T, class C, class A>
599int
600AVLMMap<K,T,C,A>::depth(AVLMMapNode<K,T>*node) const
601{
602 int d = 0;
603 while (node) {
604 node = uplink(node);
605 d++;
606 }
607 return d;
608}
609
610template <class K, class T, class C, class A>
611void
612AVLMMap<K,T,C,A>::check_node(AVLMMapNode<K,T>*n) const
613{
614 if (uplink(n) && uplink(n) == n) abort();
615 if (llink(n) && llink(n) == n) abort();
616 if (rlink(n) && rlink(n) == n) abort();
617 if (rlink(n) && rlink(n) == llink(n)) abort();
618 if (uplink(n) && uplink(n) == llink(n)) abort();
619 if (uplink(n) && uplink(n) == rlink(n)) abort();
620 if (uplink(n) && !(llink(uplink(n)) == n
621 || rlink(uplink(n)) == n)) abort();
622}
623
624template <class K, class T, class C, class A>
625void
626AVLMMap<K,T,C,A>::clear(AVLMMapNode<K,T>*n)
627{
628 if (!n) return;
629 clear(llink(n));
630 clear(rlink(n));
631 alloc_.destroy(n);
632 alloc_.deallocate(n,1);
633}
634
635template <class K, class T, class C, class A>
636int
637AVLMMap<K,T,C,A>::height(AVLMMapNode<K,T>* node)
638{
639 if (!node) return 0;
640 int rh = height(rlink(node)) + 1;
641 int lh = height(llink(node)) + 1;
642 return rh>lh?rh:lh;
643}
644
645template <class K, class T, class C, class A>
646void
647AVLMMap<K,T,C,A>::check()
648{
649 AVLMMapNode<K,T>* node;
650 AVLMMapNode<K,T>* prev=0;
651 size_t computed_length = 0;
652 for (node = start(); node; next(node)) {
653 check_node(node);
654 if (prev && compare(key(prev),key(node)) > 0) {
655 throw std::runtime_error("nodes out of order");
656 }
657 prev = node;
658 computed_length++;
659 }
660 for (node = start(); node; next(node)) {
661 if (balance(node) != height(rlink(node)) - height(llink(node))) {
662 throw std::runtime_error("balance inconsistency");
663 }
664 if (balance(node) < -1 || balance(node) > 1) {
665 throw std::runtime_error("balance out of range");
666 }
667 }
668 if (length_ != computed_length) {
669 throw std::runtime_error("length error");
670 }
671}
672
673template <class K, class T, class C, class A>
674void
675AVLMMap<K,T,C,A>::next(const AVLMMapNode<K,T>*& node)
676{
677 const AVLMMapNode<K,T>* r;
678 if ((r = rlink(node))) {
679 node = r;
680 while ((r = llink(node))) node = r;
681 return;
682 }
683 while ((r = uplink(node))) {
684 if (node == llink(r)) {
685 node = r;
686 return;
687 }
688 node = r;
689 }
690 node = 0;
691}
692
693template <class K, class T, class C, class A>
694void
695AVLMMap<K,T,C,A>::next(AVLMMapNode<K,T>*& node)
696{
697 AVLMMapNode<K,T>* r;
698 if ((r = rlink(node))) {
699 node = r;
700 while ((r = llink(node))) node = r;
701 return;
702 }
703 while ((r = uplink(node))) {
704 if (node == llink(r)) {
705 node = r;
706 return;
707 }
708 node = r;
709 }
710 node = 0;
711}
712
713template <class K, class T, class C, class A>
714typename AVLMMap<K,T,C,A>::iterator
715AVLMMap<K,T,C,A>::insert_equal(const iterator &hint, const std::pair<K,T> &ipair)
716{
717 AVLMMapNode<K,T>* n = alloc_.allocate(1);
718 new((void*)n)AVLMMapNode<K,T>(ipair);
719
720 llink(n) = 0;
721 rlink(n) = 0;
722 balance(n) = 0;
723
724 AVLMMapNode<K,T> *x = hint.node;
725 if (x == 0) return subtree_insert_equal_(root_,n);
726 AVLMMapNode<K,T> *y = uplink(x);
727 while (y != 0) {
728 int cmp = compare(key(n), key(x));
729 if (cmp == 0) return subtree_insert_equal_(x, n);
730 int cmp2 = compare(key(n), key(y));
731 if (cmp2 == 0) return subtree_insert_equal_(y, n);
732 if (cmp == -1 && cmp2 == 1) {
733 y = llink(x);
734 if (y != 0) return subtree_insert_equal_(y, n);
735 else {
736 uplink(n) = x;
737 llink(x) = n;
738 adjust_balance_insert(x,n);
739 return iterator(n);
740 }
741 }
742 else if (cmp == 1 && cmp2 == -1) {
743 y = rlink(x);
744 if (y != 0) return subtree_insert_equal_(y, n);
745 else {
746 uplink(n) = x;
747 rlink(x) = n;
748 adjust_balance_insert(x,n);
749 return iterator(n);
750 }
751 }
752 x = y;
753 cmp = cmp2;
754 y = uplink(x);
755 }
756 return subtree_insert_equal_(x, n);
757}
758
759template <class K, class T, class C, class A>
760typename AVLMMap<K,T,C,A>::iterator
761AVLMMap<K,T,C,A>::insert_new(const iterator &hint, const std::pair<K,T> &ipair)
762{
763 AVLMMapNode<K,T>* n = alloc_.allocate(1);
764 new((void*)n)AVLMMapNode<K,T>(ipair);
765
766 llink(n) = 0;
767 rlink(n) = 0;
768 balance(n) = 0;
769
770 AVLMMapNode<K,T> *x = hint.node;
771 if (x == 0) return subtree_insert_new_(root_,n);
772 AVLMMapNode<K,T> *y = uplink(x);
773 while (y != 0) {
774 bool cmp = key_comp_(key(n), key(x));
775 bool cmp2 = key_comp_(key(n), key(y));
776 if (cmp && !cmp2) {
777 y = llink(x);
778 if (y != 0) return subtree_insert_new_(y, n);
779 else {
780 uplink(n) = x;
781 llink(x) = n;
782 adjust_balance_insert(x,n);
783 return iterator(n);
784 }
785 }
786 else if (!cmp && cmp2) {
787 y = rlink(x);
788 if (y != 0) return subtree_insert_new_(y, n);
789 else {
790 uplink(n) = x;
791 rlink(x) = n;
792 adjust_balance_insert(x,n);
793 return iterator(n);
794 }
795 }
796 x = y;
797 cmp = cmp2;
798 y = uplink(x);
799 }
800 return subtree_insert_new_(x, n);
801}
802
803template <class K, class T, class C, class A>
804inline typename AVLMMap<K,T,C,A>::iterator
805AVLMMap<K,T,C,A>::insert_equal(const std::pair<K,T> &ipair)
806{
807 AVLMMapNode<K,T>* n = alloc_.allocate(1);
808 new((void*)n)AVLMMapNode<K,T>(ipair);
809
810 return subtree_insert_equal_(root_, n);
811}
812
813template <class K, class T, class C, class A>
814inline typename AVLMMap<K,T,C,A>::iterator
815AVLMMap<K,T,C,A>::insert_unique(const std::pair<K,T> &ipair)
816{
817 return subtree_insert_unique_(root_, ipair);
818}
819
820template <class K, class T, class C, class A>
821inline typename AVLMMap<K,T,C,A>::iterator
822AVLMMap<K,T,C,A>::insert_new(const std::pair<K,T> &ipair)
823{
824 AVLMMapNode<K,T>* n = alloc_.allocate(1);
825 new((void*)n)AVLMMapNode<K,T>(ipair);
826
827 length_++;
828
829 rlink(n) = 0;
830 llink(n) = 0;
831 balance(n) = 0;
832
833 return subtree_insert_new_(root_, n);
834}
835
836template <class K, class T, class C, class A>
837typename AVLMMap<K,T,C,A>::iterator
838AVLMMap<K,T,C,A>::subtree_insert_equal_(AVLMMapNode<K,T> *root,
839 AVLMMapNode<K,T> *n)
840{
841 length_++;
842
843 rlink(n) = 0;
844 llink(n) = 0;
845 balance(n) = 0;
846
847 // root is only null if the actual root is null
848 if (!root) {
849 uplink(n) = 0;
850 root_ = n;
851 start_ = n;
852 return iterator(n);
853 }
854
855 // find an insertion point
856 AVLMMapNode<K,T>* p = root;
857 AVLMMapNode<K,T>* prev_p = 0;
858 int cmp;
859 while (p) {
860 if (p == n) {
861 abort();
862 }
863 prev_p = p;
864 cmp = compare(key(n),key(p));
865 if (cmp < 0) p = llink(p);
866 else {
867 p = rlink(p);
868 }
869 }
870
871 // insert the node
872 uplink(n) = prev_p;
873 if (prev_p) {
874 if (cmp < 0) {
875 llink(prev_p) = n;
876 if (prev_p == start_) start_ = n;
877 }
878 else rlink(prev_p) = n;
879 }
880
881 // adjust the balance factors
882 if (prev_p) {
883 adjust_balance_insert(prev_p, n);
884 }
885
886 return iterator(n);
887}
888
889template <class K, class T, class C, class A>
890typename AVLMMap<K,T,C,A>::iterator
891AVLMMap<K,T,C,A>::subtree_insert_unique_(AVLMMapNode<K,T> *root,
892 const std::pair<K,T> &ipair)
893{
894 // root is only null if the actual root is null
895 if (!root) {
896 AVLMMapNode<K,T>* n = alloc_.allocate(1);
897 new((void*)n)AVLMMapNode<K,T>(ipair);
898
899 length_++;
900
901 rlink(n) = 0;
902 llink(n) = 0;
903 balance(n) = 0;
904 uplink(n) = 0;
905 root_ = n;
906 start_ = n;
907 return iterator(n);
908 }
909
910 // find an insertion point
911 AVLMMapNode<K,T>* p = root;
912 AVLMMapNode<K,T>* prev_p = 0;
913 int cmp;
914 while (p) {
915 prev_p = p;
916 cmp = compare(ipair.first,key(p));
917 if (cmp < 0) p = llink(p);
918 else if (cmp == 0) {
919 return iterator(p);
920 }
921 else {
922 p = rlink(p);
923 }
924 }
925
926 // no match was found; create the node
927 AVLMMapNode<K,T>* n = alloc_.allocate(1);
928 new((void*)n)AVLMMapNode<K,T>(ipair);
929
930 length_++;
931
932 rlink(n) = 0;
933 llink(n) = 0;
934 balance(n) = 0;
935
936 // insert the node
937 uplink(n) = prev_p;
938 if (prev_p) {
939 if (cmp < 0) {
940 llink(prev_p) = n;
941 if (prev_p == start_) start_ = n;
942 }
943 else rlink(prev_p) = n;
944 }
945
946 // adjust the balance factors
947 if (prev_p) {
948 adjust_balance_insert(prev_p, n);
949 }
950
951 return iterator(n);
952}
953
954template <class K, class T, class C, class A>
955typename AVLMMap<K,T,C,A>::iterator
956AVLMMap<K,T,C,A>::subtree_insert_new_(AVLMMapNode<K,T> *root,
957 AVLMMapNode<K,T> *n)
958{
959 // root is only null if the actual root is null
960 if (!root) {
961 uplink(n) = 0;
962 root_ = n;
963 start_ = n;
964 return iterator(n);
965 }
966
967 // find an insertion point
968 AVLMMapNode<K,T>* p = root;
969 AVLMMapNode<K,T>* prev_p = 0;
970 bool cmp;
971 while (p) {
972 prev_p = p;
973 cmp = key_comp_(key(n),key(p));
974 if (cmp) p = llink(p);
975 else {
976 p = rlink(p);
977 }
978 }
979
980 // insert the node
981 uplink(n) = prev_p;
982 if (prev_p) {
983 if (cmp) {
984 llink(prev_p) = n;
985 if (prev_p == start_) start_ = n;
986 }
987 else rlink(prev_p) = n;
988 }
989
990 // adjust the balance factors
991 if (prev_p) {
992 adjust_balance_insert(prev_p, n);
993 }
994
995 return iterator(n);
996}
997
998template <class K, class T, class C, class Alloc>
999void
1000AVLMMap<K,T,C,Alloc>::adjust_balance_insert(AVLMMapNode<K,T>* A, AVLMMapNode<K,T>* child)
1001{
1002 if (!A) return;
1003 int adjustment;
1004 if (llink(A) == child) adjustment = -1;
1005 else adjustment = 1;
1006 int bal = balance(A) + adjustment;
1007 if (bal == 0) {
1008 balance(A) = 0;
1009 }
1010 else if (bal == -1 || bal == 1) {
1011 balance(A) = bal;
1012 adjust_balance_insert(uplink(A), A);
1013 }
1014 else if (bal == 2) {
1015 AVLMMapNode<K,T>* B = rlink(A);
1016 if (balance(B) == 1) {
1017 balance(B) = 0;
1018 balance(A) = 0;
1019 rlink(A) = llink(B);
1020 llink(B) = A;
1021 uplink(B) = uplink(A);
1022 uplink(A) = B;
1023 if (rlink(A)) uplink(rlink(A)) = A;
1024 if (llink(B)) uplink(llink(B)) = B;
1025 if (uplink(B) == 0) root_ = B;
1026 else {
1027 if (rlink(uplink(B)) == A) rlink(uplink(B)) = B;
1028 else llink(uplink(B)) = B;
1029 }
1030 }
1031 else {
1032 AVLMMapNode<K,T>* X = llink(B);
1033 rlink(A) = llink(X);
1034 llink(B) = rlink(X);
1035 llink(X) = A;
1036 rlink(X) = B;
1037 if (balance(X) == 1) {
1038 balance(A) = -1;
1039 balance(B) = 0;
1040 }
1041 else if (balance(X) == -1) {
1042 balance(A) = 0;
1043 balance(B) = 1;
1044 }
1045 else {
1046 balance(A) = 0;
1047 balance(B) = 0;
1048 }
1049 balance(X) = 0;
1050 uplink(X) = uplink(A);
1051 uplink(A) = X;
1052 uplink(B) = X;
1053 if (rlink(A)) uplink(rlink(A)) = A;
1054 if (llink(B)) uplink(llink(B)) = B;
1055 if (uplink(X) == 0) root_ = X;
1056 else {
1057 if (rlink(uplink(X)) == A) rlink(uplink(X)) = X;
1058 else llink(uplink(X)) = X;
1059 }
1060 }
1061 }
1062 else if (bal == -2) {
1063 AVLMMapNode<K,T>* B = llink(A);
1064 if (balance(B) == -1) {
1065 balance(B) = 0;
1066 balance(A) = 0;
1067 llink(A) = rlink(B);
1068 rlink(B) = A;
1069 uplink(B) = uplink(A);
1070 uplink(A) = B;
1071 if (llink(A)) uplink(llink(A)) = A;
1072 if (rlink(B)) uplink(rlink(B)) = B;
1073 if (uplink(B) == 0) root_ = B;
1074 else {
1075 if (llink(uplink(B)) == A) llink(uplink(B)) = B;
1076 else rlink(uplink(B)) = B;
1077 }
1078 }
1079 else {
1080 AVLMMapNode<K,T>* X = rlink(B);
1081 llink(A) = rlink(X);
1082 rlink(B) = llink(X);
1083 rlink(X) = A;
1084 llink(X) = B;
1085 if (balance(X) == -1) {
1086 balance(A) = 1;
1087 balance(B) = 0;
1088 }
1089 else if (balance(X) == 1) {
1090 balance(A) = 0;
1091 balance(B) = -1;
1092 }
1093 else {
1094 balance(A) = 0;
1095 balance(B) = 0;
1096 }
1097 balance(X) = 0;
1098 uplink(X) = uplink(A);
1099 uplink(A) = X;
1100 uplink(B) = X;
1101 if (llink(A)) uplink(llink(A)) = A;
1102 if (rlink(B)) uplink(rlink(B)) = B;
1103 if (uplink(X) == 0) root_ = X;
1104 else {
1105 if (llink(uplink(X)) == A) llink(uplink(X)) = X;
1106 else rlink(uplink(X)) = X;
1107 }
1108 }
1109 }
1110}
1111
1112template <class K, class T, class C, class Alloc>
1113void
1114AVLMMap<K,T,C,Alloc>::adjust_balance_remove(AVLMMapNode<K,T>* A, AVLMMapNode<K,T>* child)
1115{
1116 if (!A) return;
1117 int adjustment;
1118 if (llink(A) == child) adjustment = 1;
1119 else adjustment = -1;
1120 int bal = balance(A) + adjustment;
1121 if (bal == 0) {
1122 balance(A) = 0;
1123 adjust_balance_remove(uplink(A), A);
1124 }
1125 else if (bal == -1 || bal == 1) {
1126 balance(A) = bal;
1127 }
1128 else if (bal == 2) {
1129 AVLMMapNode<K,T>* B = rlink(A);
1130 if (balance(B) == 0) {
1131 balance(B) = -1;
1132 balance(A) = 1;
1133 rlink(A) = llink(B);
1134 llink(B) = A;
1135 uplink(B) = uplink(A);
1136 uplink(A) = B;
1137 if (rlink(A)) uplink(rlink(A)) = A;
1138 if (llink(B)) uplink(llink(B)) = B;
1139 if (uplink(B) == 0) root_ = B;
1140 else {
1141 if (rlink(uplink(B)) == A) rlink(uplink(B)) = B;
1142 else llink(uplink(B)) = B;
1143 }
1144 }
1145 else if (balance(B) == 1) {
1146 balance(B) = 0;
1147 balance(A) = 0;
1148 rlink(A) = llink(B);
1149 llink(B) = A;
1150 uplink(B) = uplink(A);
1151 uplink(A) = B;
1152 if (rlink(A)) uplink(rlink(A)) = A;
1153 if (llink(B)) uplink(llink(B)) = B;
1154 if (uplink(B) == 0) root_ = B;
1155 else {
1156 if (rlink(uplink(B)) == A) rlink(uplink(B)) = B;
1157 else llink(uplink(B)) = B;
1158 }
1159 adjust_balance_remove(uplink(B), B);
1160 }
1161 else {
1162 AVLMMapNode<K,T>* X = llink(B);
1163 rlink(A) = llink(X);
1164 llink(B) = rlink(X);
1165 llink(X) = A;
1166 rlink(X) = B;
1167 if (balance(X) == 0) {
1168 balance(A) = 0;
1169 balance(B) = 0;
1170 }
1171 else if (balance(X) == 1) {
1172 balance(A) = -1;
1173 balance(B) = 0;
1174 }
1175 else {
1176 balance(A) = 0;
1177 balance(B) = 1;
1178 }
1179 balance(X) = 0;
1180 uplink(X) = uplink(A);
1181 uplink(A) = X;
1182 uplink(B) = X;
1183 if (rlink(A)) uplink(rlink(A)) = A;
1184 if (llink(B)) uplink(llink(B)) = B;
1185 if (uplink(X) == 0) root_ = X;
1186 else {
1187 if (rlink(uplink(X)) == A) rlink(uplink(X)) = X;
1188 else llink(uplink(X)) = X;
1189 }
1190 adjust_balance_remove(uplink(X), X);
1191 }
1192 }
1193 else if (bal == -2) {
1194 AVLMMapNode<K,T>* B = llink(A);
1195 if (balance(B) == 0) {
1196 balance(B) = 1;
1197 balance(A) = -1;
1198 llink(A) = rlink(B);
1199 rlink(B) = A;
1200 uplink(B) = uplink(A);
1201 uplink(A) = B;
1202 if (llink(A)) uplink(llink(A)) = A;
1203 if (rlink(B)) uplink(rlink(B)) = B;
1204 if (uplink(B) == 0) root_ = B;
1205 else {
1206 if (llink(uplink(B)) == A) llink(uplink(B)) = B;
1207 else rlink(uplink(B)) = B;
1208 }
1209 }
1210 else if (balance(B) == -1) {
1211 balance(B) = 0;
1212 balance(A) = 0;
1213 llink(A) = rlink(B);
1214 rlink(B) = A;
1215 uplink(B) = uplink(A);
1216 uplink(A) = B;
1217 if (llink(A)) uplink(llink(A)) = A;
1218 if (rlink(B)) uplink(rlink(B)) = B;
1219 if (uplink(B) == 0) root_ = B;
1220 else {
1221 if (llink(uplink(B)) == A) llink(uplink(B)) = B;
1222 else rlink(uplink(B)) = B;
1223 }
1224 adjust_balance_remove(uplink(B), B);
1225 }
1226 else {
1227 AVLMMapNode<K,T>* X = rlink(B);
1228 llink(A) = rlink(X);
1229 rlink(B) = llink(X);
1230 rlink(X) = A;
1231 llink(X) = B;
1232 if (balance(X) == 0) {
1233 balance(A) = 0;
1234 balance(B) = 0;
1235 }
1236 else if (balance(X) == -1) {
1237 balance(A) = 1;
1238 balance(B) = 0;
1239 }
1240 else {
1241 balance(A) = 0;
1242 balance(B) = -1;
1243 }
1244 balance(X) = 0;
1245 uplink(X) = uplink(A);
1246 uplink(A) = X;
1247 uplink(B) = X;
1248 if (llink(A)) uplink(llink(A)) = A;
1249 if (rlink(B)) uplink(rlink(B)) = B;
1250 if (uplink(X) == 0) root_ = X;
1251 else {
1252 if (llink(uplink(X)) == A) llink(uplink(X)) = X;
1253 else rlink(uplink(X)) = X;
1254 }
1255 adjust_balance_remove(uplink(X), X);
1256 }
1257 }
1258}
1259
1260template <class K, class T, class C, class A>
1261inline
1262AVLMMap<K,T,C,A>::AVLMMap()
1263{
1264 initialize();
1265}
1266
1267template <class K, class T, class C, class A>
1268inline
1269AVLMMap<K,T,C,A>::AVLMMap(const C &c):
1270 key_comp_(c)
1271{
1272 initialize();
1273}
1274
1275template <class K, class T, class C, class A>
1276inline
1277AVLMMap<K,T,C,A>::AVLMMap(const AVLMMap<K,T,C,A>&m)
1278{
1279 initialize();
1280 insert(m.begin(), m.end());
1281}
1282
1283template <class K, class T, class C, class A>
1284inline void
1285AVLMMap<K,T,C,A>::initialize()
1286{
1287 root_ = 0;
1288 start_ = 0;
1289 length_ = 0;
1290}
1291
1292}
1293
1294#endif
1295
1296// ///////////////////////////////////////////////////////////////////////////
1297
1298// Local Variables:
1299// mode: c++
1300// c-file-style: "CLJ"
1301// End:
Definition avlmmap.h:42
Definition avlmmap.h:206
Definition avlmmap.h:187
Definition avlmmap.h:155
Definition avlmmap.h:59
Definition avlmmap.h:140
Contains all MPQC code up to version 3.
Definition mpqcin.h:14

Generated at Wed Sep 25 2024 02:45:29 for MPQC 3.0.0-alpha using the documentation package Doxygen 1.12.0.