+/* STON DHT API
+ Primary functions for creating hashtables, retrieving pointers to values,
+ iterating over all keys and values, and destroying hashtables. */
+STON_FUNC
+ston_dht ston_dht_new(uint16_t,uint8_t,void*(*)(size_t),void(*)(void*));
+STON_FUNC
+void* ston_dht_val(ston_dht,void*);
+STON_FUNC
+ston_dht ston_dht_free(ston_dht);
+STON_FUNC
+void ston_dht_iterate(ston_dht,void(*)(void*,void*,void*),void*);
+/* Recursive functions intended to be called by other functions, above */
+STON_FUNC_STATIC
+STON_FUNC_NOINLINE
+void ston_dht_free_bucket(ston_dht,void*);
+STON_FUNC_STATIC
+STON_FUNC_NOINLINE
+void ston_dht_iterate_r(ston_dht,void*);
+// Compatibility macros - Deprecated
+#define ston_dht32_new(_COL,_ALOC,_FRE) (ston_dht_new(4 * _COL, 4, _ALOC, _FRE))
+#define ston_dht32_row(_HT,_K) ((uint32_t*)((uint8_t*)ston_dht_val(_HT,&(_K)) - 4))
+#define ston_dht32_insertx(_HT,_K,_VP,_OFFS,_N) \
+ memcpy((uint32_t*)((uint8_t*)ston_dht_val(_HT,&(_K)) + ((_OFFS - 1) * 4)),_VP,_N * 4)
+
+/* New dynamic hashtable, provided value bytes, key bytes, allocator function,
+ and free function. Value bytes and key bytes are respectively constrained to
+ uint16 and uint8 so they can be aligned to hashtables encoded for
+ streaming */
+STON_FUNC
+ston_dht ston_dht_new
+( uint16_t val_bytes,
+ uint8_t key_bytes,
+ void* (*ht_alloc)(size_t),
+ void (*ht_free)(void*)
+)
+{ ston_dht ht = (ston_dht) ht_alloc(sizeof(struct ston_dht_t));
+ if (ht != NULL)
+ { ht->header.val_bytes = val_bytes;
+ ht->header.key_bytes = key_bytes;
+ ht->rowsize = sizeof(void*) + key_bytes + val_bytes;
+ ht->bucketsize = ht->rowsize * 0x100;
+ ht->ht_alloc = ht_alloc;
+ ht->ht_free = ht_free;
+ ht->bucket_root = ht_alloc(ht->bucketsize);
+ if (ht->bucket_root == NULL && ht_free != NULL)
+ ht_free(ht);
+ else
+ memset((ht->bucket_root), 0, ht->bucketsize);
+ }
+ return ht;
+}
+