50inline bool memCompare(
const char* a,
const char* b,
int len)
54 for (
int i = 0; i < len64; i+=8) {
55 memcpy(&val64[0], &a[i], 8);
56 memcpy(&val64[1], &b[i], 8);
57 if (val64[0] != val64[1])
return 1;
59 return memcmp(&a[len64], &b[len64], len & 7);
78 _len = uint16_t(strlen(val));
79 _hash = uint32_t(std::hash<std::string_view>{}(std::string_view(
_val,
_len)));
87 char* newval =
new char[key.
_len+1];
88 memcpy(newval, key.
_val, key.
_len+1);
128 uint32_t
hash()
volatile const {
return (
_val*7919) & ~0xf; }
131template <
typename Key,
typename Value>
165 for (uint32_t i = 0; i < header->numEntries; ++i) {
166 entries[i].key.~Key();
167 if (entries[i].value)
delete entries[i].value;
170 for (
size_t i = 0; i <
_oldTables.size(); ++i) {
194 return ((TableHeader*)
_table)->size;
199 const TableHeader* header;
200 const Entry* entries;
202 uint32_t mask = header->numEntries-1;
203 uint32_t hash = key.hash();
206 for (uint32_t i = hash;; ++i) {
207 const Entry& e = entries[i & mask];
220 Value
tryInsert(Key& key, Value value,
size_t& newMemUsed)
226 uint32_t mask = header->numEntries-1;
227 uint32_t hash = key.hash();
230 for (uint32_t i = hash;; ++i) {
231 Entry& e = entries[i & mask];
250 template <
typename Fn>
251 void foreach(Fn& fn)
const
253 const TableHeader* header;
254 const Entry* entries;
256 for (uint32_t i = 0; i < header->numEntries; ++i) {
257 Value v = entries[i].value;
265 memsize =
sizeof(TableHeader) +
sizeof(Entry) * numEntries;
266 void* table = malloc(memsize);
267 memset(table, 0, memsize);
268 TableHeader* header =
new (table) TableHeader;
269 header->numEntries = numEntries;
271 Entry* entries = (Entry*)((
char*)table +
sizeof(TableHeader));
272 for (int32_t i = 0; i < numEntries; ++i)
274 new (&entries[i]) Entry();
279 static void getTable(
const void* table,
const TableHeader*& header,
const Entry*& entries)
281 header = (
const TableHeader*) table;
282 entries = (
const Entry*)((
const char*)table +
sizeof(TableHeader));
285 static void getTable(
void* table, TableHeader*& header, Entry*& entries)
287 header = (TableHeader*) table;
288 entries = (Entry*)((
char*)table +
sizeof(TableHeader));
305 if (header->size*2 >= header->numEntries) {
306 table =
grow(table, newMemUsed);
311 void*
grow(
void* oldTable,
size_t& newMemUsed)
313 TableHeader* oldHeader;
315 getTable(oldTable, oldHeader, oldEntries);
318 void* newTable =
allocTable(oldHeader->numEntries*2, newMemUsed);
319 TableHeader* newHeader;
321 getTable(newTable, newHeader, newEntries);
322 uint32_t mask = newHeader->numEntries-1;
323 for (uint32_t oldIndex = 0; oldIndex < oldHeader->numEntries; ++oldIndex) {
324 Entry& oldEntry = oldEntries[oldIndex];
325 if (oldEntry.value) {
326 for (
int newIndex = oldEntry.key.
hash();; ++newIndex) {
327 Entry& newEntry = newEntries[newIndex&mask];
328 if (!newEntry.value) {
329 newEntry.key.
move(oldEntry.key);
330 newEntry.value = oldEntry.value;
336 newHeader->size = oldHeader->size;
PTEX_NAMESPACE_BEGIN bool memCompare(const char *a, const char *b, int len)
#define PTEX_NAMESPACE_END
bool matches(const IntKey &key) const volatile
void copy(volatile IntKey &key) volatile
uint32_t hash() volatile const
void move(volatile IntKey &key) volatile
bool isEmpty() volatile const
void operator=(const Entry &)
static void getTable(const void *table, const TableHeader *&header, const Entry *&entries)
void * allocTable(int32_t numEntries, size_t &memsize)
void * grow(void *oldTable, size_t &newMemUsed)
PtexHashMap(const PtexHashMap &)
std::vector< void * > _oldTables
void unlockTable(void *table)
Value get(Key &key) const
static void getTable(void *table, TableHeader *&header, Entry *&entries)
void * lockTableAndGrowIfNeeded(size_t &newMemUsed)
void operator=(const PtexHashMap &)
Value tryInsert(Key &key, Value value, size_t &newMemUsed)
bool isEmpty() const volatile
StringKey(const char *val)
uint16_t volatile _ownsVal
uint32_t hash() const volatile
bool matches(const StringKey &key) const volatile
const char *volatile _val
void operator=(const StringKey &key)
void move(volatile StringKey &key) volatile
void copy(volatile StringKey &key) volatile
StringKey(const StringKey &key)