RavEngine
Loading...
Searching...
No Matches
NvFlowStringHash.h
1// Redistribution and use in source and binary forms, with or without
2// modification, are permitted provided that the following conditions
3// are met:
4// * Redistributions of source code must retain the above copyright
5// notice, this list of conditions and the following disclaimer.
6// * Redistributions in binary form must reproduce the above copyright
7// notice, this list of conditions and the following disclaimer in the
8// documentation and/or other materials provided with the distribution.
9// * Neither the name of NVIDIA CORPORATION nor the names of its
10// contributors may be used to endorse or promote products derived
11// from this software without specific prior written permission.
12//
13// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
14// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24//
25// Copyright (c) 2014-2022 NVIDIA Corporation. All rights reserved.
26
27#pragma once
28
29#include "NvFlowTypes.h"
30#include "NvFlowArray.h"
31
32NV_FLOW_INLINE NvFlowUint NvFlowStringHashFNV(const char* a)
33{
34 // FNV-1a
35 NvFlowUint hash = 2166136261u;
36 NvFlowUint idx = 0u;
37 if (a)
38 {
39 while (a[idx])
40 {
41 hash = 16777619u * (hash ^ (NvFlowUint)(a[idx]));
42 idx++;
43 }
44 }
45 return hash;
46}
47
48template<class T, NvFlowUint64 staticCapacity = 0u>
50{
52 NvFlowArray<NvFlowArray<char>, staticCapacity> keys;
54 NvFlowUint64 keyCount = 0llu;
55
56 NvFlowUint64 find(const char* path, NvFlowUint hash)
57 {
58 path = path ? path : "";
59 NvFlowUint64 beginIdx = hash & (hashs.size - 1u);
60 for (NvFlowUint64 iterIdx = 0u; iterIdx < hashs.size; iterIdx++)
61 {
62 NvFlowUint64 idx = (iterIdx + beginIdx) & (hashs.size - 1u);
63 if (hashs[idx] == hash &&
64 keys[idx].size > 0u &&
65 strcmp(keys[idx].data, path) == 0)
66 {
67 return idx;
68 }
69 }
70 return ~0llu;
71 }
72
73 NvFlowUint64 insertNoResize(const char* path, NvFlowUint hash, const T& value, NvFlowBool32* pSuccess = nullptr)
74 {
75 path = path ? path : "";
76 if (pSuccess)
77 {
78 *pSuccess = NV_FLOW_FALSE;
79 }
80 NvFlowUint64 beginIdx = hash & (hashs.size - 1u);
81 for (NvFlowUint64 iterIdx = 0u; iterIdx < hashs.size; iterIdx++)
82 {
83 NvFlowUint64 idx = (iterIdx + beginIdx) & (hashs.size - 1u);
84 if (keys[idx].size == 0u)
85 {
86 keyCount++;
87 hashs[idx] = hash;
88 for (NvFlowUint64 strIdx = 0u; path[strIdx]; strIdx++)
89 {
90 keys[idx].pushBack(path[strIdx]);
91 }
92 keys[idx].pushBack('\0');
93 values[idx] = value;
94 if (pSuccess)
95 {
96 *pSuccess = NV_FLOW_TRUE;
97 }
98 return idx;
99 }
100 else if (hashs[idx] == hash &&
101 keys[idx].size > 0u &&
102 strcmp(keys[idx].data, path) == 0)
103 {
104 return idx;
105 }
106 }
107 return ~0llu;
108 }
109
110 NvFlowUint64 insert(const char* path, NvFlowUint hash, const T& value, NvFlowBool32* pSuccess = nullptr)
111 {
112 // resize if adding key would make 50+% full
113 if (2u * (keyCount + 1u) >= hashs.size)
114 {
115 NvFlowArray<NvFlowUint, staticCapacity> hashs_old(std::move(hashs));
116 NvFlowArray<NvFlowArray<char>, staticCapacity> keys_old(std::move(keys));
117 NvFlowArray<T, staticCapacity> values_old(std::move(values));
118 NvFlowUint64 newSize = 1u;
119 while (newSize <= hashs_old.size)
120 {
121 newSize *= 2u;
122 }
123 hashs.reserve(newSize);
124 keys.reserve(newSize);
125 values.reserve(newSize);
126 hashs.size = newSize;
127 keys.size = newSize;
128 values.size = newSize;
129 keyCount = 0u; // reset key count, because insert counts it again
130 for (NvFlowUint64 idx = 0u; idx < hashs_old.size; idx++)
131 {
132 if (keys_old[idx].size > 0u)
133 {
134 insertNoResize(keys_old[idx].data, hashs_old[idx], values_old[idx], nullptr);
135 }
136 }
137 }
138 return insertNoResize(path, hash, value, pSuccess);
139 }
140
141 NvFlowBool32 erase(const char* path, NvFlowUint hash)
142 {
143 NvFlowUint64 findIdx = find(path, hash);
144 if (findIdx != ~0llu)
145 {
146 keyCount--;
147 hashs[findIdx] = 0u;
148 keys[findIdx].size = 0u;
149 values[findIdx] = T();
150 return NV_FLOW_TRUE;
151 }
152 return NV_FLOW_FALSE;
153 }
154};
Definition NvFlowArray.h:36
Definition NvFlowStringHash.h:50