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 if (entries[i].value)
delete entries[i].value;
169 for (
size_t i = 0; i <
_oldTables.size(); ++i) {
193 return ((TableHeader*)
_table)->size;
198 const TableHeader* header;
199 const Entry* entries;
201 uint32_t mask = header->numEntries-1;
202 uint32_t hash = key.hash();
205 for (uint32_t i = hash;; ++i) {
206 const Entry& e = entries[i & mask];
219 Value
tryInsert(Key& key, Value value,
size_t& newMemUsed)
225 uint32_t mask = header->numEntries-1;
226 uint32_t hash = key.hash();
229 for (uint32_t i = hash;; ++i) {
230 Entry& e = entries[i & mask];
249 template <
typename Fn>
250 void foreach(Fn& fn)
const
252 const TableHeader* header;
253 const Entry* entries;
255 for (uint32_t i = 0; i < header->numEntries; ++i) {
256 Value v = entries[i].value;
264 memsize =
sizeof(TableHeader) +
sizeof(Entry) * numEntries;
265 void* table = malloc(memsize);
266 memset(table, 0, memsize);
267 TableHeader* header = (TableHeader*) table;
268 header->numEntries = numEntries;
273 static void getTable(
const void* table,
const TableHeader*& header,
const Entry*& entries)
275 header = (
const TableHeader*) table;
276 entries = (
const Entry*)((
const char*)table +
sizeof(TableHeader));
279 static void getTable(
void* table, TableHeader*& header, Entry*& entries)
281 header = (TableHeader*) table;
282 entries = (Entry*)((
char*)table +
sizeof(TableHeader));
299 if (header->size*2 >= header->numEntries) {
300 table =
grow(table, newMemUsed);
305 void*
grow(
void* oldTable,
size_t& newMemUsed)
307 TableHeader* oldHeader;
309 getTable(oldTable, oldHeader, oldEntries);
312 void* newTable =
allocTable(oldHeader->numEntries*2, newMemUsed);
313 TableHeader* newHeader;
315 getTable(newTable, newHeader, newEntries);
316 uint32_t mask = newHeader->numEntries-1;
317 for (uint32_t oldIndex = 0; oldIndex < oldHeader->numEntries; ++oldIndex) {
318 Entry& oldEntry = oldEntries[oldIndex];
319 if (oldEntry.value) {
320 for (
int newIndex = oldEntry.key.
hash();; ++newIndex) {
321 Entry& newEntry = newEntries[newIndex&mask];
322 if (!newEntry.value) {
323 newEntry.key.
move(oldEntry.key);
324 newEntry.value = oldEntry.value;
330 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)