1 /*------------------------------------------------------------------------
2 Junction: Concurrent data structures in C++
3 Copyright (c) 2016 Jeff Preshing
5 Distributed under the Simplified BSD License.
6 Original location: https://github.com/preshing/junction
8 This software is distributed WITHOUT ANY WARRANTY; without even the
9 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 See the LICENSE file for more information.
11 ------------------------------------------------------------------------*/
13 #ifndef SAMPLES_MAPCORRECTNESSTESTS_TESTINSERTDIFFERENTKEYS_H
14 #define SAMPLES_MAPCORRECTNESSTESTS_TESTINSERTDIFFERENTKEYS_H
16 #include <junction/Core.h>
17 #include "TestEnvironment.h"
18 #include <turf/extra/Random.h>
20 class TestInsertDifferentKeys {
22 static const ureg KeysToInsert = 2048;
23 TestEnvironment& m_env;
24 MapAdapter::Map* m_map;
25 turf::extra::Random m_random;
29 TestInsertDifferentKeys(TestEnvironment& env) : m_env(env), m_map(NULL), m_startIndex(0), m_relativePrime(0) {
32 void insertKeys(ureg threadIndex) {
33 u32 index = m_startIndex + threadIndex * (KeysToInsert + 2);
34 sreg keysRemaining = KeysToInsert;
35 while (keysRemaining > 0) {
36 u32 key = index * m_relativePrime;
37 key = key ^ (key >> 16);
38 if (key >= 2) { // Don't insert 0 or 1
39 m_map->assign(key, (void*) uptr(key));
44 m_env.threads[threadIndex].update();
47 void eraseKeys(ureg threadIndex) {
48 u32 index = m_startIndex + threadIndex * (KeysToInsert + 2);
49 sreg keysRemaining = KeysToInsert;
50 while (keysRemaining > 0) {
51 u32 key = index * m_relativePrime;
52 key = key ^ (key >> 16);
53 if (key >= 2) { // Don't insert 0 or 1
59 m_env.threads[threadIndex].update();
62 void checkMapContents() {
63 #if TEST_CHECK_MAP_CONTENTS
65 ureg iterChecksum = 0;
66 for (MapAdapter::Map::Iterator iter(*m_map); iter.isValid(); iter.next()) {
68 u32 key = iter.getKey();
70 if (iter.getValue() != (void*) uptr(key))
74 ureg actualChecksum = 0;
75 for (ureg i = 0; i < m_env.numThreads; i++) {
76 u32 index = m_startIndex + i * (KeysToInsert + 2);
77 sreg leftToCheck = KeysToInsert;
78 while (leftToCheck > 0) {
79 u32 key = index * m_relativePrime;
80 key = key ^ (key >> 16);
81 if (key >= 2) { // Don't insert 0 or 1
82 if (m_map->get(key) != (void*) uptr(key))
84 actualChecksum += key;
91 if (iterCount != KeysToInsert * m_env.numThreads)
93 if (iterChecksum != actualChecksum)
98 void checkMapEmpty() {
99 #if TEST_CHECK_MAP_CONTENTS
100 for (MapAdapter::Map::Iterator iter(*m_map); iter.isValid(); iter.next()) {
104 for (ureg i = 0; i < m_env.numThreads; i++) {
105 u32 index = m_startIndex + i * (KeysToInsert + 2);
106 sreg leftToCheck = KeysToInsert;
107 while (leftToCheck > 0) {
108 u32 key = index * m_relativePrime;
109 key = key ^ (key >> 16);
110 if (key >= 2) { // Don't insert 0 or 1
118 #endif // TEST_CHECK_MAP_CONTENTS
122 m_map = new MapAdapter::Map(MapAdapter::getInitialCapacity(KeysToInsert));
123 m_startIndex = m_random.next32();
124 m_relativePrime = m_random.next32() * 2 + 1;
125 m_env.dispatcher.kick(&TestInsertDifferentKeys::insertKeys, *this);
127 m_env.dispatcher.kick(&TestInsertDifferentKeys::eraseKeys, *this);
134 #endif // SAMPLES_MAPCORRECTNESSTESTS_TESTINSERTDIFFERENTKEYS_H