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
acb6cf6b
authored
May 18, 2015
by
Danila Klimenko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chromatic_tree: updated documentation, fixed test cases for MSVC
parent
2f75565c
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
355 additions
and
77 deletions
+355
-77
containers_cpp/include/embb/containers/internal/lock_free_chromatic_tree-inl.h
+139
-3
containers_cpp/include/embb/containers/lock_free_chromatic_tree.h
+208
-72
containers_cpp/test/tree_test-inl.h
+8
-2
No files found.
containers_cpp/include/embb/containers/internal/lock_free_chromatic_tree-inl.h
View file @
acb6cf6b
...
@@ -90,6 +90,132 @@ ChromaticTreeNode<Key, Value>::GetRight() {
...
@@ -90,6 +90,132 @@ ChromaticTreeNode<Key, Value>::GetRight() {
return
right_
;
return
right_
;
}
}
template
<
typename
Key
,
typename
Value
>
void
ChromaticTreeNode
<
Key
,
Value
>::
Retire
()
{
retired_
=
true
;
}
template
<
typename
Key
,
typename
Value
>
bool
ChromaticTreeNode
<
Key
,
Value
>::
IsRetired
()
const
{
return
retired_
;
}
template
<
typename
Key
,
typename
Value
>
embb
::
base
::
Mutex
&
ChromaticTreeNode
<
Key
,
Value
>::
GetMutex
()
{
return
mutex_
;
}
template
<
typename
GuardedType
>
UniqueHazardPointer
<
GuardedType
>::
UniqueHazardPointer
()
:
hazard_guard_
(
NULL
),
undefined_guard_
(
NULL
),
active_
(
false
)
{}
template
<
typename
GuardedType
>
UniqueHazardPointer
<
GuardedType
>::
UniqueHazardPointer
(
AtomicGuard
&
hazard_guard
,
GuardedPtr
undefined_guard
)
:
hazard_guard_
(
&
hazard_guard
),
undefined_guard_
(
undefined_guard
),
active_
(
LoadGuardedPointer
()
==
undefined_guard_
)
{}
template
<
typename
GuardedType
>
UniqueHazardPointer
<
GuardedType
>::
~
UniqueHazardPointer
()
{
if
(
IsActive
())
ClearHazard
();
}
template
<
typename
GuardedType
>
bool
UniqueHazardPointer
<
GuardedType
>::
ProtectHazard
(
const
AtomicGuard
&
hazard
)
{
assert
(
OwnsHazardGuard
());
// Read the hazard and store it into the guard
StoreGuardedPointer
(
hazard
.
Load
());
// Check whether the guard is valid
SetActive
(
LoadGuardedPointer
()
==
hazard
.
Load
());
// Clear the guard if it is invalid
if
(
!
IsActive
())
ClearHazard
();
return
IsActive
();
}
template
<
typename
GuardedType
>
UniqueHazardPointer
<
GuardedType
>::
operator
GuardedPtr
()
const
{
assert
(
IsActive
());
return
LoadGuardedPointer
();
}
template
<
typename
GuardedType
>
typename
UniqueHazardPointer
<
GuardedType
>::
GuardedPtr
UniqueHazardPointer
<
GuardedType
>::
operator
->
()
const
{
assert
(
IsActive
());
return
LoadGuardedPointer
();
}
template
<
typename
GuardedType
>
GuardedType
&
UniqueHazardPointer
<
GuardedType
>::
operator
*
()
const
{
assert
(
IsActive
());
return
*
(
LoadGuardedPointer
());
}
template
<
typename
GuardedType
>
void
UniqueHazardPointer
<
GuardedType
>::
AdoptGuard
(
const
UniqueHazardPointer
<
GuardedType
>&
other
)
{
assert
(
OwnsHazardGuard
());
StoreGuardedPointer
(
other
.
LoadGuardedPointer
());
SetActive
(
other
.
active_
);
}
template
<
typename
GuardedType
>
void
UniqueHazardPointer
<
GuardedType
>::
Swap
(
UniqueHazardPointer
<
GuardedType
>&
other
)
{
std
::
swap
(
hazard_guard_
,
other
.
hazard_guard_
);
std
::
swap
(
undefined_guard_
,
other
.
undefined_guard_
);
std
::
swap
(
active_
,
other
.
active_
);
}
template
<
typename
GuardedType
>
typename
UniqueHazardPointer
<
GuardedType
>::
GuardedPtr
UniqueHazardPointer
<
GuardedType
>::
ReleaseHazard
()
{
assert
(
IsActive
());
GuardedPtr
released_hazard
=
LoadGuardedPointer
();
ClearHazard
();
SetActive
(
false
);
return
released_hazard
;
}
template
<
typename
GuardedType
>
bool
UniqueHazardPointer
<
GuardedType
>::
IsActive
()
const
{
return
active_
;
}
template
<
typename
GuardedType
>
void
UniqueHazardPointer
<
GuardedType
>::
SetActive
(
bool
active
)
{
active_
=
active
;
}
template
<
typename
GuardedType
>
void
UniqueHazardPointer
<
GuardedType
>::
ClearHazard
()
{
StoreGuardedPointer
(
undefined_guard_
);
}
template
<
typename
GuardedType
>
typename
UniqueHazardPointer
<
GuardedType
>::
GuardedPtr
UniqueHazardPointer
<
GuardedType
>::
LoadGuardedPointer
()
const
{
return
hazard_guard_
->
Load
();
}
template
<
typename
GuardedType
>
void
UniqueHazardPointer
<
GuardedType
>::
StoreGuardedPointer
(
GuardedPtr
ptr
)
{
hazard_guard_
->
Store
(
ptr
);
}
template
<
typename
GuardedType
>
bool
UniqueHazardPointer
<
GuardedType
>::
OwnsHazardGuard
()
const
{
return
hazard_guard_
!=
NULL
;
}
}
// namespace internal
}
// namespace internal
...
@@ -314,7 +440,7 @@ TryDelete(const Key& key, Value& old_value) {
...
@@ -314,7 +440,7 @@ TryDelete(const Key& key, Value& old_value) {
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
size_t
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
size_t
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
GetCapacity
()
{
GetCapacity
()
const
{
return
capacity_
;
return
capacity_
;
}
}
...
@@ -326,8 +452,9 @@ GetUndefinedValue() {
...
@@ -326,8 +452,9 @@ GetUndefinedValue() {
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
bool
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
bool
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
IsEmpty
()
{
IsEmpty
()
const
{
return
IsLeaf
(
entry_
->
GetLeft
());
NodePtr
entry
=
entry_
;
//Bug: "operator->()" is not const in AtomicPointer<>
return
IsLeaf
(
entry
->
GetLeft
());
}
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
...
@@ -466,6 +593,15 @@ IsBalanced(const NodePtr& node) const {
...
@@ -466,6 +593,15 @@ IsBalanced(const NodePtr& node) const {
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
void
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
void
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
RetireHazardousNode
(
HazardNodePtr
&
node
,
UniqueLock
&
node_lock
)
{
node
->
Retire
();
node_lock
.
Unlock
();
NodePtr
node_to_delete
=
node
.
ReleaseHazard
();
node_hazard_manager_
.
EnqueuePointerForDeletion
(
node_to_delete
);
}
template
<
typename
Key
,
typename
Value
,
typename
Compare
,
typename
NodePool
>
void
ChromaticTree
<
Key
,
Value
,
Compare
,
NodePool
>::
FreeNode
(
NodePtr
node
)
{
FreeNode
(
NodePtr
node
)
{
#ifdef EMBB_DEBUG
#ifdef EMBB_DEBUG
node
->
GetLeft
()
=
reinterpret_cast
<
NodePtr
>
(
INVALID_POINTER
);
node
->
GetLeft
()
=
reinterpret_cast
<
NodePtr
>
(
INVALID_POINTER
);
...
...
containers_cpp/include/embb/containers/lock_free_chromatic_tree.h
View file @
acb6cf6b
...
@@ -110,90 +110,206 @@ class ChromaticTreeNode {
...
@@ -110,90 +110,206 @@ class ChromaticTreeNode {
*/
*/
AtomicChildPointer
&
GetRight
();
AtomicChildPointer
&
GetRight
();
void
Retire
()
{
retired_
=
true
;
}
/**
bool
IsRetired
()
const
{
return
retired_
;
}
* Marks node for deletion from the tree
embb
::
base
::
Mutex
&
GetMutex
()
{
return
mutex_
;
}
*/
void
Retire
();
/**
* Checks whether the node is marked for deletion from the tree
*
* \return \c true if node is retired, \c false otherwise
*/
bool
IsRetired
()
const
;
/**
* Accessor for the FGL mutex
*
* \return Reference to this node's mutex
*/
embb
::
base
::
Mutex
&
GetMutex
();
private
:
private
:
/**
* Disable copy construction and assignment.
*/
ChromaticTreeNode
(
const
ChromaticTreeNode
&
);
ChromaticTreeNode
(
const
ChromaticTreeNode
&
);
ChromaticTreeNode
&
operator
=
(
const
ChromaticTreeNode
&
);
ChromaticTreeNode
&
operator
=
(
const
ChromaticTreeNode
&
);
const
Key
key_
;
/**< Stored key */
const
Key
key_
;
/**< Stored key */
const
Value
value_
;
/**< Stored value */
const
Value
value_
;
/**< Stored value */
const
int
weight_
;
/**< Weight of the node */
const
int
weight_
;
/**< Weight of the node */
AtomicChildPointer
left_
;
/**< Pointer to left child node */
AtomicChildPointer
left_
;
/**< Pointer to left child node */
AtomicChildPointer
right_
;
/**< Pointer to right child node */
AtomicChildPointer
right_
;
/**< Pointer to right child node */
embb
::
base
::
Atomic
<
bool
>
retired_
;
/**< Retired (marked for deletion) flag */
embb
::
base
::
Atomic
<
bool
>
retired_
;
embb
::
base
::
Mutex
mutex_
;
embb
::
base
::
Mutex
mutex_
;
/**< Fine-grained locking tree: per node mutex */
};
};
/**
* Ownership wrapper for a hazard pointer
*
* Uses an entry of the hazard table to provide protection for a single
* hazardous pointer. While providing standard pointer dereference and member
* access operators, it requires special care for pointer assignment (realized
* via 'ProtectHazard' method).
* On destruction, it clears the wrapped hazard table entry, releasing the
* protected hazardous pointer (if any).
*
* \tparam GuardedType Type of the object to be protected by the hazard pointer
*/
template
<
typename
GuardedType
>
template
<
typename
GuardedType
>
class
UniqueHazard
Guard
{
class
UniqueHazard
Pointer
{
public
:
public
:
typedef
embb
::
base
::
Atomic
<
GuardedType
>
AtomicGuard
;
/**
* Typedef for a pointer to the guarded object.
*/
typedef
GuardedType
*
GuardedPtr
;
/**
* Typedef for a atomic pointer to the guarded object.
*/
typedef
embb
::
base
::
Atomic
<
GuardedPtr
>
AtomicGuard
;
UniqueHazardGuard
(
AtomicGuard
&
guard
,
const
GuardedType
&
undefined_guard
)
/**
:
guard_
(
guard
),
* Creates an uninitialized, empty wrapper.
undefined_guard_
(
undefined_guard
),
*
active_
(
guard_
.
Load
()
==
undefined_guard_
)
{}
* An uninitialized wrapper may only be swapped with another wrapper (using
* \c Swap() method) or checked for being active (using 'IsActive()' method,
* which should always return /c false for an uninitialized wrapper).
*/
UniqueHazardPointer
();
~
UniqueHazardGuard
()
{
/**
if
(
active_
)
SetUndefinedGuard
();
* Creates a wrapper that uses the given hazard table entry (referred to as
}
* "guard") to protect hazardous pointers.
*
* \param[IN] hazard_guard Reference to a hazard table entry
* \param[IN] undefined_guard Dummy value used to clear the hazard table entry
*/
explicit
UniqueHazardPointer
(
AtomicGuard
&
hazard_guard
,
GuardedPtr
undefined_guard
=
NULL
);
bool
ProtectHazard
(
const
AtomicGuard
&
hazard
)
{
/**
// Read the hazard and store it into the guard
* If initialized and active, clears the hazard table entry.
guard_
=
hazard
.
Load
();
*/
~
UniqueHazardPointer
();
// Check whether the guard is valid
/**
active_
=
(
guard_
.
Load
()
==
hazard
.
Load
());
* Tries to protect the given hazard using the wrapped hazard pointer (guard).
* If it succeeds, the hazard may be safely dereferenced as long as the guard
* is not destroyed or reset to protect another hazard.
*
* \param hazard The hazard to be protected
* \return \c true if the specified hazard is now protected by the guard,
* \c false if the hazard was modified by a concurrent thread
*/
bool
ProtectHazard
(
const
AtomicGuard
&
hazard
);
// Clear the guard if it is invalid
/**
if
(
!
active_
)
SetUndefinedGuard
();
* Type cast operator.
*
* \return The hazardous pointer protected by this wrapper
*/
operator
GuardedPtr
()
const
;
return
active_
;
/**
}
* Pointer member access operator.
*
* \return The hazardous pointer protected by this wrapper
*/
GuardedPtr
operator
->
()
const
;
bool
IsActive
()
const
{
/**
return
active_
;
* Pointer dereference operator.
}
*
* \return Reference to the object pointed to by the protected pointer
*/
GuardedType
&
operator
*
()
const
;
operator
GuardedType
()
const
{
/**
assert
(
active_
==
true
);
* Protects the hazard that is currently protected by another wrapper (so it
return
guard_
.
Load
();
* becomes protected by two guards simultaneously). The other wrapper remains
}
* unmodified.
*
* \param other Another wrapper those protected pointer is to be protected by
* the calling wrapper
*/
void
AdoptGuard
(
const
UniqueHazardPointer
<
GuardedType
>&
other
);
GuardedType
operator
->
()
const
{
/**
assert
(
active_
==
true
);
* Swaps the guard ownership with another wrapper. Swaps not just the
return
guard_
.
Load
();
* protected hazards, but the hazard guards themselves.
}
*
* \param other Another wrapper to swap guards with
*/
void
Swap
(
UniqueHazardPointer
<
GuardedType
>&
other
);
void
AdoptGuard
(
const
UniqueHazardGuard
<
GuardedType
>&
other
)
{
/**
guard_
=
other
.
guard_
.
Load
();
* Clears the hazard guard and returns the hazard previously protected by that
active_
=
other
.
active_
;
* guard.
}
*
* \return The hazardous pointer previously protected by this wrapper
*/
GuardedPtr
ReleaseHazard
();
GuardedType
ReleaseHazard
()
{
/**
assert
(
active_
==
true
);
* Check whether the wrapper is active.
GuardedType
released_hazard
=
guard_
.
Load
();
*
SetUndefinedGuard
();
* \return \c true if the wrapper is initialized and currently protecting some
active_
=
false
;
* hazard, \c false otherwise
return
released_hazard
;
*/
}
bool
IsActive
()
const
;
private
:
private
:
void
SetUndefinedGuard
()
{
/**
guard_
=
undefined_guard_
;
* Sets the 'active' flag of this wrapper.
}
*
* \param active The new value for the flag
*/
void
SetActive
(
bool
active
);
/**
* Reset the wrapped hazard guard to a state when it is not protecting any
* hazards.
*/
void
ClearHazard
();
// Non-copyable
/**
UniqueHazardGuard
(
const
UniqueHazardGuard
<
GuardedType
>&
);
* Retrieves the hazardous pointer currently protected by the wrapped guard.
UniqueHazardGuard
<
GuardedType
>&
*
operator
=
(
const
UniqueHazardGuard
<
GuardedType
>&
);
* \return The hazardous pointer protected by this wrapper
*/
GuardedPtr
LoadGuardedPointer
()
const
;
/**
* Updates the wrapped guard to protect the specified hazardous pointer.
*
* \param ptr Hazardous pointer to be protected
*/
void
StoreGuardedPointer
(
GuardedPtr
ptr
);
/**
* Check whether the wrapper is initialized (i.e. it wraps some hazard guard)
*
* \return \c true if this wrapper is initialized, \c false otherwise
*/
bool
OwnsHazardGuard
()
const
;
AtomicGuard
&
guard_
;
/**
GuardedType
undefined_guard_
;
* Disable copy construction and assignment.
*/
UniqueHazardPointer
(
const
UniqueHazardPointer
&
);
UniqueHazardPointer
&
operator
=
(
const
UniqueHazardPointer
&
);
/**
* Pointer to a hazard table entry (the guard) that is used to store the
* hazardous pointers
*/
AtomicGuard
*
hazard_guard_
;
/** Dummy value used to clear the hazard guard from any hazards */
GuardedPtr
undefined_guard_
;
/** Flag set to true when the guard is protecting some hazardous pointer */
bool
active_
;
bool
active_
;
};
};
...
@@ -318,7 +434,7 @@ class ChromaticTree {
...
@@ -318,7 +434,7 @@ class ChromaticTree {
* \param[IN] key Key to be removed
* \param[IN] key Key to be removed
*
*
* \return \c true if the given key-value pair was successfully deleted from
* \return \c true if the given key-value pair was successfully deleted from
* the tree, \c false if the
tree is out of
memory
* the tree, \c false if the
re is not enough
memory
*/
*/
bool
TryDelete
(
const
Key
&
key
);
bool
TryDelete
(
const
Key
&
key
);
...
@@ -332,7 +448,7 @@ class ChromaticTree {
...
@@ -332,7 +448,7 @@ class ChromaticTree {
* tree for the given key
* tree for the given key
*
*
* \return \c true if the given key-value pair was successfully deleted from
* \return \c true if the given key-value pair was successfully deleted from
* the tree, \c false if the
tree is out of
memory
* the tree, \c false if the
re is not enough
memory
*/
*/
bool
TryDelete
(
const
Key
&
key
,
Value
&
old_value
);
bool
TryDelete
(
const
Key
&
key
,
Value
&
old_value
);
...
@@ -342,7 +458,7 @@ class ChromaticTree {
...
@@ -342,7 +458,7 @@ class ChromaticTree {
*
*
* \return Number of key-value pairs the tree can store
* \return Number of key-value pairs the tree can store
*/
*/
size_t
GetCapacity
()
;
size_t
GetCapacity
()
const
;
/**
/**
* Accessor for the dummy value used by the tree
* Accessor for the dummy value used by the tree
...
@@ -356,7 +472,7 @@ class ChromaticTree {
...
@@ -356,7 +472,7 @@ class ChromaticTree {
*
*
* \return \c true if the tree stores no key-value pairs, \c false otherwise
* \return \c true if the tree stores no key-value pairs, \c false otherwise
*/
*/
bool
IsEmpty
()
;
bool
IsEmpty
()
const
;
private
:
private
:
/**
/**
...
@@ -371,8 +487,13 @@ class ChromaticTree {
...
@@ -371,8 +487,13 @@ class ChromaticTree {
* Typedef for an atomic pointer to a node of the tree.
* Typedef for an atomic pointer to a node of the tree.
*/
*/
typedef
embb
::
base
::
Atomic
<
NodePtr
>
AtomicNodePtr
;
typedef
embb
::
base
::
Atomic
<
NodePtr
>
AtomicNodePtr
;
/**
typedef
internal
::
UniqueHazardGuard
<
NodePtr
>
HazardNodePtr
;
* Typedef for an pointer to a node protected by a Hazard Pointer.
*/
typedef
internal
::
UniqueHazardPointer
<
Node
>
HazardNodePtr
;
/**
* Typedef for the UniqueLock class.
*/
typedef
embb
::
base
::
UniqueLock
<
embb
::
base
::
Mutex
>
UniqueLock
;
typedef
embb
::
base
::
UniqueLock
<
embb
::
base
::
Mutex
>
UniqueLock
;
...
@@ -474,15 +595,30 @@ class ChromaticTree {
...
@@ -474,15 +595,30 @@ class ChromaticTree {
*/
*/
int
GetHeight
(
const
NodePtr
&
node
)
const
;
int
GetHeight
(
const
NodePtr
&
node
)
const
;
/**
* Check whether the tree is currently in a balanced state (if it is a valid
* red-black tree).
*
* \return \c true if the tree is balanced, \c false otherwise
*/
bool
IsBalanced
()
const
;
bool
IsBalanced
()
const
;
/**
* Check whether a subtree rooted at the given node is balanced.
*
* \param[IN] node Root of the subtree for which the balance is checked
*
* \return \c true if the tree is balanced, \c false otherwise
*/
bool
IsBalanced
(
const
NodePtr
&
node
)
const
;
bool
IsBalanced
(
const
NodePtr
&
node
)
const
;
void
RetireHazardousNode
(
HazardNodePtr
&
node
,
UniqueLock
&
node_lock
)
{
/**
node
->
Retire
();
* Free a tree node using the Hazard Pointers memory reclamation routines.
node_lock
.
Unlock
();
*
NodePtr
node_to_delete
=
node
.
ReleaseHazard
();
* \param[IN] node A node to be freed.
node_hazard_manager_
.
EnqueuePointerForDeletion
(
node_to_delete
);
* \param[IN] node_lock A lock holding the mutex of the \c node to be freed.
}
*/
void
RetireHazardousNode
(
HazardNodePtr
&
node
,
UniqueLock
&
node_lock
);
/**
/**
* Free a tree node by returning it to the node pool.
* Free a tree node by returning it to the node pool.
...
...
containers_cpp/test/tree_test-inl.h
View file @
acb6cf6b
...
@@ -127,7 +127,8 @@ void TreeTest<Tree>::Worker::
...
@@ -127,7 +127,8 @@ void TreeTest<Tree>::Worker::
ReplaceHalf
()
{
ReplaceHalf
()
{
// Replace some of the elements that were inserted earlier
// Replace some of the elements that were inserted earlier
::
std
::
random_shuffle
(
elements_
.
begin
(),
elements_
.
end
());
::
std
::
random_shuffle
(
elements_
.
begin
(),
elements_
.
end
());
ElementIterator
elements_middle
=
elements_
.
begin
()
+
elements_
.
size
()
/
2
;
ElementIterator
elements_middle
=
elements_
.
begin
()
+
static_cast
<
ptrdiff_t
>
(
elements_
.
size
()
/
2
);
for
(
ElementIterator
it
=
elements_
.
begin
();
it
!=
elements_middle
;
++
it
)
{
for
(
ElementIterator
it
=
elements_
.
begin
();
it
!=
elements_middle
;
++
it
)
{
Value
old_value
;
Value
old_value
;
Value
expected
=
it
->
second
;
Value
expected
=
it
->
second
;
...
@@ -166,7 +167,8 @@ void TreeTest<Tree>::Worker::
...
@@ -166,7 +167,8 @@ void TreeTest<Tree>::Worker::
DeleteHalf
()
{
DeleteHalf
()
{
// Delete half of the elements from the tree
// Delete half of the elements from the tree
::
std
::
random_shuffle
(
elements_
.
begin
(),
elements_
.
end
());
::
std
::
random_shuffle
(
elements_
.
begin
(),
elements_
.
end
());
ElementIterator
elements_middle
=
elements_
.
begin
()
+
elements_
.
size
()
/
2
;
ElementIterator
elements_middle
=
elements_
.
begin
()
+
static_cast
<
ptrdiff_t
>
(
elements_
.
size
()
/
2
);
for
(
ElementIterator
it
=
elements_
.
begin
();
it
!=
elements_middle
;
++
it
)
{
for
(
ElementIterator
it
=
elements_
.
begin
();
it
!=
elements_middle
;
++
it
)
{
Value
old_value
;
Value
old_value
;
Value
expected
=
it
->
second
;
Value
expected
=
it
->
second
;
...
@@ -179,6 +181,7 @@ DeleteHalf() {
...
@@ -179,6 +181,7 @@ DeleteHalf() {
template
<
typename
Tree
>
template
<
typename
Tree
>
void
TreeTest
<
Tree
>::
void
TreeTest
<
Tree
>::
TreeTestInsertDelete_Pre
()
{
TreeTestInsertDelete_Pre
()
{
embb_internal_thread_index_reset
();
tree_
=
new
Tree
(
TREE_CAPACITY
,
bad_key_
,
bad_value_
);
tree_
=
new
Tree
(
TREE_CAPACITY
,
bad_key_
,
bad_value_
);
}
}
...
@@ -220,6 +223,7 @@ TreeTestInsertDelete_Post() {
...
@@ -220,6 +223,7 @@ TreeTestInsertDelete_Post() {
template
<
typename
Tree
>
template
<
typename
Tree
>
void
TreeTest
<
Tree
>::
void
TreeTest
<
Tree
>::
TreeTestConcurrentGet_Pre
()
{
TreeTestConcurrentGet_Pre
()
{
embb_internal_thread_index_reset
();
tree_
=
new
Tree
(
TREE_CAPACITY
/
2
,
bad_key_
,
bad_value_
);
tree_
=
new
Tree
(
TREE_CAPACITY
/
2
,
bad_key_
,
bad_value_
);
ElementVector
elements
;
ElementVector
elements
;
...
@@ -242,6 +246,7 @@ TreeTestConcurrentGet_Pre() {
...
@@ -242,6 +246,7 @@ TreeTestConcurrentGet_Pre() {
template
<
typename
Tree
>
template
<
typename
Tree
>
void
TreeTest
<
Tree
>::
void
TreeTest
<
Tree
>::
TreeTestConcurrentGetMinimal_Pre
()
{
TreeTestConcurrentGetMinimal_Pre
()
{
embb_internal_thread_index_reset
();
tree_
=
new
Tree
(
NUM_TEST_THREADS
/
2
,
bad_key_
,
bad_value_
);
tree_
=
new
Tree
(
NUM_TEST_THREADS
/
2
,
bad_key_
,
bad_value_
);
for
(
int
i
=
0
;
i
<
NUM_TEST_THREADS
/
2
;
++
i
)
{
for
(
int
i
=
0
;
i
<
NUM_TEST_THREADS
/
2
;
++
i
)
{
...
@@ -300,6 +305,7 @@ TreeTestConcurrentGet_Post() {
...
@@ -300,6 +305,7 @@ TreeTestConcurrentGet_Post() {
template
<
typename
Tree
>
template
<
typename
Tree
>
void
TreeTest
<
Tree
>::
void
TreeTest
<
Tree
>::
TreeTestBalance_Pre
()
{
TreeTestBalance_Pre
()
{
embb_internal_thread_index_reset
();
tree_
=
new
Tree
(
TREE_CAPACITY
,
bad_key_
,
bad_value_
);
tree_
=
new
Tree
(
TREE_CAPACITY
,
bad_key_
,
bad_value_
);
}
}
...
...
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