github.com/m3db/m3@v1.5.1-0.20231129193456-75a402aa583b/src/dbnode/persist/fs/checked_bytes_by_id_map_gen.go (about) 1 // Copyright (c) 2019 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 // This file was automatically generated by genny. 22 // Any changes will be lost if this file is regenerated. 23 // see https://github.com/mauricelam/genny 24 25 package fs 26 27 import ( 28 "github.com/m3db/m3/src/x/checked" 29 "github.com/m3db/m3/src/x/ident" 30 ) 31 32 // Copyright (c) 2019 Uber Technologies, Inc. 33 // 34 // Permission is hereby granted, free of charge, to any person obtaining a copy 35 // of this software and associated documentation files (the "Software"), to deal 36 // in the Software without restriction, including without limitation the rights 37 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 38 // copies of the Software, and to permit persons to whom the Software is 39 // furnished to do so, subject to the following conditions: 40 // 41 // The above copyright notice and this permission notice shall be included in 42 // all copies or substantial portions of the Software. 43 // 44 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 45 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 46 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 47 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 48 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 49 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 50 // THE SOFTWARE. 51 52 // This file was automatically generated by genny. 53 // Any changes will be lost if this file is regenerated. 54 // see https://github.com/mauricelam/genny 55 56 // Copyright (c) 2018 Uber Technologies, Inc. 57 // 58 // Permission is hereby granted, free of charge, to any person obtaining a copy 59 // of this software and associated documentation files (the "Software"), to deal 60 // in the Software without restriction, including without limitation the rights 61 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 62 // copies of the Software, and to permit persons to whom the Software is 63 // furnished to do so, subject to the following conditions: 64 // 65 // The above copyright notice and this permission notice shall be included in 66 // all copies or substantial portions of the Software. 67 // 68 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 69 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 70 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 71 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 72 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 73 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 74 // THE SOFTWARE. 75 76 // checkedBytesMapHash is the hash for a given map entry, this is public to support 77 // iterating over the map using a native Go for loop. 78 type checkedBytesMapHash uint64 79 80 // checkedBytesMapHashFn is the hash function to execute when hashing a key. 81 type checkedBytesMapHashFn func(ident.ID) checkedBytesMapHash 82 83 // checkedBytesMapEqualsFn is the equals key function to execute when detecting equality of a key. 84 type checkedBytesMapEqualsFn func(ident.ID, ident.ID) bool 85 86 // checkedBytesMapCopyFn is the copy key function to execute when copying the key. 87 type checkedBytesMapCopyFn func(ident.ID) ident.ID 88 89 // checkedBytesMapFinalizeFn is the finalize key function to execute when finished with a key. 90 type checkedBytesMapFinalizeFn func(ident.ID) 91 92 // checkedBytesMap uses the genny package to provide a generic hash map that can be specialized 93 // by running the following command from this root of the repository: 94 // ``` 95 // make hashmap-gen pkg=outpkg key_type=Type value_type=Type out_dir=/tmp 96 // ``` 97 // Or if you would like to use bytes or ident.ID as keys you can use the 98 // partially specialized maps to generate your own maps as well: 99 // ``` 100 // make byteshashmap-gen pkg=outpkg value_type=Type out_dir=/tmp 101 // make idhashmap-gen pkg=outpkg value_type=Type out_dir=/tmp 102 // ``` 103 // This will output to stdout the generated source file to use for your map. 104 // It uses linear probing by incrementing the number of the hash created when 105 // hashing the identifier if there is a collision. 106 // checkedBytesMap is a value type and not an interface to allow for less painful 107 // upgrades when adding/removing methods, it is not likely to need mocking so 108 // an interface would not be super useful either. 109 type checkedBytesMap struct { 110 _checkedBytesMapOptions 111 112 // lookup uses hash of the identifier for the key and the MapEntry value 113 // wraps the value type and the key (used to ensure lookup is correct 114 // when dealing with collisions), we use uint64 for the hash partially 115 // because lookups of maps with uint64 keys has a fast path for Go. 116 lookup map[checkedBytesMapHash]checkedBytesMapEntry 117 } 118 119 // _checkedBytesMapOptions is a set of options used when creating an identifier map, it is kept 120 // private so that implementers of the generated map can specify their own options 121 // that partially fulfill these options. 122 type _checkedBytesMapOptions struct { 123 // hash is the hash function to execute when hashing a key. 124 hash checkedBytesMapHashFn 125 // equals is the equals key function to execute when detecting equality. 126 equals checkedBytesMapEqualsFn 127 // copy is the copy key function to execute when copying the key. 128 copy checkedBytesMapCopyFn 129 // finalize is the finalize key function to execute when finished with a 130 // key, this is optional to specify. 131 finalize checkedBytesMapFinalizeFn 132 // initialSize is the initial size for the map, use zero to use Go's std map 133 // initial size and consequently is optional to specify. 134 initialSize int 135 } 136 137 // checkedBytesMapEntry is an entry in the map, this is public to support iterating 138 // over the map using a native Go for loop. 139 type checkedBytesMapEntry struct { 140 // key is used to check equality on lookups to resolve collisions 141 key _checkedBytesMapKey 142 // value type stored 143 value checked.Bytes 144 } 145 146 type _checkedBytesMapKey struct { 147 key ident.ID 148 finalize bool 149 } 150 151 // Key returns the map entry key. 152 func (e checkedBytesMapEntry) Key() ident.ID { 153 return e.key.key 154 } 155 156 // Value returns the map entry value. 157 func (e checkedBytesMapEntry) Value() checked.Bytes { 158 return e.value 159 } 160 161 // _checkedBytesMapAlloc is a non-exported function so that when generating the source code 162 // for the map you can supply a public constructor that sets the correct 163 // hash, equals, copy, finalize options without users of the map needing to 164 // implement them themselves. 165 func _checkedBytesMapAlloc(opts _checkedBytesMapOptions) *checkedBytesMap { 166 m := &checkedBytesMap{_checkedBytesMapOptions: opts} 167 m.Reallocate() 168 return m 169 } 170 171 func (m *checkedBytesMap) newMapKey(k ident.ID, opts _checkedBytesMapKeyOptions) _checkedBytesMapKey { 172 key := _checkedBytesMapKey{key: k, finalize: opts.finalizeKey} 173 if !opts.copyKey { 174 return key 175 } 176 177 key.key = m.copy(k) 178 return key 179 } 180 181 func (m *checkedBytesMap) removeMapKey(hash checkedBytesMapHash, key _checkedBytesMapKey) { 182 delete(m.lookup, hash) 183 if key.finalize { 184 m.finalize(key.key) 185 } 186 } 187 188 // Get returns a value in the map for an identifier if found. 189 func (m *checkedBytesMap) Get(k ident.ID) (checked.Bytes, bool) { 190 hash := m.hash(k) 191 for entry, ok := m.lookup[hash]; ok; entry, ok = m.lookup[hash] { 192 if m.equals(entry.key.key, k) { 193 return entry.value, true 194 } 195 // Linear probe to "next" to this entry (really a rehash) 196 hash++ 197 } 198 var empty checked.Bytes 199 return empty, false 200 } 201 202 // Set will set the value for an identifier. 203 func (m *checkedBytesMap) Set(k ident.ID, v checked.Bytes) { 204 m.set(k, v, _checkedBytesMapKeyOptions{ 205 copyKey: true, 206 finalizeKey: m.finalize != nil, 207 }) 208 } 209 210 // checkedBytesMapSetUnsafeOptions is a set of options to use when setting a value with 211 // the SetUnsafe method. 212 type checkedBytesMapSetUnsafeOptions struct { 213 NoCopyKey bool 214 NoFinalizeKey bool 215 } 216 217 // SetUnsafe will set the value for an identifier with unsafe options for how 218 // the map treats the key. 219 func (m *checkedBytesMap) SetUnsafe(k ident.ID, v checked.Bytes, opts checkedBytesMapSetUnsafeOptions) { 220 m.set(k, v, _checkedBytesMapKeyOptions{ 221 copyKey: !opts.NoCopyKey, 222 finalizeKey: !opts.NoFinalizeKey, 223 }) 224 } 225 226 type _checkedBytesMapKeyOptions struct { 227 copyKey bool 228 finalizeKey bool 229 } 230 231 func (m *checkedBytesMap) set(k ident.ID, v checked.Bytes, opts _checkedBytesMapKeyOptions) { 232 hash := m.hash(k) 233 for entry, ok := m.lookup[hash]; ok; entry, ok = m.lookup[hash] { 234 if m.equals(entry.key.key, k) { 235 m.lookup[hash] = checkedBytesMapEntry{ 236 key: entry.key, 237 value: v, 238 } 239 return 240 } 241 // Linear probe to "next" to this entry (really a rehash) 242 hash++ 243 } 244 245 m.lookup[hash] = checkedBytesMapEntry{ 246 key: m.newMapKey(k, opts), 247 value: v, 248 } 249 } 250 251 // Iter provides the underlying map to allow for using a native Go for loop 252 // to iterate the map, however callers should only ever read and not write 253 // the map. 254 func (m *checkedBytesMap) Iter() map[checkedBytesMapHash]checkedBytesMapEntry { 255 return m.lookup 256 } 257 258 // Len returns the number of map entries in the map. 259 func (m *checkedBytesMap) Len() int { 260 return len(m.lookup) 261 } 262 263 // Contains returns true if value exists for key, false otherwise, it is 264 // shorthand for a call to Get that doesn't return the value. 265 func (m *checkedBytesMap) Contains(k ident.ID) bool { 266 _, ok := m.Get(k) 267 return ok 268 } 269 270 // Delete will remove a value set in the map for the specified key. 271 func (m *checkedBytesMap) Delete(k ident.ID) { 272 hash := m.hash(k) 273 for entry, ok := m.lookup[hash]; ok; entry, ok = m.lookup[hash] { 274 if m.equals(entry.key.key, k) { 275 m.removeMapKey(hash, entry.key) 276 return 277 } 278 // Linear probe to "next" to this entry (really a rehash) 279 hash++ 280 } 281 } 282 283 // Reset will reset the map by simply deleting all keys to avoid 284 // allocating a new map. 285 func (m *checkedBytesMap) Reset() { 286 for hash, entry := range m.lookup { 287 m.removeMapKey(hash, entry.key) 288 } 289 } 290 291 // Reallocate will avoid deleting all keys and reallocate a new 292 // map, this is useful if you believe you have a large map and 293 // will not need to grow back to a similar size. 294 func (m *checkedBytesMap) Reallocate() { 295 if m.initialSize > 0 { 296 m.lookup = make(map[checkedBytesMapHash]checkedBytesMapEntry, m.initialSize) 297 } else { 298 m.lookup = make(map[checkedBytesMapHash]checkedBytesMapEntry) 299 } 300 }