123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- /* Copyright (C) 2009-2015 Free Software Foundation, Inc.
- Contributed by Richard Henderson <rth@redhat.com>.
- This file is part of the GNU Transactional Memory Library (libitm).
- Libitm 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
- (at your option) any later version.
- Libitm 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.
- Under Section 7 of GPL version 3, you are granted additional
- permissions described in the GCC Runtime Library Exception, version
- 3.1, as published by the Free Software Foundation.
- You should have received a copy of the GNU General Public License and
- a copy of the GCC Runtime Library Exception along with this program;
- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
- <http://www.gnu.org/licenses/>. */
- /* Implements an AA tree (http://en.wikipedia.org/wiki/AA_tree) with an
- integer key, and data attached to the node via flexible array member. */
- #ifndef LIBITM_AATREE_H
- #define LIBITM_AATREE_H 1
- namespace GTM HIDDEN {
- template<typename KEY> class aa_tree_key;
- class aa_node_base
- {
- public:
- static const bool L = false;
- static const bool R = true;
- private:
- typedef unsigned int level_type;
- aa_node_base *m_link[2];
- level_type m_level;
- static const aa_node_base s_nil;
- public:
- aa_node_base(level_type l = 1)
- : m_link { const_cast<aa_node_base *>(&s_nil),
- const_cast<aa_node_base *>(&s_nil) },
- m_level(l)
- { }
- bool is_nil() const { return this == &s_nil; }
- aa_node_base * link(bool d) { return m_link[d]; }
- void set_link(bool d, aa_node_base *val) { m_link[d] = val; }
- aa_node_base *skew();
- aa_node_base *split();
- void decrease_level();
- static void *operator new (size_t s) { return xmalloc (s); }
- static void operator delete (void *p) { free (p); }
- };
- template<typename KEY>
- struct aa_node_key : public aa_node_base
- {
- typedef aa_node_base base;
- KEY key;
- explicit aa_node_key(KEY k) : key(k) { }
- aa_node_key * link(bool d)
- {
- return static_cast<aa_node_key *>(base::link(d));
- }
- aa_node_key *skew() { return static_cast<aa_node_key *>(base::skew()); }
- aa_node_key *split() { return static_cast<aa_node_key *>(base::split()); }
- };
- template<typename KEY, typename DATA>
- struct aa_node : public aa_node_key<KEY>
- {
- typedef aa_node_key<KEY> base;
- DATA data;
- explicit aa_node(KEY k) : base(k) { }
- aa_node * link(bool d)
- {
- return static_cast<aa_node *>(base::link(d));
- }
- };
- template<typename KEY>
- class aa_tree_key
- {
- public:
- typedef aa_node_key<KEY> node;
- typedef node *node_ptr;
- protected:
- node_ptr m_tree;
- protected:
- aa_tree_key() : m_tree(0) { }
- node_ptr find(KEY k) const;
- static node_ptr insert_1 (node_ptr t, node_ptr n);
- void insert(node_ptr n);
- static node_ptr erase_1 (node_ptr t, KEY k, node_ptr *pfree);
- node_ptr erase(KEY k);
- };
- extern template class aa_tree_key<uintptr_t>;
- template<typename KEY, typename DATA>
- class aa_tree : public aa_tree_key<KEY>
- {
- public:
- typedef aa_tree_key<KEY> base;
- typedef aa_node<KEY, DATA> node;
- typedef node *node_ptr;
- typedef void (*trav_callback)(KEY, DATA *, void *);
- private:
- static void clear_1 (node_ptr);
- static void traverse_1 (node_ptr, trav_callback, void *);
- public:
- aa_tree() = default;
- ~aa_tree() { clear(); }
- static void *operator new (size_t s, aa_tree<KEY, DATA>* p) { return p; }
- DATA *find(KEY k) const
- {
- node_ptr n = static_cast<node_ptr>(base::find (k));
- return n ? &n->data : 0;
- }
- DATA *insert(KEY k)
- {
- node_ptr n = new node(k);
- base::insert(n);
- return &n->data;
- }
- void erase(KEY k)
- {
- node_ptr n = static_cast<node_ptr>(base::erase (k));
- delete n;
- }
- node_ptr remove(KEY k, DATA** data)
- {
- node_ptr n = static_cast<node_ptr>(base::erase (k));
- *data = (n ? &n->data : 0);
- return n;
- }
- void clear()
- {
- node_ptr n = static_cast<node_ptr>(this->m_tree);
- if (n)
- {
- this->m_tree = 0;
- clear_1 (n);
- }
- }
- void traverse (trav_callback cb, void *cb_data)
- {
- node_ptr t = static_cast<node_ptr>(this->m_tree);
- if (t != 0)
- traverse_1 (t, cb, cb_data);
- }
- };
- template<typename KEY, typename DATA>
- void
- aa_tree<KEY, DATA>::clear_1 (node_ptr t)
- {
- if (t->is_nil())
- return;
- clear_1 (t->link(node::L));
- clear_1 (t->link(node::R));
- delete t;
- }
- template<typename KEY, typename DATA>
- void
- aa_tree<KEY, DATA>::traverse_1 (node_ptr t, trav_callback cb, void *cb_data)
- {
- if (t->is_nil())
- return;
- cb (t->key, &t->data, cb_data);
- traverse_1 (t->link(node::L), cb, cb_data);
- traverse_1 (t->link(node::R), cb, cb_data);
- }
- } // namespace GTM
- #endif // LIBITM_AATREE_H
|