Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
FORMUS3IC_LAS3
/
embb
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
871b5391
authored
May 12, 2015
by
Danila Klimenko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chromatic_tree: Fine-grained locking implementation without rebalancing
parent
8ded09ad
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
1251 additions
and
1227 deletions
+1251
-1227
base_cpp/include/embb/base/mutex.h
+0
-66
containers_cpp/include/embb/containers/internal/lock_free_chromatic_tree-inl.h
+299
-1053
containers_cpp/include/embb/containers/internal/lock_free_chromatic_tree-rebalance.h
+867
-0
containers_cpp/include/embb/containers/lock_free_chromatic_tree.h
+80
-103
containers_cpp/test/tree_test-inl.h
+5
-5
No files found.
base_cpp/include/embb/base/mutex.h
View file @
871b5391
...
...
@@ -29,7 +29,6 @@
#include <embb/base/internal/platform.h>
#include <embb/base/exceptions.h>
#include <embb/base/c/counter.h>
namespace
embb
{
namespace
base
{
...
...
@@ -484,71 +483,6 @@ class UniqueLock {
friend
class
embb
::
base
::
ConditionVariable
;
};
class
ReadWriteLock
{
public
:
ReadWriteLock
()
:
read_lock_
(),
write_lock_
(),
reader_
(
self
()),
writer_
(
self
())
{
embb_counter_init
(
&
active_readers_
);
}
void
ReadLock
()
{
LockGuard
<
Mutex
>
read_guard
(
read_lock_
);
unsigned
int
me
=
embb_counter_increment
(
&
active_readers_
);
if
(
me
==
0
)
{
write_lock_
.
Lock
();
}
}
void
ReadUnlock
()
{
unsigned
int
me
=
embb_counter_decrement
(
&
active_readers_
);
if
(
me
==
1
)
{
write_lock_
.
Unlock
();
}
}
void
WriteLock
()
{
read_lock_
.
Lock
();
write_lock_
.
Lock
();
}
void
WriteUnlock
()
{
write_lock_
.
Unlock
();
read_lock_
.
Unlock
();
}
~
ReadWriteLock
()
{
embb_counter_destroy
(
&
active_readers_
);
}
class
Reader
{
public
:
explicit
Reader
(
ReadWriteLock
&
rwlock
)
:
readwrite_lock_
(
rwlock
)
{}
void
Lock
()
{
readwrite_lock_
.
ReadLock
();
}
void
Unlock
()
{
readwrite_lock_
.
ReadUnlock
();
}
private
:
ReadWriteLock
&
readwrite_lock_
;
};
class
Writer
{
public
:
explicit
Writer
(
ReadWriteLock
&
rwlock
)
:
readwrite_lock_
(
rwlock
)
{}
void
Lock
()
{
readwrite_lock_
.
WriteLock
();
}
void
Unlock
()
{
readwrite_lock_
.
WriteUnlock
();
}
private
:
ReadWriteLock
&
readwrite_lock_
;
};
Reader
&
GetReader
()
{
return
reader_
;
}
Writer
&
GetWriter
()
{
return
writer_
;
}
private
:
ReadWriteLock
(
const
ReadWriteLock
&
);
ReadWriteLock
&
operator
=
(
const
ReadWriteLock
&
);
ReadWriteLock
&
self
()
{
return
*
this
;
}
Mutex
read_lock_
;
Mutex
write_lock_
;
embb_counter_t
active_readers_
;
Reader
reader_
;
Writer
writer_
;
};
}
// namespace base
}
// namespace embb
...
...
containers_cpp/include/embb/containers/internal/lock_free_chromatic_tree-inl.h
View file @
871b5391
...
...
@@ -30,6 +30,14 @@
#include <assert.h>
#include <algorithm>
#ifdef EMBB_DEBUG
static
const
size_t
INVALID_POINTER
=
static_cast
<
size_t
>
(
-
1
);
# define VERIFY_ADDRESS(addr) assert(reinterpret_cast<size_t>((addr)) != \
INVALID_POINTER)
#else
# define VERIFY_ADDRESS(address) ((void)0)
#endif
namespace
embb
{
namespace
containers
{
namespace
internal
{
...
...
@@ -37,13 +45,13 @@ namespace internal {
template
<
typename
Key
,
typename
Value
>
ChromaticTreeNode
<
Key
,
Value
>::
ChromaticTreeNode
(
const
Key
&
key
,
const
Value
&
value
,
const
int
weight
,
ChromaticTreeNode
<
Key
,
Value
>*
const
&
left
,
ChromaticTreeNode
<
Key
,
Value
>*
const
&
right
)
const
ChildPointer
&
left
,
const
ChildPointer
&
right
)
:
key_
(
key
),
value_
(
value
),
weight_
(
weight
),
left_
(
left
),
right_
(
right
)
{}
right_
(
right
),
retired_
(
false
)
{}
template
<
typename
Key
,
typename
Value
>
ChromaticTreeNode
<
Key
,
Value
>::
...
...
@@ -52,16 +60,8 @@ ChromaticTreeNode(const Key& key, const Value& value, const int weight)
value_
(
value
),
weight_
(
weight
),
left_
(
NULL
),
right_
(
NULL
)
{}
template
<
typename
Key
,
typename
Value
>
ChromaticTreeNode
<
Key
,
Value
>::
ChromaticTreeNode
(
const
ChromaticTreeNode
&
other
)
:
key_
(
other
.
key_
),
value_
(
other
.
value_
),
weight_
(
other
.
weight_
),
left_
(
other
.
left_
),
right_
(
other
.
right_
)
{}
right_
(
NULL
),
retired_
(
false
)
{}
template
<
typename
Key
,
typename
Value
>
const
Key
&
ChromaticTreeNode
<
Key
,
Value
>::
GetKey
()
const
{
...
...
@@ -79,12 +79,14 @@ int ChromaticTreeNode<Key, Value>::GetWeight() const {
}
template
<
typename
Key
,
typename
Value
>
ChromaticTreeNode
<
Key
,
Value
>*&
ChromaticTreeNode
<
Key
,
Value
>::
GetLeft
()
{
typename
ChromaticTreeNode
<
Key
,
Value
>::
AtomicChildPointer
&
ChromaticTreeNode
<
Key
,
Value
>::
GetLeft
()
{
return
left_
;
}
template
<
typename
Key
,
typename
Value
>
ChromaticTreeNode
<
Key
,
Value
>*&
ChromaticTreeNode
<
Key
,
Value
>::
GetRight
()
{
typename
ChromaticTreeNode
<
Key
,
Value
>::
AtomicChildPointer
&
ChromaticTreeNode
<
Key
,
Value
>::
GetRight
()
{
return
right_
;
}
...
...
@@ -95,11 +97,22 @@ template<typename Key, typename Value, typename Compare, typename NodePool>
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
ChromaticTree
(
size_t
capacity
,
Key
undefined_key
,
Value
undefined_value
,
Compare
compare
)
:
undefined_key_
(
undefined_key
),
#ifdef EMBB_PLATFORM_COMPILER_MSVC
#pragma warning(push)
#pragma warning(disable:4355)
#endif
:
free_node_callback_
(
*
this
,
&
ChromaticTree
::
FreeNode
),
#ifdef EMBB_PLATFORM_COMPILER_MSVC
#pragma warning(pop)
#endif
node_hazard_manager_
(
free_node_callback_
,
NULL
,
8
),
undefined_key_
(
undefined_key
),
undefined_value_
(
undefined_value
),
compare_
(
compare
),
capacity_
(
capacity
),
node_pool_
(
2
+
5
+
2
*
capacity_
)
{
node_pool_
(
2
+
5
+
2
*
capacity_
+
node_hazard_manager_
.
GetRetiredListMaxSize
()
*
embb
::
base
::
Thread
::
GetThreadsMaxCount
())
{
entry_
=
node_pool_
.
Allocate
(
undefined_key_
,
undefined_value_
);
NodePtr
sentinel
=
node_pool_
.
Allocate
(
undefined_key_
,
undefined_value_
);
entry_
->
GetLeft
()
=
sentinel
;
...
...
@@ -109,25 +122,26 @@ template<typename Key, typename Value, typename Compare, typename NodePool>
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
~
ChromaticTree
()
{
Destruct
(
entry_
->
GetLeft
());
node_pool_
.
Fre
e
(
entry_
);
FreeNod
e
(
entry_
);
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
bool
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
Get
(
const
Key
&
key
,
Value
&
value
)
{
ReaderLockGuard
guard
(
readwrite_lock_
.
GetReader
());
NodePtr
leaf
;
Search
(
key
,
leaf
);
bool
keys_are_equal
=
!
(
compare_
(
key
,
leaf
->
GetKey
())
||
bool
keys_are_equal
=
!
IsSentinel
(
leaf
)
&&
!
(
compare_
(
key
,
leaf
->
GetKey
())
||
compare_
(
leaf
->
GetKey
(),
key
));
if
(
!
IsSentinel
(
leaf
)
&&
keys_are_equal
)
{
if
(
keys_are_equal
)
{
value
=
leaf
->
GetValue
();
return
true
;
}
else
{
return
false
;
}
node_hazard_manager_
.
GuardPointer
(
0
,
NULL
);
return
keys_are_equal
;
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
...
...
@@ -140,65 +154,75 @@ TryInsert(const Key& key, const Value& value) {
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
bool
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
TryInsert
(
const
Key
&
key
,
const
Value
&
value
,
Value
&
old_value
)
{
WriterLockGuard
guard
(
readwrite_lock_
.
GetWriter
());
NodePtr
leaf
,
parent
;
Search
(
key
,
leaf
,
parent
);
assert
(
HasChild
(
parent
,
leaf
));
NodePtr
new_leaf
=
NULL
;
NodePtr
new_sibling
=
NULL
;
NodePtr
new_parent
=
NULL
;
bool
insertion_succeeded
=
false
;
while
(
!
insertion_succeeded
)
{
NodePtr
leaf
,
parent
;
Search
(
key
,
leaf
,
parent
);
// Try to lock the parent
UniqueLock
parent_lock
(
parent
->
GetMutex
(),
embb
::
base
::
try_lock
);
if
(
!
parent_lock
.
OwnsLock
()
||
parent
->
IsRetired
())
continue
;
// Verify that the leaf is still the parent's child
if
(
!
HasChild
(
parent
,
leaf
))
continue
;
// Try to lock the leaf
UniqueLock
leaf_lock
(
leaf
->
GetMutex
(),
embb
::
base
::
try_lock
);
if
(
!
leaf_lock
.
OwnsLock
()
||
leaf
->
IsRetired
())
continue
;
// Reached leaf has a matching key: replace it with a new copy
if
(
!
IsSentinel
(
leaf
)
&&
!
(
compare_
(
key
,
leaf
->
GetKey
())
||
compare_
(
leaf
->
GetKey
(),
key
)))
{
old_value
=
leaf
->
GetValue
();
new_parent
=
node_pool_
.
Allocate
(
key
,
value
,
leaf
->
GetWeight
());
if
(
new_parent
==
NULL
)
break
;
// Reached leaf has a different key: add a new leaf
}
else
{
old_value
=
undefined_value_
;
NodePtr
new_parent
;
bool
added_violation
=
false
;
new_leaf
=
node_pool_
.
Allocate
(
key
,
value
);
if
(
new_leaf
==
NULL
)
break
;
new_sibling
=
node_pool_
.
Allocate
(
leaf
->
GetKey
(),
leaf
->
GetValue
());
if
(
new_sibling
==
NULL
)
break
;
bool
keys_are_equal
=
!
(
compare_
(
key
,
leaf
->
GetKey
())
||
compare_
(
leaf
->
GetKey
(),
key
));
if
(
!
IsSentinel
(
leaf
)
&&
keys_are_equal
)
{
old_value
=
leaf
->
GetValue
();
new_parent
=
node_pool_
.
Allocate
(
key
,
value
,
leaf
->
GetWeight
());
if
(
new_parent
==
NULL
)
{
return
false
;
int
new_weight
=
(
HasFixedWeight
(
leaf
))
?
1
:
(
leaf
->
GetWeight
()
-
1
);
if
(
IsSentinel
(
leaf
)
||
compare_
(
key
,
leaf
->
GetKey
()))
{
new_parent
=
node_pool_
.
Allocate
(
leaf
->
GetKey
(),
undefined_value_
,
new_weight
,
new_leaf
,
new_sibling
);
}
else
{
new_parent
=
node_pool_
.
Allocate
(
key
,
undefined_value_
,
new_weight
,
new_sibling
,
new_leaf
);
}
if
(
new_parent
==
NULL
)
break
;
}
}
else
{
old_value
=
undefined_value_
;
NodePtr
new_leaf
=
node_pool_
.
Allocate
(
key
,
value
);
if
(
new_leaf
==
NULL
)
{
return
false
;
}
NodePtr
new_sibling
=
node_pool_
.
Allocate
(
*
leaf
);
if
(
new_sibling
==
NULL
)
{
node_pool_
.
Free
(
new_leaf
);
return
false
;
}
GetPointerToChild
(
parent
,
leaf
).
CompareAndSwap
(
leaf
,
new_parent
);
int
new_weight
=
(
HasFixedWeight
(
leaf
))
?
1
:
(
leaf
->
GetWeight
()
-
1
);
if
(
IsSentinel
(
leaf
)
||
compare_
(
key
,
leaf
->
GetKey
()))
{
new_parent
=
node_pool_
.
Allocate
(
leaf
->
GetKey
(),
undefined_value_
,
new_weight
,
new_leaf
,
new_sibling
);
}
else
{
new_parent
=
node_pool_
.
Allocate
(
key
,
undefined_value_
,
new_weight
,
new_sibling
,
new_leaf
);
}
insertion_succeeded
=
true
;
if
(
new_parent
==
NULL
)
{
node_pool_
.
Free
(
new_leaf
);
node_pool_
.
Free
(
new_sibling
);
return
false
;
}
leaf
->
Retire
();
leaf_lock
.
Unlock
();
node_hazard_manager_
.
GuardPointer
(
1
,
NULL
);
RemoveNode
(
leaf
);
added_violation
=
(
parent
->
GetWeight
()
==
0
&&
new_weight
==
0
);
// if (parent->GetWeight() == 0 && new_parent->GetWeight() == 0) {
// CleanUp(key);
// }
}
node_hazard_manager_
.
GuardPointer
(
0
,
NULL
);
node_hazard_manager_
.
GuardPointer
(
1
,
NULL
);
NodePtr
&
new_subtree_ptr
=
GetPointerToChild
(
parent
,
leaf
);
new_subtree_ptr
=
new_parent
;
node_pool_
.
Free
(
leaf
);
if
(
added_violation
)
{
CleanUp
(
key
);
if
(
!
insertion_succeeded
)
{
if
(
new_leaf
!=
NULL
)
FreeNode
(
new_leaf
);
if
(
new_sibling
!=
NULL
)
FreeNode
(
new_sibling
);
if
(
new_parent
!=
NULL
)
FreeNode
(
new_parent
);
}
return
true
;
return
insertion_succeeded
;
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
...
...
@@ -211,47 +235,89 @@ TryDelete(const Key& key) {
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
bool
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
TryDelete
(
const
Key
&
key
,
Value
&
old_value
)
{
WriterLockGuard
guard
(
readwrite_lock_
.
GetWriter
())
;
NodePtr
leaf
,
parent
,
grandparent
;
Search
(
key
,
leaf
,
parent
,
grandparent
);
bool
keys_are_equal
=
!
(
compare_
(
key
,
leaf
->
GetKey
())
||
compare_
(
leaf
->
GetKey
(),
key
));
if
(
IsSentinel
(
leaf
)
||
!
keys_are_equal
)
{
old_value
=
undefined_value_
;
return
false
;
}
assert
(
HasChild
(
grandparent
,
parent
))
;
assert
(
HasChild
(
parent
,
leaf
));
NodePtr
new_leaf
=
NULL
;
bool
deletion_succeeded
=
false
;
while
(
!
deletion_succeeded
)
{
NodePtr
leaf
,
parent
,
grandparent
;
Search
(
key
,
leaf
,
parent
,
grandparent
);
// Reached leaf has a different key - nothing to delete
if
(
IsSentinel
(
leaf
)
||
(
compare_
(
key
,
leaf
->
GetKey
())
||
compare_
(
leaf
->
GetKey
(),
key
)))
{
old_value
=
undefined_value_
;
deletion_succeeded
=
true
;
break
;
}
NodePtr
sibling
=
((
parent
->
GetLeft
()
==
leaf
)
?
parent
->
GetRight
()
:
parent
->
GetLeft
());
// Try to lock the grandparent
UniqueLock
grandparent_lock
(
grandparent
->
GetMutex
(),
embb
::
base
::
try_lock
);
if
(
!
grandparent_lock
.
OwnsLock
()
||
grandparent
->
IsRetired
())
continue
;
// Verify that the parent is still the grandparent's child
if
(
!
HasChild
(
grandparent
,
parent
))
continue
;
// Try to lock the parent
UniqueLock
parent_lock
(
parent
->
GetMutex
(),
embb
::
base
::
try_lock
);
if
(
!
parent_lock
.
OwnsLock
()
||
parent
->
IsRetired
())
continue
;
// Verify that the leaf is still the parent's child
if
(
!
HasChild
(
parent
,
leaf
))
continue
;
AtomicNodePtr
&
other_child
=
((
parent
->
GetLeft
()
==
leaf
)
?
parent
->
GetRight
()
:
parent
->
GetLeft
());
NodePtr
sibling
=
other_child
;
node_hazard_manager_
.
GuardPointer
(
3
,
sibling
);
if
(
sibling
!=
other_child
)
continue
;
VERIFY_ADDRESS
(
sibling
);
// Try to lock the sibling
UniqueLock
sibling_lock
(
sibling
->
GetMutex
(),
embb
::
base
::
try_lock
);
if
(
!
sibling_lock
.
OwnsLock
()
||
sibling
->
IsRetired
())
continue
;
// Try to lock the leaf
UniqueLock
leaf_lock
(
leaf
->
GetMutex
(),
embb
::
base
::
try_lock
);
if
(
!
leaf_lock
.
OwnsLock
()
||
leaf
->
IsRetired
())
continue
;
int
new_weight
=
(
HasFixedWeight
(
parent
))
?
1
:
(
parent
->
GetWeight
()
+
sibling
->
GetWeight
());
new_leaf
=
node_pool_
.
Allocate
(
sibling
->
GetKey
(),
sibling
->
GetValue
(),
new_weight
,
sibling
->
GetLeft
(),
sibling
->
GetRight
());
if
(
new_leaf
==
NULL
)
break
;
int
new_weight
=
(
HasFixedWeight
(
parent
))
?
1
:
(
parent
->
GetWeight
()
+
sibling
->
GetWeight
());
bool
added_violation
=
(
new_weight
>
1
);
old_value
=
leaf
->
GetValue
();
NodePtr
new_leaf
=
node_pool_
.
Allocate
(
sibling
->
GetKey
(),
sibling
->
GetValue
(),
new_weight
,
sibling
->
GetLeft
(),
sibling
->
GetRight
());
assert
((
new_leaf
!=
NULL
)
&&
"No nodes available for replacement!"
);
GetPointerToChild
(
grandparent
,
parent
).
CompareAndSwap
(
parent
,
new_leaf
);
NodePtr
&
new_subtree_ptr
=
GetPointerToChild
(
grandparent
,
parent
);
new_subtree_ptr
=
new_leaf
;
deletion_succeeded
=
true
;
old_value
=
leaf
->
GetValue
();
parent
->
Retire
();
parent_lock
.
Unlock
();
node_hazard_manager_
.
GuardPointer
(
1
,
NULL
);
RemoveNode
(
parent
);
leaf
->
Retire
();
leaf_lock
.
Unlock
();
node_hazard_manager_
.
GuardPointer
(
2
,
NULL
);
RemoveNode
(
leaf
);
sibling
->
Retire
();
sibling_lock
.
Unlock
();
node_hazard_manager_
.
GuardPointer
(
3
,
NULL
);
RemoveNode
(
sibling
);
node_pool_
.
Free
(
leaf
);
node_pool_
.
Free
(
sibling
);
node_pool_
.
Free
(
parent
);
// if (new_weight > 1) {
// CleanUp(key);
// }
}
node_hazard_manager_
.
GuardPointer
(
0
,
NULL
);
node_hazard_manager_
.
GuardPointer
(
1
,
NULL
);
node_hazard_manager_
.
GuardPointer
(
2
,
NULL
);
node_hazard_manager_
.
GuardPointer
(
3
,
NULL
);
if
(
added_violation
)
{
CleanUp
(
key
);
if
(
!
deletion_succeeded
)
{
if
(
new_leaf
!=
NULL
)
FreeNode
(
new_leaf
);
}
return
true
;
return
deletion_succeeded
;
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
...
...
@@ -274,31 +340,77 @@ IsEmpty() {
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
void
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
Search
(
const
Key
&
key
,
NodePtr
&
leaf
)
const
{
Search
(
const
Key
&
key
,
NodePtr
&
leaf
)
{
NodePtr
parent
;
Search
(
key
,
leaf
,
parent
);
node_hazard_manager_
.
GuardPointer
(
0
,
leaf
);
node_hazard_manager_
.
GuardPointer
(
1
,
NULL
);
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
void
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
Search
(
const
Key
&
key
,
NodePtr
&
leaf
,
NodePtr
&
parent
)
const
{
NodePtr
grandparent
;
Search
(
key
,
leaf
,
parent
,
grandparent
);
Search
(
const
Key
&
key
,
NodePtr
&
leaf
,
NodePtr
&
parent
)
{
bool
reached_leaf
=
false
;
while
(
!
reached_leaf
)
{
parent
=
entry_
;
node_hazard_manager_
.
GuardPointer
(
0
,
parent
);
leaf
=
entry_
->
GetLeft
();
node_hazard_manager_
.
GuardPointer
(
1
,
leaf
);
if
(
leaf
!=
entry_
->
GetLeft
())
continue
;
reached_leaf
=
IsLeaf
(
leaf
);
while
(
!
reached_leaf
)
{
parent
=
leaf
;
node_hazard_manager_
.
GuardPointer
(
0
,
parent
);
AtomicNodePtr
&
next_leaf
=
(
IsSentinel
(
leaf
)
||
compare_
(
key
,
leaf
->
GetKey
()))
?
leaf
->
GetLeft
()
:
leaf
->
GetRight
();
leaf
=
next_leaf
;
node_hazard_manager_
.
GuardPointer
(
1
,
leaf
);
if
(
leaf
!=
next_leaf
||
parent
->
IsRetired
())
break
;
VERIFY_ADDRESS
(
leaf
);
reached_leaf
=
IsLeaf
(
leaf
);
}
}
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
void
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
Search
(
const
Key
&
key
,
NodePtr
&
leaf
,
NodePtr
&
parent
,
NodePtr
&
grandparent
)
const
{
grandparent
=
NULL
;
parent
=
entry_
;
leaf
=
entry_
->
GetLeft
();
while
(
!
IsLeaf
(
leaf
))
{
grandparent
=
parent
;
parent
=
leaf
;
leaf
=
(
IsSentinel
(
leaf
)
||
compare_
(
key
,
leaf
->
GetKey
()))
?
leaf
->
GetLeft
()
:
leaf
->
GetRight
();
Search
(
const
Key
&
key
,
NodePtr
&
leaf
,
NodePtr
&
parent
,
NodePtr
&
grandparent
)
{
bool
reached_leaf
=
false
;
while
(
!
reached_leaf
)
{
grandparent
=
NULL
;
parent
=
entry_
;
node_hazard_manager_
.
GuardPointer
(
1
,
parent
);
leaf
=
entry_
->
GetLeft
();
node_hazard_manager_
.
GuardPointer
(
2
,
leaf
);
if
(
leaf
!=
entry_
->
GetLeft
())
continue
;
reached_leaf
=
IsLeaf
(
leaf
);
while
(
!
reached_leaf
)
{
grandparent
=
parent
;
node_hazard_manager_
.
GuardPointer
(
0
,
grandparent
);
parent
=
leaf
;
node_hazard_manager_
.
GuardPointer
(
1
,
parent
);
AtomicNodePtr
&
next_leaf
=
(
IsSentinel
(
leaf
)
||
compare_
(
key
,
leaf
->
GetKey
()))
?
leaf
->
GetLeft
()
:
leaf
->
GetRight
();
leaf
=
next_leaf
;
node_hazard_manager_
.
GuardPointer
(
2
,
leaf
);
if
(
leaf
!=
next_leaf
||
parent
->
IsRetired
())
break
;
VERIFY_ADDRESS
(
leaf
);
reached_leaf
=
IsLeaf
(
leaf
);
}
}
}
...
...
@@ -327,7 +439,7 @@ HasChild(const NodePtr& parent, const NodePtr& child) const {
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
typename
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
NodePtr
&
typename
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
Atomic
NodePtr
&
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
GetPointerToChild
(
const
NodePtr
&
parent
,
const
NodePtr
&
child
)
const
{
assert
(
HasChild
(
parent
,
child
));
...
...
@@ -341,13 +453,63 @@ Destruct(const NodePtr& node) {
Destruct
(
node
->
GetLeft
());
Destruct
(
node
->
GetRight
());
}
FreeNode
(
node
);
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
int
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
GetHeight
(
const
NodePtr
&
node
)
const
{
int
height
=
0
;
if
(
node
!=
NULL
)
{
height
=
1
+
::
std
::
max
(
GetHeight
(
node
->
GetLeft
()),
GetHeight
(
node
->
GetRight
()));
}
return
height
;
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
bool
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
IsBalanced
()
const
{
return
IsBalanced
(
entry_
->
GetLeft
());
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
bool
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
IsBalanced
(
const
NodePtr
&
node
)
const
{
// Overweight violation
bool
has_violation
=
node
->
GetWeight
()
>
1
;
if
(
!
has_violation
&&
!
IsLeaf
(
node
))
{
NodePtr
left
=
node
->
GetLeft
();
NodePtr
right
=
node
->
GetRight
();
// Red-red violation
has_violation
=
node
->
GetWeight
()
==
0
&&
(
left
->
GetWeight
()
==
0
||
right
->
GetWeight
()
==
0
);
// Check children
if
(
!
has_violation
)
{
has_violation
=
!
IsBalanced
(
left
)
||
!
IsBalanced
(
right
);
}
}
return
!
has_violation
;
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
void
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
FreeNode
(
NodePtr
node
)
{
#ifdef EMBB_DEBUG
node
->
GetLeft
()
=
reinterpret_cast
<
NodePtr
>
(
INVALID_POINTER
);
node
->
GetRight
()
=
reinterpret_cast
<
NodePtr
>
(
INVALID_POINTER
);
#endif
node_pool_
.
Free
(
node
);
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
bool
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
CleanUp
(
const
Key
&
key
)
{
while
(
true
)
{
for
(;;
)
{
NodePtr
grandgrandparent
=
NULL
;
NodePtr
grandparent
=
NULL
;
NodePtr
parent
=
entry_
;
...
...
@@ -360,6 +522,7 @@ CleanUp(const Key& key) {
parent
=
leaf
;
leaf
=
(
IsSentinel
(
leaf
)
||
compare_
(
key
,
leaf
->
GetKey
()))
?
leaf
->
GetLeft
()
:
leaf
->
GetRight
();
VERIFY_ADDRESS
(
leaf
);
}
if
(
leaf
->
GetWeight
()
==
1
)
{
...
...
@@ -382,14 +545,14 @@ Rebalance(const NodePtr& u, const NodePtr& ux, const NodePtr& uxx,
if
(
!
HasChild
(
u
,
ux
))
return
false
;
//TODO: weakLLX(ux);
NodePtr
uxl
=
ux
->
GetLeft
();
NodePtr
uxr
=
ux
->
GetRight
();
NodePtr
uxl
=
ux
->
GetLeft
();
VERIFY_ADDRESS
(
uxl
);
NodePtr
uxr
=
ux
->
GetRight
();
VERIFY_ADDRESS
(
uxr
);
bool
uxx_is_left
=
(
uxx
==
uxl
);
if
(
!
HasChild
(
ux
,
uxx
))
return
false
;
//TODO: weakLLX(uxx);
NodePtr
uxxl
=
uxx
->
GetLeft
();
NodePtr
uxxr
=
uxx
->
GetRight
();
NodePtr
uxxl
=
uxx
->
GetLeft
();
VERIFY_ADDRESS
(
uxxl
);
NodePtr
uxxr
=
uxx
->
GetRight
();
VERIFY_ADDRESS
(
uxxr
);
bool
uxxx_is_left
=
(
uxxx
==
uxxl
);
if
(
!
HasChild
(
uxx
,
uxxx
))
return
false
;
...
...
@@ -471,7 +634,7 @@ OverweightLeft(const NodePtr& u, const NodePtr& ux, const NodePtr& uxx,
assert
(
uxx
->
GetWeight
()
>
0
);
//TODO: weakLLX(uxxr);
// Note: we know that 'uxxr' is not a leaf because it has weight 0.
NodePtr
uxxrl
=
uxxr
->
GetLeft
();
NodePtr
uxxrl
=
uxxr
->
GetLeft
();
VERIFY_ADDRESS
(
uxxrl
);
//TODO: weakLLX(uxxrl);
// Root -> Middle -> Right -> Left
...
...
@@ -480,8 +643,8 @@ OverweightLeft(const NodePtr& u, const NodePtr& ux, const NodePtr& uxx,
// Root -> Middle -> Right -> Middle
}
else
if
(
uxxrl
->
GetWeight
()
==
1
)
{
NodePtr
uxxrll
=
uxxrl
->
GetLeft
();
NodePtr
uxxrlr
=
uxxrl
->
GetRight
();
NodePtr
uxxrll
=
uxxrl
->
GetLeft
();
VERIFY_ADDRESS
(
uxxrll
);
NodePtr
uxxrlr
=
uxxrl
->
GetRight
();
VERIFY_ADDRESS
(
uxxrlr
);
if
(
uxxrlr
==
NULL
)
return
false
;
// Root -> Middle -> Right -> Middle -> Left
...
...
@@ -514,8 +677,8 @@ OverweightLeft(const NodePtr& u, const NodePtr& ux, const NodePtr& uxx,
// Root -> Right
}
else
if
(
uxxr
->
GetWeight
()
==
1
)
{
//TODO: weakLLX(uxxr);
NodePtr
uxxrl
=
uxxr
->
GetLeft
();
NodePtr
uxxrr
=
uxxr
->
GetRight
();
NodePtr
uxxrl
=
uxxr
->
GetLeft
();
VERIFY_ADDRESS
(
uxxrl
);
NodePtr
uxxrr
=
uxxr
->
GetRight
();
VERIFY_ADDRESS
(
uxxrr
);
if
(
uxxrl
==
NULL
)
return
false
;
// Root -> Right -> Left
...
...
@@ -544,8 +707,6 @@ OverweightLeft(const NodePtr& u, const NodePtr& ux, const NodePtr& uxx,
//TODO: weakLLX(uxxr);
return
W7
(
ux
,
uxx
,
uxxl
,
uxxr
);
}
return
true
;
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
...
...
@@ -593,7 +754,7 @@ OverweightRight(const NodePtr& u, const NodePtr& ux, const NodePtr& uxx,
assert
(
uxx
->
GetWeight
()
>
0
);
//TODO: weakLLX(uxxl);
// Note: we know that 'uxxl' is not a leaf because it has weight 0.
NodePtr
uxxlr
=
uxxl
->
GetRight
();
NodePtr
uxxlr
=
uxxl
->
GetRight
();
VERIFY_ADDRESS
(
uxxlr
);
//TODO: weakLLX(uxxlr);
// Root -> Middle -> Right -> Left
...
...
@@ -602,8 +763,8 @@ OverweightRight(const NodePtr& u, const NodePtr& ux, const NodePtr& uxx,
// Root -> Middle -> Right -> Middle
}
else
if
(
uxxlr
->
GetWeight
()
==
1
)
{
NodePtr
uxxlrl
=
uxxlr
->
GetLeft
();
NodePtr
uxxlrr
=
uxxlr
->
GetRight
();
NodePtr
uxxlrl
=
uxxlr
->
GetLeft
();
VERIFY_ADDRESS
(
uxxlrl
);
NodePtr
uxxlrr
=
uxxlr
->
GetRight
();
VERIFY_ADDRESS
(
uxxlrr
);
if
(
uxxlrl
==
NULL
)
return
false
;
// Root -> Middle -> Right -> Middle -> Left
...
...
@@ -636,8 +797,8 @@ OverweightRight(const NodePtr& u, const NodePtr& ux, const NodePtr& uxx,
// Root -> Right
}
else
if
(
uxxl
->
GetWeight
()
==
1
)
{
//TODO: weakLLX(uxxl);
NodePtr
uxxll
=
uxxl
->
GetLeft
();
NodePtr
uxxlr
=
uxxl
->
GetRight
();
NodePtr
uxxll
=
uxxl
->
GetLeft
();
VERIFY_ADDRESS
(
uxxll
);
NodePtr
uxxlr
=
uxxl
->
GetRight
();
VERIFY_ADDRESS
(
uxxlr
);
if
(
uxxll
==
NULL
)
return
false
;
// Root -> Right -> Left
...
...
@@ -666,923 +827,8 @@ OverweightRight(const NodePtr& u, const NodePtr& ux, const NodePtr& uxx,
//TODO: weakLLX(uxxl);
return
W7
(
ux
,
uxx
,
uxxl
,
uxxr
);
}
return
true
;
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
int
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
GetHeight
(
const
NodePtr
&
node
)
const
{
int
height
=
0
;
if
(
node
!=
NULL
)
{
height
=
1
+
::
std
::
max
(
GetHeight
(
node
->
GetLeft
()),
GetHeight
(
node
->
GetRight
()));
}
return
height
;
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
bool
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
IsBalanced
()
const
{
return
IsBalanced
(
entry_
->
GetLeft
());
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
bool
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
IsBalanced
(
const
NodePtr
&
node
)
const
{
// Overweight violation
bool
has_violation
=
node
->
GetWeight
()
>
1
;
if
(
!
has_violation
&&
!
IsLeaf
(
node
))
{
NodePtr
left
=
node
->
GetLeft
();
NodePtr
right
=
node
->
GetRight
();
// Red-red violation
has_violation
=
node
->
GetWeight
()
==
0
&&
(
left
->
GetWeight
()
==
0
||
right
->
GetWeight
()
==
0
);
// Check children
if
(
!
has_violation
)
{
has_violation
=
!
IsBalanced
(
left
)
||
!
IsBalanced
(
right
);
}
}
return
!
has_violation
;
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
bool
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
BLK
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
)
{
NodePtr
nxl
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
1
,
uxl
->
GetLeft
(),
uxl
->
GetRight
());
NodePtr
nxr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
1
,
uxr
->
GetLeft
(),
uxr
->
GetRight
());
NodePtr
nx
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
HasFixedWeight
(
ux
)
?
1
:
ux
->
GetWeight
()
-
1
,
nxl
,
nxr
);
if
(
nxl
==
NULL
||
nxr
==
NULL
||
nx
==
NULL
)
{
if
(
nxl
)
node_pool_
.
Free
(
nxl
);
if
(
nxr
)
node_pool_
.
Free
(
nxr
);
if
(
nx
)
node_pool_
.
Free
(
nx
);
return
false
;
}
NodePtr
&
new_subtree_ptr
=
GetPointerToChild
(
u
,
ux
);
new_subtree_ptr
=
nx
;
node_pool_
.
Free
(
ux
);
node_pool_
.
Free
(
uxl
);
node_pool_
.
Free
(
uxr
);
return
true
;
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
bool
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
PUSH_L
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
)
{
NodePtr
nxl
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
uxl
->
GetWeight
()
-
1
,
uxl
->
GetLeft
(),
uxl
->
GetRight
());
NodePtr
nxr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
0
,
uxr
->
GetLeft
(),
uxr
->
GetRight
());
NodePtr
nx
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
HasFixedWeight
(
ux
)
?
1
:
ux
->
GetWeight
()
+
1
,
nxl
,
nxr
);
if
(
nxl
==
NULL
||
nxr
==
NULL
||
nx
==
NULL
)
{
if
(
nxl
)
node_pool_
.
Free
(
nxl
);
if
(
nxr
)
node_pool_
.
Free
(
nxr
);
if
(
nx
)
node_pool_
.
Free
(
nx
);
return
false
;
}
NodePtr
&
new_subtree_ptr
=
GetPointerToChild
(
u
,
ux
);
new_subtree_ptr
=
nx
;
node_pool_
.
Free
(
ux
);
node_pool_
.
Free
(
uxl
);
node_pool_
.
Free
(
uxr
);
return
true
;
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
bool
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
PUSH_R
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
)
{
NodePtr
nxr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
uxr
->
GetWeight
()
-
1
,
uxr
->
GetLeft
(),
uxr
->
GetRight
());
NodePtr
nxl
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
0
,
uxl
->
GetLeft
(),
uxl
->
GetRight
());
NodePtr
nx
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
HasFixedWeight
(
ux
)
?
1
:
ux
->
GetWeight
()
+
1
,
nxl
,
nxr
);
if
(
nxr
==
NULL
||
nxl
==
NULL
||
nx
==
NULL
)
{
if
(
nxr
)
node_pool_
.
Free
(
nxr
);
if
(
nxl
)
node_pool_
.
Free
(
nxl
);
if
(
nx
)
node_pool_
.
Free
(
nx
);
return
false
;
}
NodePtr
&
new_subtree_ptr
=
GetPointerToChild
(
u
,
ux
);
new_subtree_ptr
=
nx
;
node_pool_
.
Free
(
ux
);
node_pool_
.
Free
(
uxl
);
node_pool_
.
Free
(
uxr
);
return
true
;
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
bool
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
RB1_L
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
)
{
NodePtr
nxr
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
0
,
uxl
->
GetRight
(),
ux
->
GetRight
());
NodePtr
nx
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
ux
->
GetWeight
(),
uxl
->
GetLeft
(),
nxr
);
if
(
nxr
==
NULL
||
nx
==
NULL
)
{
if
(
nxr
)
node_pool_
.
Free
(
nxr
);
if
(
nx
)
node_pool_
.
Free
(
nx
);
return
false
;
}
NodePtr
&
new_subtree_ptr
=
GetPointerToChild
(
u
,
ux
);
new_subtree_ptr
=
nx
;
node_pool_
.
Free
(
ux
);
node_pool_
.
Free
(
uxl
);
return
true
;
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
bool
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
RB1_R
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxr
)
{
NodePtr
nxl
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
0
,
ux
->
GetLeft
(),
uxr
->
GetLeft
());
NodePtr
nx
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
ux
->
GetWeight
(),
nxl
,
uxr
->
GetRight
());
if
(
nxl
==
NULL
||
nx
==
NULL
)
{
if
(
nxl
)
node_pool_
.
Free
(
nxl
);
if
(
nx
)
node_pool_
.
Free
(
nx
);
return
false
;
}
NodePtr
&
new_subtree_ptr
=
GetPointerToChild
(
u
,
ux
);
new_subtree_ptr
=
nx
;
node_pool_
.
Free
(
ux
);
node_pool_
.
Free
(
uxr
);
return
true
;
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
bool
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
RB2_L
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxlr
)
{
NodePtr
nxl
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
0
,
uxl
->
GetLeft
(),
uxlr
->
GetLeft
());
NodePtr
nxr
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
0
,
uxlr
->
GetRight
(),
ux
->
GetRight
());
NodePtr
nx
=
node_pool_
.
Allocate
(
uxlr
->
GetKey
(),
uxlr
->
GetValue
(),
ux
->
GetWeight
(),
nxl
,
nxr
);
if
(
nxl
==
NULL
||
nxr
==
NULL
||
nx
==
NULL
)
{
if
(
nxl
)
node_pool_
.
Free
(
nxl
);
if
(
nxr
)
node_pool_
.
Free
(
nxr
);
if
(
nx
)
node_pool_
.
Free
(
nx
);
return
false
;
}
NodePtr
&
new_subtree_ptr
=
GetPointerToChild
(
u
,
ux
);
new_subtree_ptr
=
nx
;
node_pool_
.
Free
(
ux
);
node_pool_
.
Free
(
uxl
);
node_pool_
.
Free
(
uxlr
);
return
true
;
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
bool
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
RB2_R
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxrl
)
{
NodePtr
nxr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
0
,
uxrl
->
GetRight
(),
uxr
->
GetRight
());
NodePtr
nxl
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
0
,
ux
->
GetLeft
(),
uxrl
->
GetLeft
());
NodePtr
nx
=
node_pool_
.
Allocate
(
uxrl
->
GetKey
(),
uxrl
->
GetValue
(),
ux
->
GetWeight
(),
nxl
,
nxr
);
if
(
nxr
==
NULL
||
nxl
==
NULL
||
nx
==
NULL
)
{
if
(
nxr
)
node_pool_
.
Free
(
nxr
);
if
(
nxl
)
node_pool_
.
Free
(
nxl
);
if
(
nx
)
node_pool_
.
Free
(
nx
);
return
false
;
}
NodePtr
&
new_subtree_ptr
=
GetPointerToChild
(
u
,
ux
);
new_subtree_ptr
=
nx
;
node_pool_
.
Free
(
ux
);
node_pool_
.
Free
(
uxr
);
node_pool_
.
Free
(
uxrl
);
return
true
;
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
bool
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
W1_L
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxrl
)
{
NodePtr
nxll
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
uxl
->
GetWeight
()
-
1
,
uxl
->
GetLeft
(),
uxl
->
GetRight
());
NodePtr
nxlr
=
node_pool_
.
Allocate
(
uxrl
->
GetKey
(),
uxrl
->
GetValue
(),
uxrl
->
GetWeight
()
-
1
,
uxrl
->
GetLeft
(),
uxrl
->
GetRight
());
NodePtr
nxl
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
1
,
nxll
,
nxlr
);
NodePtr
nx
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
ux
->
GetWeight
(),
nxl
,
uxr
->
GetRight
());
if
(
nxll
==
NULL
||
nxlr
==
NULL
||
nxl
==
NULL
||
nx
==
NULL
)
{
if
(
nxll
)
node_pool_
.
Free
(
nxll
);
if
(
nxlr
)
node_pool_
.
Free
(
nxlr
);
if
(
nxl
)
node_pool_
.
Free
(
nxl
);
if
(
nx
)
node_pool_
.
Free
(
nx
);
return
false
;
}
NodePtr
&
new_subtree_ptr
=
GetPointerToChild
(
u
,
ux
);
new_subtree_ptr
=
nx
;
node_pool_
.
Free
(
ux
);
node_pool_
.
Free
(
uxl
);
node_pool_
.
Free
(
uxr
);
node_pool_
.
Free
(
uxrl
);
return
true
;
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
bool
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
W1_R
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxlr
)
{
NodePtr
nxrr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
uxr
->
GetWeight
()
-
1
,
uxr
->
GetLeft
(),
uxr
->
GetRight
());
NodePtr
nxrl
=
node_pool_
.
Allocate
(
uxlr
->
GetKey
(),
uxlr
->
GetValue
(),
uxlr
->
GetWeight
()
-
1
,
uxlr
->
GetLeft
(),
uxlr
->
GetRight
());
NodePtr
nxr
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
1
,
nxrl
,
nxrr
);
NodePtr
nx
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
ux
->
GetWeight
(),
uxl
->
GetLeft
(),
nxr
);
if
(
nxrr
==
NULL
||
nxrl
==
NULL
||
nxr
==
NULL
||
nx
==
NULL
)
{
if
(
nxrr
)
node_pool_
.
Free
(
nxrr
);
if
(
nxrl
)
node_pool_
.
Free
(
nxrl
);
if
(
nxr
)
node_pool_
.
Free
(
nxr
);
if
(
nx
)
node_pool_
.
Free
(
nx
);
return
false
;
}
NodePtr
&
new_subtree_ptr
=
GetPointerToChild
(
u
,
ux
);
new_subtree_ptr
=
nx
;
node_pool_
.
Free
(
ux
);
node_pool_
.
Free
(
uxl
);
node_pool_
.
Free
(
uxr
);
node_pool_
.
Free
(
uxlr
);
return
true
;
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
bool
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
W2_L
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxrl
)
{
NodePtr
nxll
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
uxl
->
GetWeight
()
-
1
,
uxl
->
GetLeft
(),
uxl
->
GetRight
());
NodePtr
nxlr
=
node_pool_
.
Allocate
(
uxrl
->
GetKey
(),
uxrl
->
GetValue
(),
0
,
uxrl
->
GetLeft
(),
uxrl
->
GetRight
());
NodePtr
nxl
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
1
,
nxll
,
nxlr
);
NodePtr
nx
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
ux
->
GetWeight
(),
nxl
,
uxr
->
GetRight
());
if
(
nxll
==
NULL
||
nxlr
==
NULL
||
nxl
==
NULL
||
nx
==
NULL
)
{
if
(
nxll
)
node_pool_
.
Free
(
nxll
);
if
(
nxlr
)
node_pool_
.
Free
(
nxlr
);
if
(
nxl
)
node_pool_
.
Free
(
nxl
);
if
(
nx
)
node_pool_
.
Free
(
nx
);
return
false
;
}
NodePtr
&
new_subtree_ptr
=
GetPointerToChild
(
u
,
ux
);
new_subtree_ptr
=
nx
;
node_pool_
.
Free
(
ux
);
node_pool_
.
Free
(
uxl
);
node_pool_
.
Free
(
uxr
);
node_pool_
.
Free
(
uxrl
);
return
true
;
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
bool
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
W2_R
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxlr
)
{
NodePtr
nxrr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
uxr
->
GetWeight
()
-
1
,
uxr
->
GetLeft
(),
uxr
->
GetRight
());
NodePtr
nxrl
=
node_pool_
.
Allocate
(
uxlr
->
GetKey
(),
uxlr
->
GetValue
(),
0
,
uxlr
->
GetLeft
(),
uxlr
->
GetRight
());
NodePtr
nxr
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
1
,
nxrl
,
nxrr
);
NodePtr
nx
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
ux
->
GetWeight
(),
uxl
->
GetLeft
(),
nxr
);
if
(
nxrr
==
NULL
||
nxrl
==
NULL
||
nxr
==
NULL
||
nx
==
NULL
)
{
if
(
nxrr
)
node_pool_
.
Free
(
nxrr
);
if
(
nxrl
)
node_pool_
.
Free
(
nxrl
);
if
(
nxr
)
node_pool_
.
Free
(
nxr
);
if
(
nx
)
node_pool_
.
Free
(
nx
);
return
false
;
}
NodePtr
&
new_subtree_ptr
=
GetPointerToChild
(
u
,
ux
);
new_subtree_ptr
=
nx
;
node_pool_
.
Free
(
ux
);
node_pool_
.
Free
(
uxl
);
node_pool_
.
Free
(
uxr
);
node_pool_
.
Free
(
uxlr
);
return
true
;
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
bool
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
W3_L
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxrl
,
const
NodePtr
&
uxrll
)
{
NodePtr
nxlll
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
uxl
->
GetWeight
()
-
1
,
uxl
->
GetLeft
(),
uxl
->
GetRight
());
NodePtr
nxll
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
1
,
nxlll
,
uxrll
->
GetLeft
());
NodePtr
nxlr
=
node_pool_
.
Allocate
(
uxrl
->
GetKey
(),
uxrl
->
GetValue
(),
1
,
uxrll
->
GetRight
(),
uxrl
->
GetRight
());
NodePtr
nxl
=
node_pool_
.
Allocate
(
uxrll
->
GetKey
(),
uxrll
->
GetValue
(),
0
,
nxll
,
nxlr
);
NodePtr
nx
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
ux
->
GetWeight
(),
nxl
,
uxr
->
GetRight
());
if
(
nxlll
==
NULL
||
nxll
==
NULL
||
nxlr
==
NULL
||
nxl
==
NULL
||
nx
==
NULL
)
{
if
(
nxlll
)
node_pool_
.
Free
(
nxlll
);
if
(
nxll
)
node_pool_
.
Free
(
nxll
);
if
(
nxlr
)
node_pool_
.
Free
(
nxlr
);
if
(
nxl
)
node_pool_
.
Free
(
nxl
);
if
(
nx
)
node_pool_
.
Free
(
nx
);
return
false
;
}
NodePtr
&
new_subtree_ptr
=
GetPointerToChild
(
u
,
ux
);
new_subtree_ptr
=
nx
;
node_pool_
.
Free
(
ux
);
node_pool_
.
Free
(
uxl
);
node_pool_
.
Free
(
uxr
);
node_pool_
.
Free
(
uxrl
);
node_pool_
.
Free
(
uxrll
);
return
true
;
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
bool
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
W3_R
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxlr
,
const
NodePtr
&
uxlrr
)
{
NodePtr
nxrrr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
uxr
->
GetWeight
()
-
1
,
uxr
->
GetLeft
(),
uxr
->
GetRight
());
NodePtr
nxrr
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
1
,
uxlrr
->
GetRight
(),
nxrrr
);
NodePtr
nxrl
=
node_pool_
.
Allocate
(
uxlr
->
GetKey
(),
uxlr
->
GetValue
(),
1
,
uxlr
->
GetLeft
(),
uxlrr
->
GetLeft
());
NodePtr
nxr
=
node_pool_
.
Allocate
(
uxlrr
->
GetKey
(),
uxlrr
->
GetValue
(),
0
,
nxrl
,
nxrr
);
NodePtr
nx
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
ux
->
GetWeight
(),
uxl
->
GetLeft
(),
nxr
);
if
(
nxrrr
==
NULL
||
nxrr
==
NULL
||
nxrl
==
NULL
||
nxr
==
NULL
||
nx
==
NULL
)
{
if
(
nxrrr
)
node_pool_
.
Free
(
nxrrr
);
if
(
nxrr
)
node_pool_
.
Free
(
nxrr
);
if
(
nxrl
)
node_pool_
.
Free
(
nxrl
);
if
(
nxr
)
node_pool_
.
Free
(
nxr
);
if
(
nx
)
node_pool_
.
Free
(
nx
);
return
false
;
}
NodePtr
&
new_subtree_ptr
=
GetPointerToChild
(
u
,
ux
);
new_subtree_ptr
=
nx
;
node_pool_
.
Free
(
ux
);
node_pool_
.
Free
(
uxl
);
node_pool_
.
Free
(
uxr
);
node_pool_
.
Free
(
uxlr
);
node_pool_
.
Free
(
uxlrr
);
return
true
;
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
bool
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
W4_L
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxrl
,
const
NodePtr
&
uxrlr
)
{
NodePtr
nxll
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
uxl
->
GetWeight
()
-
1
,
uxl
->
GetLeft
(),
uxl
->
GetRight
());
NodePtr
nxrl
=
node_pool_
.
Allocate
(
uxrlr
->
GetKey
(),
uxrlr
->
GetValue
(),
1
,
uxrlr
->
GetLeft
(),
uxrlr
->
GetRight
());
NodePtr
nxl
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
1
,
nxll
,
uxrl
->
GetLeft
());
NodePtr
nxr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
0
,
nxrl
,
uxr
->
GetRight
());
NodePtr
nx
=
node_pool_
.
Allocate
(
uxrl
->
GetKey
(),
uxrl
->
GetValue
(),
ux
->
GetWeight
(),
nxl
,
nxr
);
if
(
nxll
==
NULL
||
nxrl
==
NULL
||
nxl
==
NULL
||
nxr
==
NULL
||
nx
==
NULL
)
{
if
(
nxll
)
node_pool_
.
Free
(
nxll
);
if
(
nxrl
)
node_pool_
.
Free
(
nxrl
);
if
(
nxl
)
node_pool_
.
Free
(
nxl
);
if
(
nxr
)
node_pool_
.
Free
(
nxr
);
if
(
nx
)
node_pool_
.
Free
(
nx
);
return
false
;
}
NodePtr
&
new_subtree_ptr
=
GetPointerToChild
(
u
,
ux
);
new_subtree_ptr
=
nx
;
node_pool_
.
Free
(
ux
);
node_pool_
.
Free
(
uxl
);
node_pool_
.
Free
(
uxr
);
node_pool_
.
Free
(
uxrl
);
node_pool_
.
Free
(
uxrlr
);
return
true
;
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
bool
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
W4_R
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxlr
,
const
NodePtr
&
uxlrl
)
{
NodePtr
nxrr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
uxr
->
GetWeight
()
-
1
,
uxr
->
GetLeft
(),
uxr
->
GetRight
());
NodePtr
nxlr
=
node_pool_
.
Allocate
(
uxlrl
->
GetKey
(),
uxlrl
->
GetValue
(),
1
,
uxlrl
->
GetLeft
(),
uxlrl
->
GetRight
());
NodePtr
nxr
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
1
,
uxlr
->
GetRight
(),
nxrr
);
NodePtr
nxl
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
0
,
uxl
->
GetLeft
(),
nxlr
);
NodePtr
nx
=
node_pool_
.
Allocate
(
uxlr
->
GetKey
(),
uxlr
->
GetValue
(),
ux
->
GetWeight
(),
nxl
,
nxr
);
if
(
nxrr
==
NULL
||
nxlr
==
NULL
||
nxr
==
NULL
||
nxl
==
NULL
||
nx
==
NULL
)
{
if
(
nxrr
)
node_pool_
.
Free
(
nxrr
);
if
(
nxlr
)
node_pool_
.
Free
(
nxlr
);
if
(
nxr
)
node_pool_
.
Free
(
nxr
);
if
(
nxl
)
node_pool_
.
Free
(
nxl
);
if
(
nx
)
node_pool_
.
Free
(
nx
);
return
false
;
}
NodePtr
&
new_subtree_ptr
=
GetPointerToChild
(
u
,
ux
);
new_subtree_ptr
=
nx
;
node_pool_
.
Free
(
ux
);
node_pool_
.
Free
(
uxl
);
node_pool_
.
Free
(
uxr
);
node_pool_
.
Free
(
uxlr
);
node_pool_
.
Free
(
uxlrl
);
return
true
;
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
bool
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
W5_L
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxrr
)
{
NodePtr
nxll
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
uxl
->
GetWeight
()
-
1
,
uxl
->
GetLeft
(),
uxl
->
GetRight
());
NodePtr
nxl
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
1
,
nxll
,
uxr
->
GetLeft
());
NodePtr
nxr
=
node_pool_
.
Allocate
(
uxrr
->
GetKey
(),
uxrr
->
GetValue
(),
1
,
uxrr
->
GetLeft
(),
uxrr
->
GetRight
());
NodePtr
nx
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
ux
->
GetWeight
(),
nxl
,
nxr
);
if
(
nxll
==
NULL
||
nxl
==
NULL
||
nxr
==
NULL
||
nx
==
NULL
)
{
if
(
nxll
)
node_pool_
.
Free
(
nxll
);
if
(
nxl
)
node_pool_
.
Free
(
nxl
);
if
(
nxr
)
node_pool_
.
Free
(
nxr
);
if
(
nx
)
node_pool_
.
Free
(
nx
);
return
false
;
}
NodePtr
&
new_subtree_ptr
=
GetPointerToChild
(
u
,
ux
);
new_subtree_ptr
=
nx
;
node_pool_
.
Free
(
ux
);
node_pool_
.
Free
(
uxl
);
node_pool_
.
Free
(
uxr
);
node_pool_
.
Free
(
uxrr
);
return
true
;
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
bool
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
W5_R
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxll
)
{
NodePtr
nxrr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
uxr
->
GetWeight
()
-
1
,
uxr
->
GetLeft
(),
uxr
->
GetRight
());
NodePtr
nxr
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
1
,
uxl
->
GetRight
(),
nxrr
);
NodePtr
nxl
=
node_pool_
.
Allocate
(
uxll
->
GetKey
(),
uxll
->
GetValue
(),
1
,
uxll
->
GetLeft
(),
uxll
->
GetRight
());
NodePtr
nx
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
ux
->
GetWeight
(),
nxl
,
nxr
);
if
(
nxrr
==
NULL
||
nxr
==
NULL
||
nxl
==
NULL
||
nx
==
NULL
)
{
if
(
nxrr
)
node_pool_
.
Free
(
nxrr
);
if
(
nxr
)
node_pool_
.
Free
(
nxr
);
if
(
nxl
)
node_pool_
.
Free
(
nxl
);
if
(
nx
)
node_pool_
.
Free
(
nx
);
return
false
;
}
NodePtr
&
new_subtree_ptr
=
GetPointerToChild
(
u
,
ux
);
new_subtree_ptr
=
nx
;
node_pool_
.
Free
(
ux
);
node_pool_
.
Free
(
uxl
);
node_pool_
.
Free
(
uxr
);
node_pool_
.
Free
(
uxll
);
return
true
;
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
bool
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
W6_L
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxrl
)
{
NodePtr
nxll
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
uxl
->
GetWeight
()
-
1
,
uxl
->
GetLeft
(),
uxl
->
GetRight
());
NodePtr
nxl
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
1
,
nxll
,
uxrl
->
GetLeft
());
NodePtr
nxr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
1
,
uxrl
->
GetRight
(),
uxr
->
GetRight
());
NodePtr
nx
=
node_pool_
.
Allocate
(
uxrl
->
GetKey
(),
uxrl
->
GetValue
(),
ux
->
GetWeight
(),
nxl
,
nxr
);
if
(
nxll
==
NULL
||
nxl
==
NULL
||
nxr
==
NULL
||
nx
==
NULL
)
{
if
(
nxll
)
node_pool_
.
Free
(
nxll
);
if
(
nxl
)
node_pool_
.
Free
(
nxl
);
if
(
nxr
)
node_pool_
.
Free
(
nxr
);
if
(
nx
)
node_pool_
.
Free
(
nx
);
return
false
;
}
NodePtr
&
new_subtree_ptr
=
GetPointerToChild
(
u
,
ux
);
new_subtree_ptr
=
nx
;
node_pool_
.
Free
(
ux
);
node_pool_
.
Free
(
uxl
);
node_pool_
.
Free
(
uxr
);
node_pool_
.
Free
(
uxrl
);
return
true
;
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
bool
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
W6_R
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxlr
)
{
NodePtr
nxrr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
uxr
->
GetWeight
()
-
1
,
uxr
->
GetLeft
(),
uxr
->
GetRight
());
NodePtr
nxr
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
1
,
uxlr
->
GetRight
(),
nxrr
);
NodePtr
nxl
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
1
,
uxl
->
GetLeft
(),
uxlr
->
GetLeft
());
NodePtr
nx
=
node_pool_
.
Allocate
(
uxlr
->
GetKey
(),
uxlr
->
GetValue
(),
ux
->
GetWeight
(),
nxl
,
nxr
);
if
(
nxrr
==
NULL
||
nxr
==
NULL
||
nxl
==
NULL
||
nx
==
NULL
)
{
if
(
nxrr
)
node_pool_
.
Free
(
nxrr
);
if
(
nxr
)
node_pool_
.
Free
(
nxr
);
if
(
nxl
)
node_pool_
.
Free
(
nxl
);
if
(
nx
)
node_pool_
.
Free
(
nx
);
return
false
;
}
NodePtr
&
new_subtree_ptr
=
GetPointerToChild
(
u
,
ux
);
new_subtree_ptr
=
nx
;
node_pool_
.
Free
(
ux
);
node_pool_
.
Free
(
uxl
);
node_pool_
.
Free
(
uxr
);
node_pool_
.
Free
(
uxlr
);
return
true
;
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
bool
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
W7
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
)
{
NodePtr
nxl
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
uxl
->
GetWeight
()
-
1
,
uxl
->
GetLeft
(),
uxl
->
GetRight
());
NodePtr
nxr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
uxr
->
GetWeight
()
-
1
,
uxr
->
GetLeft
(),
uxr
->
GetRight
());
NodePtr
nx
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
HasFixedWeight
(
ux
)
?
1
:
ux
->
GetWeight
()
+
1
,
nxl
,
nxr
);
if
(
nxl
==
NULL
||
nxr
==
NULL
||
nx
==
NULL
)
{
if
(
nxl
)
node_pool_
.
Free
(
nxl
);
if
(
nxr
)
node_pool_
.
Free
(
nxr
);
if
(
nx
)
node_pool_
.
Free
(
nx
);
return
false
;
}
NodePtr
&
new_subtree_ptr
=
GetPointerToChild
(
u
,
ux
);
new_subtree_ptr
=
nx
;
node_pool_
.
Free
(
ux
);
node_pool_
.
Free
(
uxl
);
node_pool_
.
Free
(
uxr
);
return
true
;
}
}
// namespace containers
}
// namespace embb
...
...
containers_cpp/include/embb/containers/internal/lock_free_chromatic_tree-rebalance.h
0 → 100644
View file @
871b5391
/*
* Copyright (c) 2014-2015, Siemens AG. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
//
// This file was created automatically by a code generator.
// Any direct changes will be lost after rebuild of the project.
//
#ifndef EMBB_CONTAINERS_LOCK_FREE_CHROMATIC_TREE_REBALANCE_H_
#define EMBB_CONTAINERS_LOCK_FREE_CHROMATIC_TREE_REBALANCE_H_
bool
BLK
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
)
{
NodePtr
nxl
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
1
,
uxl
->
GetLeft
(),
uxl
->
GetRight
());
NodePtr
nxr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
1
,
uxr
->
GetLeft
(),
uxr
->
GetRight
());
NodePtr
nx
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
HasFixedWeight
(
ux
)
?
1
:
ux
->
GetWeight
()
-
1
,
nxl
,
nxr
);
if
(
nxl
==
NULL
||
nxr
==
NULL
||
nx
==
NULL
)
{
if
(
nxl
)
FreeNode
(
nxl
);
if
(
nxr
)
FreeNode
(
nxr
);
if
(
nx
)
FreeNode
(
nx
);
return
false
;
}
NodePtr
expected
=
ux
;
GetPointerToChild
(
u
,
ux
).
CompareAndSwap
(
expected
,
nx
);
RetireNode
(
ux
);
RetireNode
(
uxl
);
RetireNode
(
uxr
);
return
true
;
}
bool
PUSH_L
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
)
{
NodePtr
nxl
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
uxl
->
GetWeight
()
-
1
,
uxl
->
GetLeft
(),
uxl
->
GetRight
());
NodePtr
nxr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
0
,
uxr
->
GetLeft
(),
uxr
->
GetRight
());
NodePtr
nx
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
HasFixedWeight
(
ux
)
?
1
:
ux
->
GetWeight
()
+
1
,
nxl
,
nxr
);
if
(
nxl
==
NULL
||
nxr
==
NULL
||
nx
==
NULL
)
{
if
(
nxl
)
FreeNode
(
nxl
);
if
(
nxr
)
FreeNode
(
nxr
);
if
(
nx
)
FreeNode
(
nx
);
return
false
;
}
NodePtr
expected
=
ux
;
GetPointerToChild
(
u
,
ux
).
CompareAndSwap
(
expected
,
nx
);
RetireNode
(
ux
);
RetireNode
(
uxl
);
RetireNode
(
uxr
);
return
true
;
}
bool
PUSH_R
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
)
{
NodePtr
nxr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
uxr
->
GetWeight
()
-
1
,
uxr
->
GetLeft
(),
uxr
->
GetRight
());
NodePtr
nxl
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
0
,
uxl
->
GetLeft
(),
uxl
->
GetRight
());
NodePtr
nx
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
HasFixedWeight
(
ux
)
?
1
:
ux
->
GetWeight
()
+
1
,
nxl
,
nxr
);
if
(
nxr
==
NULL
||
nxl
==
NULL
||
nx
==
NULL
)
{
if
(
nxr
)
FreeNode
(
nxr
);
if
(
nxl
)
FreeNode
(
nxl
);
if
(
nx
)
FreeNode
(
nx
);
return
false
;
}
NodePtr
expected
=
ux
;
GetPointerToChild
(
u
,
ux
).
CompareAndSwap
(
expected
,
nx
);
RetireNode
(
ux
);
RetireNode
(
uxl
);
RetireNode
(
uxr
);
return
true
;
}
bool
RB1_L
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
)
{
NodePtr
nxr
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
0
,
uxl
->
GetRight
(),
ux
->
GetRight
());
NodePtr
nx
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
ux
->
GetWeight
(),
uxl
->
GetLeft
(),
nxr
);
if
(
nxr
==
NULL
||
nx
==
NULL
)
{
if
(
nxr
)
FreeNode
(
nxr
);
if
(
nx
)
FreeNode
(
nx
);
return
false
;
}
NodePtr
expected
=
ux
;
GetPointerToChild
(
u
,
ux
).
CompareAndSwap
(
expected
,
nx
);
RetireNode
(
ux
);
RetireNode
(
uxl
);
return
true
;
}
bool
RB1_R
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxr
)
{
NodePtr
nxl
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
0
,
ux
->
GetLeft
(),
uxr
->
GetLeft
());
NodePtr
nx
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
ux
->
GetWeight
(),
nxl
,
uxr
->
GetRight
());
if
(
nxl
==
NULL
||
nx
==
NULL
)
{
if
(
nxl
)
FreeNode
(
nxl
);
if
(
nx
)
FreeNode
(
nx
);
return
false
;
}
NodePtr
expected
=
ux
;
GetPointerToChild
(
u
,
ux
).
CompareAndSwap
(
expected
,
nx
);
RetireNode
(
ux
);
RetireNode
(
uxr
);
return
true
;
}
bool
RB2_L
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxlr
)
{
NodePtr
nxl
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
0
,
uxl
->
GetLeft
(),
uxlr
->
GetLeft
());
NodePtr
nxr
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
0
,
uxlr
->
GetRight
(),
ux
->
GetRight
());
NodePtr
nx
=
node_pool_
.
Allocate
(
uxlr
->
GetKey
(),
uxlr
->
GetValue
(),
ux
->
GetWeight
(),
nxl
,
nxr
);
if
(
nxl
==
NULL
||
nxr
==
NULL
||
nx
==
NULL
)
{
if
(
nxl
)
FreeNode
(
nxl
);
if
(
nxr
)
FreeNode
(
nxr
);
if
(
nx
)
FreeNode
(
nx
);
return
false
;
}
NodePtr
expected
=
ux
;
GetPointerToChild
(
u
,
ux
).
CompareAndSwap
(
expected
,
nx
);
RetireNode
(
ux
);
RetireNode
(
uxl
);
RetireNode
(
uxlr
);
return
true
;
}
bool
RB2_R
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxrl
)
{
NodePtr
nxr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
0
,
uxrl
->
GetRight
(),
uxr
->
GetRight
());
NodePtr
nxl
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
0
,
ux
->
GetLeft
(),
uxrl
->
GetLeft
());
NodePtr
nx
=
node_pool_
.
Allocate
(
uxrl
->
GetKey
(),
uxrl
->
GetValue
(),
ux
->
GetWeight
(),
nxl
,
nxr
);
if
(
nxr
==
NULL
||
nxl
==
NULL
||
nx
==
NULL
)
{
if
(
nxr
)
FreeNode
(
nxr
);
if
(
nxl
)
FreeNode
(
nxl
);
if
(
nx
)
FreeNode
(
nx
);
return
false
;
}
NodePtr
expected
=
ux
;
GetPointerToChild
(
u
,
ux
).
CompareAndSwap
(
expected
,
nx
);
RetireNode
(
ux
);
RetireNode
(
uxr
);
RetireNode
(
uxrl
);
return
true
;
}
bool
W1_L
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxrl
)
{
NodePtr
nxll
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
uxl
->
GetWeight
()
-
1
,
uxl
->
GetLeft
(),
uxl
->
GetRight
());
NodePtr
nxlr
=
node_pool_
.
Allocate
(
uxrl
->
GetKey
(),
uxrl
->
GetValue
(),
uxrl
->
GetWeight
()
-
1
,
uxrl
->
GetLeft
(),
uxrl
->
GetRight
());
NodePtr
nxl
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
1
,
nxll
,
nxlr
);
NodePtr
nx
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
ux
->
GetWeight
(),
nxl
,
uxr
->
GetRight
());
if
(
nxll
==
NULL
||
nxlr
==
NULL
||
nxl
==
NULL
||
nx
==
NULL
)
{
if
(
nxll
)
FreeNode
(
nxll
);
if
(
nxlr
)
FreeNode
(
nxlr
);
if
(
nxl
)
FreeNode
(
nxl
);
if
(
nx
)
FreeNode
(
nx
);
return
false
;
}
NodePtr
expected
=
ux
;
GetPointerToChild
(
u
,
ux
).
CompareAndSwap
(
expected
,
nx
);
RetireNode
(
ux
);
RetireNode
(
uxl
);
RetireNode
(
uxr
);
RetireNode
(
uxrl
);
return
true
;
}
bool
W1_R
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxlr
)
{
NodePtr
nxrr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
uxr
->
GetWeight
()
-
1
,
uxr
->
GetLeft
(),
uxr
->
GetRight
());
NodePtr
nxrl
=
node_pool_
.
Allocate
(
uxlr
->
GetKey
(),
uxlr
->
GetValue
(),
uxlr
->
GetWeight
()
-
1
,
uxlr
->
GetLeft
(),
uxlr
->
GetRight
());
NodePtr
nxr
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
1
,
nxrl
,
nxrr
);
NodePtr
nx
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
ux
->
GetWeight
(),
uxl
->
GetLeft
(),
nxr
);
if
(
nxrr
==
NULL
||
nxrl
==
NULL
||
nxr
==
NULL
||
nx
==
NULL
)
{
if
(
nxrr
)
FreeNode
(
nxrr
);
if
(
nxrl
)
FreeNode
(
nxrl
);
if
(
nxr
)
FreeNode
(
nxr
);
if
(
nx
)
FreeNode
(
nx
);
return
false
;
}
NodePtr
expected
=
ux
;
GetPointerToChild
(
u
,
ux
).
CompareAndSwap
(
expected
,
nx
);
RetireNode
(
ux
);
RetireNode
(
uxl
);
RetireNode
(
uxr
);
RetireNode
(
uxlr
);
return
true
;
}
bool
W2_L
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxrl
)
{
NodePtr
nxll
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
uxl
->
GetWeight
()
-
1
,
uxl
->
GetLeft
(),
uxl
->
GetRight
());
NodePtr
nxlr
=
node_pool_
.
Allocate
(
uxrl
->
GetKey
(),
uxrl
->
GetValue
(),
0
,
uxrl
->
GetLeft
(),
uxrl
->
GetRight
());
NodePtr
nxl
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
1
,
nxll
,
nxlr
);
NodePtr
nx
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
ux
->
GetWeight
(),
nxl
,
uxr
->
GetRight
());
if
(
nxll
==
NULL
||
nxlr
==
NULL
||
nxl
==
NULL
||
nx
==
NULL
)
{
if
(
nxll
)
FreeNode
(
nxll
);
if
(
nxlr
)
FreeNode
(
nxlr
);
if
(
nxl
)
FreeNode
(
nxl
);
if
(
nx
)
FreeNode
(
nx
);
return
false
;
}
NodePtr
expected
=
ux
;
GetPointerToChild
(
u
,
ux
).
CompareAndSwap
(
expected
,
nx
);
RetireNode
(
ux
);
RetireNode
(
uxl
);
RetireNode
(
uxr
);
RetireNode
(
uxrl
);
return
true
;
}
bool
W2_R
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxlr
)
{
NodePtr
nxrr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
uxr
->
GetWeight
()
-
1
,
uxr
->
GetLeft
(),
uxr
->
GetRight
());
NodePtr
nxrl
=
node_pool_
.
Allocate
(
uxlr
->
GetKey
(),
uxlr
->
GetValue
(),
0
,
uxlr
->
GetLeft
(),
uxlr
->
GetRight
());
NodePtr
nxr
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
1
,
nxrl
,
nxrr
);
NodePtr
nx
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
ux
->
GetWeight
(),
uxl
->
GetLeft
(),
nxr
);
if
(
nxrr
==
NULL
||
nxrl
==
NULL
||
nxr
==
NULL
||
nx
==
NULL
)
{
if
(
nxrr
)
FreeNode
(
nxrr
);
if
(
nxrl
)
FreeNode
(
nxrl
);
if
(
nxr
)
FreeNode
(
nxr
);
if
(
nx
)
FreeNode
(
nx
);
return
false
;
}
NodePtr
expected
=
ux
;
GetPointerToChild
(
u
,
ux
).
CompareAndSwap
(
expected
,
nx
);
RetireNode
(
ux
);
RetireNode
(
uxl
);
RetireNode
(
uxr
);
RetireNode
(
uxlr
);
return
true
;
}
bool
W3_L
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxrl
,
const
NodePtr
&
uxrll
)
{
NodePtr
nxlll
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
uxl
->
GetWeight
()
-
1
,
uxl
->
GetLeft
(),
uxl
->
GetRight
());
NodePtr
nxll
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
1
,
nxlll
,
uxrll
->
GetLeft
());
NodePtr
nxlr
=
node_pool_
.
Allocate
(
uxrl
->
GetKey
(),
uxrl
->
GetValue
(),
1
,
uxrll
->
GetRight
(),
uxrl
->
GetRight
());
NodePtr
nxl
=
node_pool_
.
Allocate
(
uxrll
->
GetKey
(),
uxrll
->
GetValue
(),
0
,
nxll
,
nxlr
);
NodePtr
nx
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
ux
->
GetWeight
(),
nxl
,
uxr
->
GetRight
());
if
(
nxlll
==
NULL
||
nxll
==
NULL
||
nxlr
==
NULL
||
nxl
==
NULL
||
nx
==
NULL
)
{
if
(
nxlll
)
FreeNode
(
nxlll
);
if
(
nxll
)
FreeNode
(
nxll
);
if
(
nxlr
)
FreeNode
(
nxlr
);
if
(
nxl
)
FreeNode
(
nxl
);
if
(
nx
)
FreeNode
(
nx
);
return
false
;
}
NodePtr
expected
=
ux
;
GetPointerToChild
(
u
,
ux
).
CompareAndSwap
(
expected
,
nx
);
RetireNode
(
ux
);
RetireNode
(
uxl
);
RetireNode
(
uxr
);
RetireNode
(
uxrl
);
RetireNode
(
uxrll
);
return
true
;
}
bool
W3_R
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxlr
,
const
NodePtr
&
uxlrr
)
{
NodePtr
nxrrr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
uxr
->
GetWeight
()
-
1
,
uxr
->
GetLeft
(),
uxr
->
GetRight
());
NodePtr
nxrr
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
1
,
uxlrr
->
GetRight
(),
nxrrr
);
NodePtr
nxrl
=
node_pool_
.
Allocate
(
uxlr
->
GetKey
(),
uxlr
->
GetValue
(),
1
,
uxlr
->
GetLeft
(),
uxlrr
->
GetLeft
());
NodePtr
nxr
=
node_pool_
.
Allocate
(
uxlrr
->
GetKey
(),
uxlrr
->
GetValue
(),
0
,
nxrl
,
nxrr
);
NodePtr
nx
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
ux
->
GetWeight
(),
uxl
->
GetLeft
(),
nxr
);
if
(
nxrrr
==
NULL
||
nxrr
==
NULL
||
nxrl
==
NULL
||
nxr
==
NULL
||
nx
==
NULL
)
{
if
(
nxrrr
)
FreeNode
(
nxrrr
);
if
(
nxrr
)
FreeNode
(
nxrr
);
if
(
nxrl
)
FreeNode
(
nxrl
);
if
(
nxr
)
FreeNode
(
nxr
);
if
(
nx
)
FreeNode
(
nx
);
return
false
;
}
NodePtr
expected
=
ux
;
GetPointerToChild
(
u
,
ux
).
CompareAndSwap
(
expected
,
nx
);
RetireNode
(
ux
);
RetireNode
(
uxl
);
RetireNode
(
uxr
);
RetireNode
(
uxlr
);
RetireNode
(
uxlrr
);
return
true
;
}
bool
W4_L
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxrl
,
const
NodePtr
&
uxrlr
)
{
NodePtr
nxll
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
uxl
->
GetWeight
()
-
1
,
uxl
->
GetLeft
(),
uxl
->
GetRight
());
NodePtr
nxrl
=
node_pool_
.
Allocate
(
uxrlr
->
GetKey
(),
uxrlr
->
GetValue
(),
1
,
uxrlr
->
GetLeft
(),
uxrlr
->
GetRight
());
NodePtr
nxl
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
1
,
nxll
,
uxrl
->
GetLeft
());
NodePtr
nxr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
0
,
nxrl
,
uxr
->
GetRight
());
NodePtr
nx
=
node_pool_
.
Allocate
(
uxrl
->
GetKey
(),
uxrl
->
GetValue
(),
ux
->
GetWeight
(),
nxl
,
nxr
);
if
(
nxll
==
NULL
||
nxrl
==
NULL
||
nxl
==
NULL
||
nxr
==
NULL
||
nx
==
NULL
)
{
if
(
nxll
)
FreeNode
(
nxll
);
if
(
nxrl
)
FreeNode
(
nxrl
);
if
(
nxl
)
FreeNode
(
nxl
);
if
(
nxr
)
FreeNode
(
nxr
);
if
(
nx
)
FreeNode
(
nx
);
return
false
;
}
NodePtr
expected
=
ux
;
GetPointerToChild
(
u
,
ux
).
CompareAndSwap
(
expected
,
nx
);
RetireNode
(
ux
);
RetireNode
(
uxl
);
RetireNode
(
uxr
);
RetireNode
(
uxrl
);
RetireNode
(
uxrlr
);
return
true
;
}
bool
W4_R
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxlr
,
const
NodePtr
&
uxlrl
)
{
NodePtr
nxrr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
uxr
->
GetWeight
()
-
1
,
uxr
->
GetLeft
(),
uxr
->
GetRight
());
NodePtr
nxlr
=
node_pool_
.
Allocate
(
uxlrl
->
GetKey
(),
uxlrl
->
GetValue
(),
1
,
uxlrl
->
GetLeft
(),
uxlrl
->
GetRight
());
NodePtr
nxr
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
1
,
uxlr
->
GetRight
(),
nxrr
);
NodePtr
nxl
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
0
,
uxl
->
GetLeft
(),
nxlr
);
NodePtr
nx
=
node_pool_
.
Allocate
(
uxlr
->
GetKey
(),
uxlr
->
GetValue
(),
ux
->
GetWeight
(),
nxl
,
nxr
);
if
(
nxrr
==
NULL
||
nxlr
==
NULL
||
nxr
==
NULL
||
nxl
==
NULL
||
nx
==
NULL
)
{
if
(
nxrr
)
FreeNode
(
nxrr
);
if
(
nxlr
)
FreeNode
(
nxlr
);
if
(
nxr
)
FreeNode
(
nxr
);
if
(
nxl
)
FreeNode
(
nxl
);
if
(
nx
)
FreeNode
(
nx
);
return
false
;
}
NodePtr
expected
=
ux
;
GetPointerToChild
(
u
,
ux
).
CompareAndSwap
(
expected
,
nx
);
RetireNode
(
ux
);
RetireNode
(
uxl
);
RetireNode
(
uxr
);
RetireNode
(
uxlr
);
RetireNode
(
uxlrl
);
return
true
;
}
bool
W5_L
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxrr
)
{
NodePtr
nxll
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
uxl
->
GetWeight
()
-
1
,
uxl
->
GetLeft
(),
uxl
->
GetRight
());
NodePtr
nxl
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
1
,
nxll
,
uxr
->
GetLeft
());
NodePtr
nxr
=
node_pool_
.
Allocate
(
uxrr
->
GetKey
(),
uxrr
->
GetValue
(),
1
,
uxrr
->
GetLeft
(),
uxrr
->
GetRight
());
NodePtr
nx
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
ux
->
GetWeight
(),
nxl
,
nxr
);
if
(
nxll
==
NULL
||
nxl
==
NULL
||
nxr
==
NULL
||
nx
==
NULL
)
{
if
(
nxll
)
FreeNode
(
nxll
);
if
(
nxl
)
FreeNode
(
nxl
);
if
(
nxr
)
FreeNode
(
nxr
);
if
(
nx
)
FreeNode
(
nx
);
return
false
;
}
NodePtr
expected
=
ux
;
GetPointerToChild
(
u
,
ux
).
CompareAndSwap
(
expected
,
nx
);
RetireNode
(
ux
);
RetireNode
(
uxl
);
RetireNode
(
uxr
);
RetireNode
(
uxrr
);
return
true
;
}
bool
W5_R
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxll
)
{
NodePtr
nxrr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
uxr
->
GetWeight
()
-
1
,
uxr
->
GetLeft
(),
uxr
->
GetRight
());
NodePtr
nxr
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
1
,
uxl
->
GetRight
(),
nxrr
);
NodePtr
nxl
=
node_pool_
.
Allocate
(
uxll
->
GetKey
(),
uxll
->
GetValue
(),
1
,
uxll
->
GetLeft
(),
uxll
->
GetRight
());
NodePtr
nx
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
ux
->
GetWeight
(),
nxl
,
nxr
);
if
(
nxrr
==
NULL
||
nxr
==
NULL
||
nxl
==
NULL
||
nx
==
NULL
)
{
if
(
nxrr
)
FreeNode
(
nxrr
);
if
(
nxr
)
FreeNode
(
nxr
);
if
(
nxl
)
FreeNode
(
nxl
);
if
(
nx
)
FreeNode
(
nx
);
return
false
;
}
NodePtr
expected
=
ux
;
GetPointerToChild
(
u
,
ux
).
CompareAndSwap
(
expected
,
nx
);
RetireNode
(
ux
);
RetireNode
(
uxl
);
RetireNode
(
uxr
);
RetireNode
(
uxll
);
return
true
;
}
bool
W6_L
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxrl
)
{
NodePtr
nxll
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
uxl
->
GetWeight
()
-
1
,
uxl
->
GetLeft
(),
uxl
->
GetRight
());
NodePtr
nxl
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
1
,
nxll
,
uxrl
->
GetLeft
());
NodePtr
nxr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
1
,
uxrl
->
GetRight
(),
uxr
->
GetRight
());
NodePtr
nx
=
node_pool_
.
Allocate
(
uxrl
->
GetKey
(),
uxrl
->
GetValue
(),
ux
->
GetWeight
(),
nxl
,
nxr
);
if
(
nxll
==
NULL
||
nxl
==
NULL
||
nxr
==
NULL
||
nx
==
NULL
)
{
if
(
nxll
)
FreeNode
(
nxll
);
if
(
nxl
)
FreeNode
(
nxl
);
if
(
nxr
)
FreeNode
(
nxr
);
if
(
nx
)
FreeNode
(
nx
);
return
false
;
}
NodePtr
expected
=
ux
;
GetPointerToChild
(
u
,
ux
).
CompareAndSwap
(
expected
,
nx
);
RetireNode
(
ux
);
RetireNode
(
uxl
);
RetireNode
(
uxr
);
RetireNode
(
uxrl
);
return
true
;
}
bool
W6_R
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxlr
)
{
NodePtr
nxrr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
uxr
->
GetWeight
()
-
1
,
uxr
->
GetLeft
(),
uxr
->
GetRight
());
NodePtr
nxr
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
1
,
uxlr
->
GetRight
(),
nxrr
);
NodePtr
nxl
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
1
,
uxl
->
GetLeft
(),
uxlr
->
GetLeft
());
NodePtr
nx
=
node_pool_
.
Allocate
(
uxlr
->
GetKey
(),
uxlr
->
GetValue
(),
ux
->
GetWeight
(),
nxl
,
nxr
);
if
(
nxrr
==
NULL
||
nxr
==
NULL
||
nxl
==
NULL
||
nx
==
NULL
)
{
if
(
nxrr
)
FreeNode
(
nxrr
);
if
(
nxr
)
FreeNode
(
nxr
);
if
(
nxl
)
FreeNode
(
nxl
);
if
(
nx
)
FreeNode
(
nx
);
return
false
;
}
NodePtr
expected
=
ux
;
GetPointerToChild
(
u
,
ux
).
CompareAndSwap
(
expected
,
nx
);
RetireNode
(
ux
);
RetireNode
(
uxl
);
RetireNode
(
uxr
);
RetireNode
(
uxlr
);
return
true
;
}
bool
W7
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
)
{
NodePtr
nxl
=
node_pool_
.
Allocate
(
uxl
->
GetKey
(),
uxl
->
GetValue
(),
uxl
->
GetWeight
()
-
1
,
uxl
->
GetLeft
(),
uxl
->
GetRight
());
NodePtr
nxr
=
node_pool_
.
Allocate
(
uxr
->
GetKey
(),
uxr
->
GetValue
(),
uxr
->
GetWeight
()
-
1
,
uxr
->
GetLeft
(),
uxr
->
GetRight
());
NodePtr
nx
=
node_pool_
.
Allocate
(
ux
->
GetKey
(),
ux
->
GetValue
(),
HasFixedWeight
(
ux
)
?
1
:
ux
->
GetWeight
()
+
1
,
nxl
,
nxr
);
if
(
nxl
==
NULL
||
nxr
==
NULL
||
nx
==
NULL
)
{
if
(
nxl
)
FreeNode
(
nxl
);
if
(
nxr
)
FreeNode
(
nxr
);
if
(
nx
)
FreeNode
(
nx
);
return
false
;
}
NodePtr
expected
=
ux
;
GetPointerToChild
(
u
,
ux
).
CompareAndSwap
(
expected
,
nx
);
RetireNode
(
ux
);
RetireNode
(
uxl
);
RetireNode
(
uxr
);
return
true
;
}
#endif // EMBB_CONTAINERS_LOCK_FREE_CHROMATIC_TREE_REBALANCE_H_
containers_cpp/include/embb/containers/lock_free_chromatic_tree.h
View file @
871b5391
...
...
@@ -31,6 +31,7 @@
#include <functional>
#include <embb/base/mutex.h>
#include <embb/containers/internal/hazard_pointer.h>
namespace
embb
{
namespace
containers
{
...
...
@@ -48,6 +49,9 @@ namespace internal {
template
<
typename
Key
,
typename
Value
>
class
ChromaticTreeNode
{
public
:
typedef
ChromaticTreeNode
<
Key
,
Value
>*
ChildPointer
;
typedef
embb
::
base
::
Atomic
<
ChildPointer
>
AtomicChildPointer
;
/**
* Creates a node with given parameters.
*
...
...
@@ -58,8 +62,7 @@ class ChromaticTreeNode {
* \param[IN] right Pointer to the right child node
*/
ChromaticTreeNode
(
const
Key
&
key
,
const
Value
&
value
,
const
int
weight
,
ChromaticTreeNode
<
Key
,
Value
>*
const
&
left
,
ChromaticTreeNode
<
Key
,
Value
>*
const
&
right
);
const
ChildPointer
&
left
,
const
ChildPointer
&
right
);
/**
* Creates a node given only a key-value pair. Node will have no child nodes
...
...
@@ -71,14 +74,6 @@ class ChromaticTreeNode {
ChromaticTreeNode
(
const
Key
&
key
,
const
Value
&
value
,
const
int
weight
=
1
);
/**
* Creates a copy of a given node.
*
* \param[IN] other Node to be copied
*/
ChromaticTreeNode
(
const
ChromaticTreeNode
&
other
);
/**
* Accessor for the stored key.
*
* \return Stored key
...
...
@@ -104,21 +99,31 @@ class ChromaticTreeNode {
*
* \return Reference to the left child pointer
*/
ChromaticTreeNode
<
Key
,
Value
>*
&
GetLeft
();
AtomicChildPointer
&
GetLeft
();
/**
* Accessor for the right child pointer.
*
* \return Reference to the right child pointer
*/
ChromaticTreeNode
<
Key
,
Value
>*&
GetRight
();
AtomicChildPointer
&
GetRight
();
void
Retire
()
{
retired_
=
true
;
}
bool
IsRetired
()
const
{
return
retired_
;
}
embb
::
base
::
Mutex
&
GetMutex
()
{
return
mutex_
;
}
private
:
const
Key
key_
;
/**< Stored key */
const
Value
value_
;
/**< Stored value */
const
int
weight_
;
/**< Weight of the node */
ChromaticTreeNode
<
Key
,
Value
>*
left_
;
/**< Pointer to left child node */
ChromaticTreeNode
<
Key
,
Value
>*
right_
;
/**< Pointer to right child node */
ChromaticTreeNode
(
const
ChromaticTreeNode
&
);
ChromaticTreeNode
&
operator
=
(
const
ChromaticTreeNode
&
);
const
Key
key_
;
/**< Stored key */
const
Value
value_
;
/**< Stored value */
const
int
weight_
;
/**< Weight of the node */
AtomicChildPointer
left_
;
/**< Pointer to left child node */
AtomicChildPointer
right_
;
/**< Pointer to right child node */
embb
::
base
::
Atomic
<
bool
>
retired_
;
embb
::
base
::
Mutex
mutex_
;
};
}
// namespace internal
...
...
@@ -215,7 +220,7 @@ class ChromaticTree {
* \param[IN] value New value to be inserted
*
* \return \c true if the given key-value pair was successfully inserted into
* the tree, \c false if tree has reached its capacity
* the tree, \c false if t
he t
ree has reached its capacity
*/
bool
TryInsert
(
const
Key
&
key
,
const
Value
&
value
);
...
...
@@ -232,7 +237,7 @@ class ChromaticTree {
* tree for the given key
*
* \return \c true if the given key-value pair was successfully inserted into
* the tree, \c false if tree has reached its capacity
* the tree, \c false if t
he t
ree has reached its capacity
*/
bool
TryInsert
(
const
Key
&
key
,
const
Value
&
value
,
Value
&
old_value
);
...
...
@@ -242,7 +247,7 @@ class ChromaticTree {
* \param[IN] key Key to be removed
*
* \return \c true if the given key-value pair was successfully deleted from
* the tree, \c false if the
given key was not stored in the tree
* the tree, \c false if the
tree is out of memory
*/
bool
TryDelete
(
const
Key
&
key
);
...
...
@@ -256,7 +261,7 @@ class ChromaticTree {
* tree for the given key
*
* \return \c true if the given key-value pair was successfully deleted from
* the tree, \c false if the
given key was not stored in the tree
* the tree, \c false if the
tree is out of memory
*/
bool
TryDelete
(
const
Key
&
key
,
Value
&
old_value
);
...
...
@@ -291,8 +296,14 @@ class ChromaticTree {
* Typedef for a pointer to a node of the tree.
*/
typedef
internal
::
ChromaticTreeNode
<
Key
,
Value
>*
NodePtr
;
/**
* Typedef for an atomic pointer to a node of the tree.
*/
typedef
embb
::
base
::
Atomic
<
NodePtr
>
AtomicNodePtr
;
typedef
embb
::
base
::
UniqueLock
<
embb
::
base
::
Mutex
>
UniqueLock
;
/**
* Follows a path from the root of the tree to some leaf searching for the
* given key (the leaf found by this method may or may not contain the given
...
...
@@ -301,7 +312,7 @@ class ChromaticTree {
* \param[IN] key Key to be searched for
* \param[IN,OUT] leaf Reference to the reached leaf
*/
void
Search
(
const
Key
&
key
,
NodePtr
&
leaf
)
const
;
void
Search
(
const
Key
&
key
,
NodePtr
&
leaf
);
/**
* Follows a path from the root of the tree to some leaf searching for the
...
...
@@ -312,7 +323,7 @@ class ChromaticTree {
* \param[IN,OUT] leaf Reference to the reached leaf
* \param[IN,OUT] parent Reference to the parent of the reached leaf
*/
void
Search
(
const
Key
&
key
,
NodePtr
&
leaf
,
NodePtr
&
parent
)
const
;
void
Search
(
const
Key
&
key
,
NodePtr
&
leaf
,
NodePtr
&
parent
);
/**
* Follows a path from the root of the tree to some leaf searching for the
...
...
@@ -325,7 +336,7 @@ class ChromaticTree {
* \param[IN,OUT] grandparent Reference to the grandparent of the reached leaf
*/
void
Search
(
const
Key
&
key
,
NodePtr
&
leaf
,
NodePtr
&
parent
,
NodePtr
&
grandparent
)
const
;
NodePtr
&
grandparent
);
/**
* Checks whether the given node is a leaf.
...
...
@@ -376,7 +387,8 @@ class ChromaticTree {
* \return Reference to a member pointer of the \c parent that points to
* the \c child
*/
NodePtr
&
GetPointerToChild
(
const
NodePtr
&
parent
,
const
NodePtr
&
child
)
const
;
AtomicNodePtr
&
GetPointerToChild
(
const
NodePtr
&
parent
,
const
NodePtr
&
child
)
const
;
/**
* Destroys all the nodes of a subtree rooted at the given node, including the
...
...
@@ -387,13 +399,39 @@ class ChromaticTree {
* \param node Root of the subtree to be destroyed
*/
void
Destruct
(
const
NodePtr
&
node
);
/**
* Computes the hight of the subtree rooted at the given node.
*
* \notthreadsafe
*
* \param[IN] node Root of the subtree for which the height is requested
*
* \return The height of a subtree rooted at node \c node. (The height of a
* leaf node is defined to be zero).
*/
int
GetHeight
(
const
NodePtr
&
node
)
const
;
bool
IsBalanced
()
const
;
bool
IsBalanced
(
const
NodePtr
&
node
)
const
;
void
RemoveNode
(
const
NodePtr
&
node
)
{
node_hazard_manager_
.
EnqueuePointerForDeletion
(
node
);
}
/**
* Free a tree node by returning it to the node pool.
*
* \param[IN] node A node to be freed.
*/
void
FreeNode
(
NodePtr
node
);
/**
* Follows the path from the root to some leaf (directed by the given key) and
* checks for any tree balancing violations. If a violation is found, tries
* to fix it by using a set of rebalancing rotations.
*
* \param key Key to be searched for
* \param
[IN]
key Key to be searched for
*
* \return \c true if the tree was successfully rebalanced, \c false otherwise
*/
...
...
@@ -412,76 +450,16 @@ class ChromaticTree {
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxxl
,
const
NodePtr
&
uxxr
,
const
bool
&
uxx_is_right
);
bool
BLK
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
);
bool
PUSH_L
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
);
bool
PUSH_R
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
);
bool
RB1_L
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
);
bool
RB1_R
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxr
);
bool
RB2_L
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxlr
);
bool
RB2_R
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxrl
);
bool
W1_L
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxrl
);
bool
W1_R
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxlr
);
bool
W2_L
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxrl
);
bool
W2_R
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxlr
);
bool
W3_L
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxrl
,
const
NodePtr
&
uxrll
);
bool
W3_R
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxlr
,
const
NodePtr
&
uxlrr
);
bool
W4_L
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxrl
,
const
NodePtr
&
uxrlr
);
bool
W4_R
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxlr
,
const
NodePtr
&
uxlrl
);
bool
W5_L
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxrr
);
bool
W5_R
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxll
);
bool
W6_L
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxrl
);
bool
W6_R
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
,
const
NodePtr
&
uxlr
);
bool
W7
(
const
NodePtr
&
u
,
const
NodePtr
&
ux
,
const
NodePtr
&
uxl
,
const
NodePtr
&
uxr
);
/**
* Friending the test class for white-box testing
*/
friend
class
test
::
TreeTest
<
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>
>
;
/**
* Computes the hight of the subtree rooted at the given node.
*
* \notthreadsafe
*
* \param[IN] node Root of the subtree for which the height is requested
*
* \return The height of a subtree rooted at node \c node. (The height of a
* leaf node is defined to be zero).
*/
int
GetHeight
(
const
NodePtr
&
node
)
const
;
bool
IsBalanced
()
const
;
bool
IsBalanced
(
const
NodePtr
&
node
)
const
;
// The following included header contains the class methods implementing
// tree rotations. It is generated automatically and must be included
// directly inside the class definition.
# include <embb/containers/internal/lock_free_chromatic_tree-rebalance.h>
/** Callback functor for the hazard pointer that frees retired nodes */
embb
::
base
::
Function
<
void
,
NodePtr
>
free_node_callback_
;
/** Hazard pointer instance for protection of node pointers */
embb
::
containers
::
internal
::
HazardPointer
<
NodePtr
>
node_hazard_manager_
;
const
Key
undefined_key_
;
/**< A dummy key used by the tree */
const
Value
undefined_value_
;
/**< A dummy value used by the tree */
...
...
@@ -491,11 +469,10 @@ class ChromaticTree {
NodePtr
entry_
;
/**< Pointer to the sentinel node used as
* the entry point into the tree */
typedef
embb
::
base
::
ReadWriteLock
::
Reader
ReadWriteLockReader
;
typedef
embb
::
base
::
ReadWriteLock
::
Writer
ReadWriteLockWriter
;
typedef
embb
::
base
::
LockGuard
<
ReadWriteLockReader
>
ReaderLockGuard
;
typedef
embb
::
base
::
LockGuard
<
ReadWriteLockWriter
>
WriterLockGuard
;
embb
::
base
::
ReadWriteLock
readwrite_lock_
;
/**
* Friending the test class for white-box testing
*/
friend
class
test
::
TreeTest
<
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>
>
;
};
}
// namespace containers
...
...
containers_cpp/test/tree_test-inl.h
View file @
871b5391
...
...
@@ -66,11 +66,11 @@ TreeTest<Tree>::TreeTest()
Add
(
&
TreeTest
::
TreeTestConcurrentGet_ReaderMethod
,
this
,
NUM_TEST_THREADS
/
2
,
NUM_ITERATIONS
).
Post
(
&
TreeTest
::
TreeTestConcurrentGet_Post
,
this
);
CreateUnit
(
"TreeTestBalance"
).
Pre
(
&
TreeTest
::
TreeTestBalance_Pre
,
this
).
Add
(
&
TreeTest
::
TreeTestBalance_ThreadMethod
,
this
,
NUM_TEST_THREADS
,
1
).
Post
(
&
TreeTest
::
TreeTestBalance_Post
,
this
);
//
CreateUnit("TreeTestBalance").
//
Pre(&TreeTest::TreeTestBalance_Pre, this).
//
Add(&TreeTest::TreeTestBalance_ThreadMethod, this,
//
NUM_TEST_THREADS, 1).
//
Post(&TreeTest::TreeTestBalance_Post, this);
}
template
<
typename
Tree
>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment