A Junction map is a lot like a big array of `std::atomic<>` variables, where the key is an index into the array. More precisely:
* All of a Junction map's member functions, together with its `Mutator` member functions, are atomic with respect to each other, so you can safely call them from any thread without mutual exclusion.
-* If an `set` [happens before](http://preshing.com/20130702/the-happens-before-relation/) a `get` with the same key, the `get` will return the value set, except if another operation changes the value in between. Any [synchronizing operation](http://preshing.com/20130823/the-synchronizes-with-relation/) will establish this relationship.
-* For Linear, Leapfrog and Grampa maps, `set` is a [release](http://preshing.com/20120913/acquire-and-release-semantics/) operation and `get` is a [consume](http://preshing.com/20140709/the-purpose-of-memory_order_consume-in-cpp11/) operation, so you can safely pass non-atomic information between threads using a pointer. For Crude maps, all operations are relaxed.
-* In the current version, you must not set while concurrently using an `Iterator`.
+* If an `assign` [happens before](http://preshing.com/20130702/the-happens-before-relation/) a `get` with the same key, the `get` will return the value it inserted, except if another operation changes the value in between. Any [synchronizing operation](http://preshing.com/20130823/the-synchronizes-with-relation/) will establish this relationship.
+* For Linear, Leapfrog and Grampa maps, `assign` is a [release](http://preshing.com/20120913/acquire-and-release-semantics/) operation and `get` is a [consume](http://preshing.com/20140709/the-purpose-of-memory_order_consume-in-cpp11/) operation, so you can safely pass non-atomic information between threads using a pointer. For Crude maps, all operations are relaxed.
+* In the current version, you must not `assign` while concurrently using an `Iterator`.
## Feedback
delete[] m_cells;
}
- void set(Key key, Value value) {
+ void assign(Key key, Value value) {
TURF_ASSERT(key != KeyTraits::NullKey);
TURF_ASSERT(value != Value(ValueTraits::NullValue));
}
}
- void setValue(Value desired) {
+ void assignValue(Value desired) {
exchangeValue(desired);
}
}
}
- Value set(Key key, Value desired) {
+ Value assign(Key key, Value desired) {
Mutator iter(*this, key);
return iter.exchangeValue(desired);
}
}
}
- void setValue(Value desired) {
+ void assignValue(Value desired) {
exchangeValue(desired);
}
}
}
- Value set(Key key, Value desired) {
+ Value assign(Key key, Value desired) {
Mutator iter(*this, key);
return iter.exchangeValue(desired);
}
}
}
- void setValue(Value desired) {
+ void assignValue(Value desired) {
exchangeValue(desired);
}
}
}
- Value set(Key key, Value desired) {
+ Value assign(Key key, Value desired) {
Mutator iter(*this, key);
return iter.exchangeValue(desired);
}
return iter.isValid() ? iter.getValue() : NULL;
}
- Value set(const Key& key, Value desired) {
+ Value assign(const Key& key, Value desired) {
Mutator iter(*this, key);
return iter.exchangeValue(desired);
}
Map(ureg capacity) : m_map() {
}
- void set(u32 key, void* value) {
+ void assign(u32 key, void* value) {
m_map.insert(key, value);
}
Map(ureg capacity) : m_map(capacity, 1) {
}
- void set(u32 key, void* value) {
+ void assign(u32 key, void* value) {
m_map.insert(key, value);
}
Map(ureg capacity) : m_map(capacity) {
}
- void set(u32 key, void* value) {
+ void assign(u32 key, void* value) {
m_map.insert(std::make_pair(key, value));
}
Map(ureg capacity) : m_map(capacity) {
}
- void set(u32 key, void* value) {
+ void assign(u32 key, void* value) {
m_map.insert(key, value);
}
Map(ureg capacity) : m_map(capacity) {
}
- void set(u32 key, void* value) {
+ void assign(u32 key, void* value) {
turf::LockGuard<turf::Mutex> guard(m_mutex);
- m_map.set(key, value);
+ m_map.assign(key, value);
}
void* get(u32 key) {
Map(ureg capacity) : m_map(capacity) {
}
- void set(u32 key, void* value) {
+ void assign(u32 key, void* value) {
turf::ExclusiveLockGuard<turf::RWLock> guard(m_rwLock);
- m_map.set(key, value);
+ m_map.assign(key, value);
}
void* get(u32 key) {
ht_free(m_map);
}
- void set(u32 key, void* value) {
+ void assign(u32 key, void* value) {
ht_cas(m_map, key, CAS_EXPECT_WHATEVER, (map_val_t) value);
}
Map(ureg) {
}
- void set(u32, void*) {
+ void assign(u32, void*) {
}
void* get(u32) {
Map(ureg) {
}
- void set(u32 key, void* value) {
+ void assign(u32 key, void* value) {
std::lock_guard<std::mutex> guard(m_mutex);
m_map[key] = value;
}
Map(ureg capacity) : m_map(capacity) {
}
- void set(u32 key, void* value) {
+ void assign(u32 key, void* value) {
m_map.insert(std::make_pair(key, value));
}
Map(ureg capacity) : m_map(capacity, 3) {
}
- void set(u32 key, void* value) {
+ void assign(u32 key, void* value) {
m_map.insert(key, (u64) value);
}
std::cout << "Population=" << population << ", inUse=" << TURF_HEAP.getInUseBytes() << std::endl;
#endif
for (; population < i * 5000; population++)
- map.set(population + 1, (void*) ((population << 2) | 3));
+ map.assign(population + 1, (void*) ((population << 2) | 3));
}
return 0;
u32 key = thread.insertIndex * m_relativePrime;
key = key ^ (key >> 16);
if (key >= 2) {
- m_map.set(key, (void*) uptr(key));
+ m_map.assign(key, (void*) uptr(key));
}
if (++thread.insertIndex >= thread.rangeHi)
thread.insertIndex = thread.rangeLo;
u32 key = thread.insertIndex * m_relativePrime;
key = key ^ (key >> 16);
if (key >= 2) {
- m_map.set(key, (void*) uptr(key));
+ m_map.assign(key, (void*) uptr(key));
}
if (++thread.insertIndex >= thread.rangeHi)
thread.insertIndex = thread.rangeLo;
u32 key = index * m_relativePrime;
key = key ^ (key >> 16);
if (key >= 2) { // Don't insert 0 or 1
- m_map->set(key, (void*) uptr(key));
+ m_map->assign(key, (void*) uptr(key));
keysRemaining--;
}
index++;
u32 key = index * m_relativePrime;
key = key ^ (key >> 16);
if (key >= 2) { // Don't insert 0 or 1
- m_map->set(key, (void*) uptr(key));
+ m_map->assign(key, (void*) uptr(key));
keysRemaining--;
}
index++;
if (threadIndex == 0) {
// We store 2 because Junction maps reserve 1 for the default Redirect value.
// The default can be overridden, but this is easier.
- m_map.set(x, (void*) 2);
+ m_map.assign(x, (void*) 2);
m_r1 = (uptr) m_map.get(y);
} else {
- m_map.set(y, (void*) 2);
+ m_map.assign(y, (void*) 2);
m_r2 = (uptr) m_map.get(x);
}
}
case 0:
// We store 2 because Junction maps reserve 1 for the default Redirect value.
// The default can be overridden, but this is easier.
- m_map.set(x, (void*) 2);
+ m_map.assign(x, (void*) 2);
break;
case 1:
- m_map.set(y, (void*) 2);
+ m_map.assign(y, (void*) 2);
break;
case 2:
MapAdapter::Map* map = m_shared.map;
for (ureg i = 0; i < m_shared.numKeysPerThread; i++) {
u32 key = m_addIndex * Prime;
- map->set(key, (void*) (key & ~uptr(3)));
+ map->assign(key, (void*) (key & ~uptr(3)));
if (++m_addIndex == m_rangeHi)
m_addIndex = m_rangeLo;
}
break;
u32 key = m_addIndex * Prime;
if (key >= 2) {
- map->set(key, (void*) uptr(key));
+ map->assign(key, (void*) uptr(key));
stats.mapOpsDone++;
}
if (++m_addIndex == m_rangeHi)
for (ureg i = 0; i < m_shared.numKeysPerThread; i++) {
u32 key = m_addIndex * Prime;
if (key >= 2)
- map->set(key, (void*) uptr(key));
+ map->assign(key, (void*) uptr(key));
if (++m_addIndex == m_rangeHi)
m_addIndex = m_rangeLo;
}
break;
u32 key = m_addIndex * Prime;
if (key >= 2) {
- map->set(key, (void*) uptr(key));
+ map->assign(key, (void*) uptr(key));
stats.mapOpsDone++;
}
if (++m_addIndex == m_rangeHi)