Add lazy init to array/hash, rename 64bit max num, minor bug fixes
This commit is contained in:
		
							parent
							
								
									964304d1b7
								
							
						
					
					
						commit
						9d12c532d1
					
				| @ -206,27 +206,27 @@ void Dqn_Test() | |||||||
|     // i64 to str
 |     // i64 to str
 | ||||||
|     if (1) |     if (1) | ||||||
|     { |     { | ||||||
|         char a[DQN_64BIT_NUM_MAX_STR_SIZE] = {}; |         char a[DQN_I64_MAX_STR_SIZE] = {}; | ||||||
|         Dqn_I64ToStr(+100, a, DQN_ARRAY_COUNT(a)); |         Dqn_I64ToStr(+100, a, DQN_ARRAY_COUNT(a)); | ||||||
|         DQN_ASSERT(DqnStr_Cmp(a, "100") == 0); |         DQN_ASSERT(DqnStr_Cmp(a, "100") == 0); | ||||||
| 
 | 
 | ||||||
|         char b[DQN_64BIT_NUM_MAX_STR_SIZE] = {}; |         char b[DQN_I64_MAX_STR_SIZE] = {}; | ||||||
|         Dqn_I64ToStr(-100, b, DQN_ARRAY_COUNT(b)); |         Dqn_I64ToStr(-100, b, DQN_ARRAY_COUNT(b)); | ||||||
|         DQN_ASSERT(DqnStr_Cmp(b, "-100") == 0); |         DQN_ASSERT(DqnStr_Cmp(b, "-100") == 0); | ||||||
| 
 | 
 | ||||||
|         char c[DQN_64BIT_NUM_MAX_STR_SIZE] = {}; |         char c[DQN_I64_MAX_STR_SIZE] = {}; | ||||||
|         Dqn_I64ToStr(0, c, DQN_ARRAY_COUNT(c)); |         Dqn_I64ToStr(0, c, DQN_ARRAY_COUNT(c)); | ||||||
|         DQN_ASSERT(DqnStr_Cmp(c, "0") == 0); |         DQN_ASSERT(DqnStr_Cmp(c, "0") == 0); | ||||||
| 
 | 
 | ||||||
| #if 0 | #if 0 | ||||||
|             char d[DQN_64BIT_NUM_MAX_STR_SIZE] = {}; |             char d[DQN_I64_MAX_STR_SIZE] = {}; | ||||||
|             Dqn_I64ToStr(LARGEST_NUM, d, DQN_ARRAY_COUNT(d)); |             Dqn_I64ToStr(LARGEST_NUM, d, DQN_ARRAY_COUNT(d)); | ||||||
|             DQN_ASSERT(DqnStr_Cmp(d, "18446744073709551615") == 0); |             DQN_ASSERT(DqnStr_Cmp(d, "18446744073709551615") == 0); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|         if (sizeof(size_t) == sizeof(u64)) |         if (sizeof(size_t) == sizeof(u64)) | ||||||
|         { |         { | ||||||
|             char e[DQN_64BIT_NUM_MAX_STR_SIZE] = {}; |             char e[DQN_I64_MAX_STR_SIZE] = {}; | ||||||
|             Dqn_I64ToStr(SMALLEST_NUM, e, DQN_ARRAY_COUNT(e)); |             Dqn_I64ToStr(SMALLEST_NUM, e, DQN_ARRAY_COUNT(e)); | ||||||
|             DQN_ASSERTM(DqnStr_Cmp(e, "-9223372036854775808") == 0, "e: %s", e); |             DQN_ASSERTM(DqnStr_Cmp(e, "-9223372036854775808") == 0, "e: %s", e); | ||||||
|         } |         } | ||||||
|  | |||||||
							
								
								
									
										90
									
								
								dqn.h
									
									
									
									
									
								
							
							
						
						
									
										90
									
								
								dqn.h
									
									
									
									
									
								
							| @ -122,9 +122,9 @@ using b32 = i32; | |||||||
| using f64 = double; | using f64 = double; | ||||||
| using f32 = float; | using f32 = float; | ||||||
| 
 | 
 | ||||||
| #define DQN_F32_MIN   -FLT_MAX; | #define DQN_F32_MIN   -FLT_MAX | ||||||
| #define DQN_I64_MAX  INT64_MAX; | #define DQN_I64_MAX  INT64_MAX | ||||||
| #define DQN_U64_MAX UINT64_MAX; | #define DQN_U64_MAX UINT64_MAX | ||||||
| 
 | 
 | ||||||
| #define DQN_TERABYTE(val) (DQN_GIGABYTE(val) * 1024LL) | #define DQN_TERABYTE(val) (DQN_GIGABYTE(val) * 1024LL) | ||||||
| 
 | 
 | ||||||
| @ -150,6 +150,7 @@ using f32 = float; | |||||||
| #define DQN_DEGREES_TO_RADIANS(x) ((x * (DQN_PI / 180.0f))) | #define DQN_DEGREES_TO_RADIANS(x) ((x * (DQN_PI / 180.0f))) | ||||||
| #define DQN_RADIANS_TO_DEGREES(x) ((x * (180.0f / DQN_PI))) | #define DQN_RADIANS_TO_DEGREES(x) ((x * (180.0f / DQN_PI))) | ||||||
| 
 | 
 | ||||||
|  | #define DQN_CLAMP(value, min, max) DQN_MIN(DQN_MAX(value, min), max) | ||||||
| #define DQN_MAX(a, b) ((a) < (b) ? (b) : (a)) | #define DQN_MAX(a, b) ((a) < (b) ? (b) : (a)) | ||||||
| #define DQN_MIN(a, b) ((a) < (b) ? (a) : (b)) | #define DQN_MIN(a, b) ((a) < (b) ? (a) : (b)) | ||||||
| #define DQN_SWAP(type, a, b) do { type tmp = a; a = b; b = tmp; } while(0) | #define DQN_SWAP(type, a, b) do { type tmp = a; a = b; b = tmp; } while(0) | ||||||
| @ -832,8 +833,8 @@ DQN_FILE_SCOPE inline DqnSlice<char> DqnStr_RemoveLeadTrailQuotes (char const *s | |||||||
| DQN_FILE_SCOPE inline DqnSlice<char> DqnStr_RemoveLeadTrailBraces (char const *str, i32 strLen); | DQN_FILE_SCOPE inline DqnSlice<char> DqnStr_RemoveLeadTrailBraces (char const *str, i32 strLen); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| #define DQN_32BIT_NUM_MAX_STR_SIZE 11 | #define DQN_I32_MAX_STR_SIZE 11 | ||||||
| #define DQN_64BIT_NUM_MAX_STR_SIZE 21 | #define DQN_I64_MAX_STR_SIZE 21 | ||||||
| // Return the len of the derived string. If buf is nullptr and or bufSize is 0 the function returns the
 | // Return the len of the derived string. If buf is nullptr and or bufSize is 0 the function returns the
 | ||||||
| // required string length for the integer
 | // required string length for the integer
 | ||||||
| // TODO NOTE(doyle): Parsing stops when a non-digit is encountered, so numbers with ',' don't work atm.
 | // TODO NOTE(doyle): Parsing stops when a non-digit is encountered, so numbers with ',' don't work atm.
 | ||||||
| @ -1324,7 +1325,7 @@ struct DqnArray | |||||||
|     ~DqnArray        ()                                           { if (this->data && this->memAPI) this->memAPI->Free(data); } |     ~DqnArray        ()                                           { if (this->data && this->memAPI) this->memAPI->Free(data); } | ||||||
| 
 | 
 | ||||||
|     void  UseMemory  (T *data_, isize max_, isize count_ = 0)     { this->memAPI = nullptr; this->data = data_; this->max = max_; this->count = count_; } |     void  UseMemory  (T *data_, isize max_, isize count_ = 0)     { this->memAPI = nullptr; this->data = data_; this->max = max_; this->count = count_; } | ||||||
|     void  Clear      (Dqn::ZeroClear clear = Dqn::ZeroClear::Yes) { if (data) { count = 0; if (clear == Dqn::ZeroClear::Yes) DqnMem_Clear(data, 0, sizeof(T) * max); } } |     void  Clear      (Dqn::ZeroClear clear = Dqn::ZeroClear::No)  { if (data) { count = 0; if (clear == Dqn::ZeroClear::Yes) DqnMem_Clear(data, 0, sizeof(T) * max); } } | ||||||
|     void  Free       ()                                           { if (data) { memAPI->Free(data); } *this = {}; } |     void  Free       ()                                           { if (data) { memAPI->Free(data); } *this = {}; } | ||||||
|     T    *Front      ()                                           { DQN_ASSERT(count > 0); return data + 0; } |     T    *Front      ()                                           { DQN_ASSERT(count > 0); return data + 0; } | ||||||
|     T    *Back       ()                                           { DQN_ASSERT(count > 0); return data + (count - 1); } |     T    *Back       ()                                           { DQN_ASSERT(count > 0); return data + (count - 1); } | ||||||
| @ -2333,25 +2334,6 @@ int DqnFixedString<MAX>::SprintfAppend(char const *fmt, ...) | |||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template <typename Key> using DqnVHashTableHashingProc = isize(*)(isize count, Key const &data); |  | ||||||
| template <typename Key> using DqnVHashTableEqualsProc  = bool (*)(Key const &a, Key const &b); |  | ||||||
| 
 |  | ||||||
| #define DQN_VHASH_TABLE_HASHING_PROC(name) template <typename Key> inline isize name(isize count, Key const &key) |  | ||||||
| DQN_VHASH_TABLE_HASHING_PROC(DqnVHashTableDefaultHash) |  | ||||||
| { |  | ||||||
|     const u64 SEED = 0x9747B28CAB3F8A7B; |  | ||||||
|     u64 index64    = DqnHash_Murmur64Seed(&key, sizeof(key), SEED); |  | ||||||
|     isize result   = index64 % count; |  | ||||||
|     return result; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #define DQN_VHASH_TABLE_EQUALS_PROC(name) template <typename Key> inline bool name(Key const &a, Key const &b) |  | ||||||
| DQN_VHASH_TABLE_EQUALS_PROC(DqnVHashTableDefaultEquals) |  | ||||||
| { |  | ||||||
|     bool result = (DqnMem_Cmp(&a, &b, sizeof(a)) == 0); |  | ||||||
|     return result; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // TODO(doyle): Load factor
 | // TODO(doyle): Load factor
 | ||||||
| // #DqnHashTable API
 | // #DqnHashTable API
 | ||||||
| // =================================================================================================
 | // =================================================================================================
 | ||||||
| @ -2914,22 +2896,25 @@ struct DqnVArray | |||||||
|     isize  max;     // Read
 |     isize  max;     // Read
 | ||||||
|     T     *data;    // Read
 |     T     *data;    // Read
 | ||||||
| 
 | 
 | ||||||
|      DqnVArray       ()                                           { count = 0; max = DQN_MEGABYTE(1) / sizeof(T); data = (T *)DqnOS_VAlloc(max * sizeof(T)); DQN_ASSERT(data); } |           DqnVArray  () = default; | ||||||
|     ~DqnVArray       ()                                           { if (data)   DqnOS_VFree(data, sizeof(T) * max); } |           DqnVArray  (isize size)                                 { LazyInit(size); } | ||||||
|     void  Clear      (Dqn::ZeroClear clear = Dqn::ZeroClear::Yes) { if (data) { count = 0; if (clear == Dqn::ZeroClear::Yes) DqnMem_Clear(data, 0, sizeof(T) * max); } } |     void  LazyInit   (isize size)                                 { if (data) return; count = 0; max = size; data = (T *)DqnOS_VAlloc(max * sizeof(T)); DQN_ALWAYS_ASSERT(data); } | ||||||
|  |          ~DqnVArray  ()                                           { if (data) DqnOS_VFree(data, sizeof(T) * max); } | ||||||
|  | 
 | ||||||
|  |     void  Clear      (Dqn::ZeroClear clear = Dqn::ZeroClear::No)  { if (data) { count = 0; if (clear == Dqn::ZeroClear::Yes) DqnMem_Clear(data, 0, sizeof(T) * max); } } | ||||||
|     void  Free       ()                                           { if (data) { DqnOS_VFree(data, sizeof(T) * max); } *this = {}; } |     void  Free       ()                                           { if (data) { DqnOS_VFree(data, sizeof(T) * max); } *this = {}; } | ||||||
|     T    *Front      ()                                           { DQN_ASSERT(count > 0); return data + 0; } |     T    *Front      ()                                           { return (count > 0) (data + 0)           : nullptr; } | ||||||
|     T    *Back       ()                                           { DQN_ASSERT(count > 0); return data + (count - 1); } |     T    *Back       ()                                           { return (count > 0) (data + (count - 1)) : nullptr; } | ||||||
|     T    *Make       (isize num = 1)                              { count += num; DQN_ASSERT(count < max); return &data[count - num]; } |     T    *Make       (isize num = 1)                              { LazyInit(1024); count += num; DQN_ASSERT(count < max); return &data[count - num]; } | ||||||
|     T    *Push       (T const &v)                                 { return Insert(count, &v, 1); } |     T    *Push       (T const &v)                                 { return Insert(count, &v, 1); } | ||||||
|     T    *Push       (T const *v, isize numItems = 1)             { return Insert(count,  v, numItems); } |     T    *Push       (T const *v, isize numItems = 1)             { return Insert(count,  v, numItems); } | ||||||
|     void  Pop        ()                                           { if (count > 0) count--; } |     void  Pop        ()                                           { if (count > 0) count--; } | ||||||
|     void  Erase      (isize index)                                { DQN_ASSERT(index >= 0 && index < count); data[index] = data[--count]; } |     void  Erase      (isize index)                                { if (!data) return; DQN_ASSERT(index >= 0 && index < count); data[index] = data[--count]; } | ||||||
|     void  EraseStable(isize index); |     void  EraseStable(isize index); | ||||||
|     T    *Insert     (isize index, T const *v)                    { return Insert(index,  v, 1); } |     T    *Insert     (isize index, T const *v)                    { return Insert(index,  v, 1); } | ||||||
|     T    *Insert     (isize index, T const &v)                    { return Insert(index, &v, 1); } |     T    *Insert     (isize index, T const &v)                    { return Insert(index, &v, 1); } | ||||||
|     T    *Insert     (isize index, T const *v, isize numItems); |     T    *Insert     (isize index, T const *v, isize numItems); | ||||||
|     bool  Contains   (T const *v) const                           { T const *ptr = data;  T const *end = data + count; while (ptr < end) if (*ptr++ == *v) return true; return false; } |     bool  Contains   (T const *v) const                           { T const *ptr = data;  T const *end = data + count; while (ptr < end) { if (*ptr++ == *v) return true; } return false; } | ||||||
| 
 | 
 | ||||||
|     T    &operator[] (isize i) const                              { DQN_ASSERT(i < count && i > 0); return this->data[i]; } |     T    &operator[] (isize i) const                              { DQN_ASSERT(i < count && i > 0); return this->data[i]; } | ||||||
|     T    *begin      ()                                           { return data; } |     T    *begin      ()                                           { return data; } | ||||||
| @ -2938,7 +2923,9 @@ struct DqnVArray | |||||||
| 
 | 
 | ||||||
| template<typename T> T *DqnVArray<T>::Insert(isize index, T const *v, isize numItems) | template<typename T> T *DqnVArray<T>::Insert(isize index, T const *v, isize numItems) | ||||||
| { | { | ||||||
|     index                = DQN_MIN(DQN_MAX(index, 0), count); |     LazyInit(1024); | ||||||
|  | 
 | ||||||
|  |     index                = DQN_CLAMP(index, 0, count); | ||||||
|     isize const newCount = count + numItems; |     isize const newCount = count + numItems; | ||||||
|     DQN_ASSERT(newCount < max); |     DQN_ASSERT(newCount < max); | ||||||
| 
 | 
 | ||||||
| @ -2957,6 +2944,7 @@ template<typename T> T *DqnVArray<T>::Insert(isize index, T const *v, isize numI | |||||||
| 
 | 
 | ||||||
| template <typename T> void DqnVArray<T>::EraseStable(isize index) | template <typename T> void DqnVArray<T>::EraseStable(isize index) | ||||||
| { | { | ||||||
|  |     if (!data) return; | ||||||
|     DQN_ASSERT(index >= 0 && index < count); |     DQN_ASSERT(index >= 0 && index < count); | ||||||
|     isize const off = (data + index) - data; |     isize const off = (data + index) - data; | ||||||
|     memmove(data + off, data + off + 1, ((usize)count - (usize)off - 1) * sizeof(T)); |     memmove(data + off, data + off + 1, ((usize)count - (usize)off - 1) * sizeof(T)); | ||||||
| @ -2965,6 +2953,25 @@ template <typename T> void DqnVArray<T>::EraseStable(isize index) | |||||||
| 
 | 
 | ||||||
| // #XPlatform > #DqnVHashTable API
 | // #XPlatform > #DqnVHashTable API
 | ||||||
| // =================================================================================================
 | // =================================================================================================
 | ||||||
|  | template <typename Key> using DqnVHashTableHashingProc = isize(*)(isize count, Key const &data); | ||||||
|  | template <typename Key> using DqnVHashTableEqualsProc  = bool (*)(Key const &a, Key const &b); | ||||||
|  | 
 | ||||||
|  | #define DQN_VHASH_TABLE_HASHING_PROC(name) template <typename Key> inline isize name(isize count, Key const &key) | ||||||
|  | DQN_VHASH_TABLE_HASHING_PROC(DqnVHashTableDefaultHash) | ||||||
|  | { | ||||||
|  |     const u64 SEED = 0x9747B28CAB3F8A7B; | ||||||
|  |     u64 index64    = DqnHash_Murmur64Seed(&key, sizeof(key), SEED); | ||||||
|  |     isize result   = index64 % count; | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #define DQN_VHASH_TABLE_EQUALS_PROC(name) template <typename Key> inline bool name(Key const &a, Key const &b) | ||||||
|  | DQN_VHASH_TABLE_EQUALS_PROC(DqnVHashTableDefaultEquals) | ||||||
|  | { | ||||||
|  |     bool result = (DqnMem_Cmp(&a, &b, sizeof(a)) == 0); | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| #define DQN_VHASH_TABLE_TEMPLATE                                                                   \ | #define DQN_VHASH_TABLE_TEMPLATE                                                                   \ | ||||||
|     template <typename Key,                                                                        \ |     template <typename Key,                                                                        \ | ||||||
|               typename Item,                                                                       \ |               typename Item,                                                                       \ | ||||||
| @ -2992,22 +2999,21 @@ DQN_VHASH_TABLE_TEMPLATE struct DqnVHashTable | |||||||
|     isize      bucketsUsed; |     isize      bucketsUsed; | ||||||
| 
 | 
 | ||||||
|      DqnVHashTable() = default; |      DqnVHashTable() = default; | ||||||
|      DqnVHashTable(isize size) { LazyInitialise(size); } |      DqnVHashTable(isize size) { LazyInit(size); } | ||||||
|     ~DqnVHashTable()           { if (buckets) DqnOS_VFree(buckets, sizeof(buckets) * numBuckets); } |     ~DqnVHashTable()           { if (buckets) DqnOS_VFree(buckets, sizeof(buckets) * numBuckets); } | ||||||
| 
 | 
 | ||||||
|     void       Erase(Key const &key); |     void       LazyInit(isize size) { *this = {}; numBuckets = size; buckets = static_cast<Bucket *>(DqnOS_VAlloc(numBuckets * sizeof(*buckets))); DQN_ASSERT(buckets); } | ||||||
|     Item      *Set  (Key const &key, Item const &item); |     void       Erase   (Key const &key); | ||||||
|     Item      *Get  (Key const &key); |     Item      *Set     (Key const &key, Item const &item); | ||||||
|  |     Item      *Get     (Key const &key); | ||||||
| 
 | 
 | ||||||
|     Item *operator[](Key const &key) { return Get(key); } |     Item *operator[](Key const &key) { return Get(key); } | ||||||
| 
 | 
 | ||||||
| private: |  | ||||||
|     void LazyInitialise(isize size) { *this = {}; numBuckets = size; buckets = static_cast<Bucket *>(DqnOS_VAlloc(numBuckets * sizeof(*buckets))); DQN_ASSERT(buckets); } |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| DQN_VHASH_TABLE_TEMPLATE Item *DQN_VHASH_TABLE_DECL::Set(Key const &key, Item const &item) | DQN_VHASH_TABLE_TEMPLATE Item *DQN_VHASH_TABLE_DECL::Set(Key const &key, Item const &item) | ||||||
| { | { | ||||||
|     if (!buckets) LazyInitialise(1024); |     if (!buckets) LazyInit(1024); | ||||||
| 
 | 
 | ||||||
|     isize index       = Hash(this->numBuckets, key); |     isize index       = Hash(this->numBuckets, key); | ||||||
|     Bucket *bucket    = this->buckets + index; |     Bucket *bucket    = this->buckets + index; | ||||||
| @ -6972,6 +6978,8 @@ DQN_FILE_SCOPE i64 Dqn_BSearch(i64 *array, i64 size, i64 find, | |||||||
| DQN_FILE_SCOPE DqnJson DqnJson_Get(char const *buf, i32 bufLen, char const *findProperty, i32 findPropertyLen) | DQN_FILE_SCOPE DqnJson DqnJson_Get(char const *buf, i32 bufLen, char const *findProperty, i32 findPropertyLen) | ||||||
| { | { | ||||||
|     DqnJson result = {}; |     DqnJson result = {}; | ||||||
|  |     if (!buf || bufLen == 0 || !findProperty || findPropertyLen == 0) return result; | ||||||
|  | 
 | ||||||
|     char const *tmp = DqnChar_SkipWhitespace(buf); |     char const *tmp = DqnChar_SkipWhitespace(buf); | ||||||
|     bufLen          = static_cast<int>((buf + bufLen) - tmp); |     bufLen          = static_cast<int>((buf + bufLen) - tmp); | ||||||
|     buf             = tmp; |     buf             = tmp; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user