MongoDB C++ Driver  legacy-1.1.2
unordered_fast_key_table.h
1 // unordered_fast_key_table.h
2 
3 /* Copyright 2012 10gen Inc.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #pragma once
19 
20 #include <boost/smart_ptr/scoped_array.hpp>
21 
22 #include "mongo/base/disallow_copying.h"
23 
24 namespace mongo {
25 
26 template <typename K_L, typename K_S>
28  K_S operator()(const K_L& a) const {
29  return K_S(a);
30  }
31 };
32 
33 template <typename K_L, // key lookup
34  typename K_S, // key storage
35  typename V, // value
36  typename H, // hash of K_L
37  typename E, // equal of K_L
38  typename C, // convertor from K_S -> K_L
39  typename C_LS = UnorderedFastKeyTable_LS_C<K_L, K_S> // convertor from K_L -> K_S
40  >
42 public:
43  typedef std::pair<K_S, V> value_type;
44  typedef K_L key_type;
45  typedef V mapped_type;
46 
47 private:
48  struct Entry {
49  Entry() : used(false), everUsed(false) {}
50 
51  bool used;
52  bool everUsed;
53  size_t curHash;
54  value_type data;
55  };
56 
57  struct Area {
58  Area(unsigned capacity, double maxProbeRatio);
59  Area(const Area& other);
60 
61  int find(const K_L& key,
62  size_t hash,
63  int* firstEmpty,
64  const UnorderedFastKeyTable& sm) const;
65 
66  bool transfer(Area* newArea, const UnorderedFastKeyTable& sm) const;
67 
68  void swap(Area* other) {
69  using std::swap;
70  swap(_capacity, other->_capacity);
71  swap(_maxProbe, other->_maxProbe);
72  swap(_entries, other->_entries);
73  }
74 
75  unsigned _capacity;
76  unsigned _maxProbe;
77  boost::scoped_array<Entry> _entries;
78  };
79 
80 public:
81  static const unsigned DEFAULT_STARTING_CAPACITY = 20;
82 
89  UnorderedFastKeyTable(unsigned startingCapacity = DEFAULT_STARTING_CAPACITY,
90  double maxProbeRatio = 0.05);
91 
93 
94  UnorderedFastKeyTable& operator=(const UnorderedFastKeyTable& other) {
95  other.copyTo(this);
96  return *this;
97  }
98 
99  void copyTo(UnorderedFastKeyTable* out) const;
100 
104  size_t size() const {
105  return _size;
106  }
107 
108  bool empty() const {
109  return _size == 0;
110  }
111 
112  /*
113  * @return storage space
114  */
115  size_t capacity() const {
116  return _area._capacity;
117  }
118 
119  V& operator[](const K_L& key) {
120  return get(key);
121  }
122 
123  V& get(const K_L& key);
124 
128  size_t erase(const K_L& key);
129 
131  friend class UnorderedFastKeyTable;
132 
133  public:
134  const_iterator() {
135  _position = -1;
136  }
137  const_iterator(const Area* area) {
138  _area = area;
139  _position = 0;
140  _max = _area->_capacity - 1;
141  _skip();
142  }
143  const_iterator(const Area* area, int pos) {
144  _area = area;
145  _position = pos;
146  _max = pos;
147  }
148 
149  const value_type* operator->() const {
150  return &_area->_entries[_position].data;
151  }
152 
153  const value_type& operator*() const {
154  return _area->_entries[_position].data;
155  }
156 
157  const_iterator operator++() {
158  if (_position < 0)
159  return *this;
160  _position++;
161  if (_position > _max)
162  _position = -1;
163  else
164  _skip();
165  return *this;
166  }
167 
168  bool operator==(const const_iterator& other) const {
169  return _position == other._position;
170  }
171  bool operator!=(const const_iterator& other) const {
172  return _position != other._position;
173  }
174 
175  private:
176  void _skip() {
177  while (true) {
178  if (_area->_entries[_position].used)
179  break;
180  if (_position >= _max) {
181  _position = -1;
182  break;
183  }
184  ++_position;
185  }
186  }
187 
188  const Area* _area;
189  int _position;
190  int _max; // inclusive
191  };
192 
193  void erase(const_iterator it);
194 
198  const_iterator find(const K_L& key) const;
199 
200  const_iterator begin() const;
201 
202  const_iterator end() const;
203 
204 private:
205  /*
206  * @param firstEmpty, if we return -1, and firstEmpty != NULL,
207  * this will be set to the first empty bucket we found
208  * @retrun offset into _entries or -1 if not there
209  */
210  int _find(const K_L& key, int hash, int* firstEmpty) const;
211 
212  void _grow();
213 
214  // ----
215 
216  size_t _size;
217  double _maxProbeRatio;
218  Area _area;
219 
220  H _hash;
221  E _equals;
222  C _convertor;
223  C_LS _convertorOther;
224 };
225 }
226 
227 #include "mongo/util/unordered_fast_key_table_internal.h"
size_t size() const
Definition: unordered_fast_key_table.h:104
Definition: unordered_fast_key_table.h:27
Utility functions for parsing numbers from strings.
Definition: compare_numbers.h:20
size_t erase(const K_L &key)
Definition: unordered_fast_key_table_internal.h:150
Definition: unordered_fast_key_table.h:41
const_iterator find(const K_L &key) const
Definition: unordered_fast_key_table_internal.h:191
UnorderedFastKeyTable(unsigned startingCapacity=DEFAULT_STARTING_CAPACITY, double maxProbeRatio=0.05)
Definition: unordered_fast_key_table_internal.h:96
Definition: unordered_fast_key_table.h:130