github.com/m3db/m3@v1.5.0/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  }