github.com/m3db/m3@v1.5.0/src/query/storage/m3/consolidators/fetch_result_map_gen.go (about)

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