HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UT_ARTMapImpl.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: UT_ARTMapImpl.h
7  *
8  * COMMENTS:
9  *
10  *
11  */
12 
13 #ifndef __UT_ARTMAPIMPL_H__
14 #define __UT_ARTMAPIMPL_H__
15 
16 // -----------------------------------------------------------------------------
17 // UT_ARTNode4
18 // -----------------------------------------------------------------------------
19 
20 template <typename T>
21 inline bool
23 {
24  return this->myNumChildren == 4;
25 }
26 
27 template <typename T>
28 inline UT_ARTNode<T>**
30 {
31  UT_ASSERT(child != nullptr);
32  if (!isFull())
33  {
34  UT_StringView prefix = child->prefix();
35  unsigned c = prefix[0];
36 
37  myChildKeys[this->myNumChildren] = c;
38  myChildren[this->myNumChildren] = child.release();
39  parent_t** node = &myChildren[this->myNumChildren];
40  this->myNumChildren++;
41  return node;
42  }
43  else
44  {
45  auto upgrade = this->template newNode<UT_ARTNode16<T>>();
46  this->moveHeader(*upgrade);
47  UT_ARTNodePtr<parent_t> holder(*ref);
48 
49  upgrade->myNumChildren = this->myNumChildren;
50  memcpy(upgrade->myChildKeys, myChildKeys,
51  sizeof(unsigned char) * this->myNumChildren);
52  for (int i = 0; i < 4; ++i)
53  {
54  upgrade->myChildren[i] = myChildren[i];
55  myChildren[i] = nullptr;
56  }
57 
58  *ref = upgrade.release();
59  return (*ref)->insertChild(ref, std::move(child));
60  }
61 
62  return nullptr;
63 }
64 
65 template <typename T>
68 {
69  uchar c = child->prefix()[0];
70  int idx = 0;
71  if (myChildKeys[0] == c)
72  idx = 0;
73  else if (myChildKeys[1] == c)
74  idx = 1;
75  else if (myChildKeys[2] == c)
76  idx = 2;
77  else if (myChildKeys[3] == c)
78  idx = 3;
79  else
80  return nullptr;
81 
82  return stealChild(ref, idx);
83 }
84 
85 template <typename T>
86 inline UT_ARTNode<T>**
88 {
89  parent_t** found = nullptr;
90 
91  uchar c = prefix[0];
92  if (myChildKeys[0] == c)
93  found = &myChildren[0];
94  else if (myChildKeys[1] == c)
95  found = &myChildren[1];
96  else if (myChildKeys[2] == c)
97  found = &myChildren[2];
98  else if (myChildKeys[3] == c)
99  found = &myChildren[3];
100 
101  return found;
102 }
103 
104 template <typename T>
105 inline UT_ARTNode<T>*
107 {
108  for (; index < this->myNumChildren; index++)
109  {
110  if (myChildren[index] != nullptr)
111  return myChildren[index];
112  }
113  return nullptr;
114 }
115 
116 template <typename T>
117 inline const UT_ARTNode<T>*
119 {
120  for (; index < this->myNumChildren; index++)
121  {
122  if (myChildren[index] != nullptr)
123  return myChildren[index];
124  }
125  return nullptr;
126 }
127 
128 template <typename T>
131 {
132  this->myNumChildren--;
133  UT_ARTNodePtr<parent_t> stolen(myChildren[idx]);
134  myChildren[idx] = myChildren[this->myNumChildren];
135  myChildKeys[idx] = myChildKeys[this->myNumChildren];
136  myChildKeys[this->myNumChildren] = 0;
137  myChildren[this->myNumChildren] = nullptr;
138  return stolen;
139 }
140 
141 // -----------------------------------------------------------------------------
142 // UT_ARTNode16
143 // -----------------------------------------------------------------------------
144 
145 template <typename T>
146 inline bool
148 {
149  return this->myNumChildren == 16;
150 }
151 
152 template <typename T>
153 inline UT_ARTNode<T>**
155  parent_t** ref,
157 {
158  if (this->myNumChildren < 16)
159  {
160  uchar c = child->prefix()[0];
161  int idx = prefixToIndex_(c);
162 
163  if (idx < 0)
164  idx = this->myNumChildren;
165 
166  myChildKeys[idx] = c;
167  myChildren[idx] = child.release();
168  this->myNumChildren++;
169 
170  return &myChildren[idx];
171  }
172  else
173  {
174  UT_ARTNodePtr<parent_t> holder(*ref);
175  auto upgrade = this->template newNode<UT_ARTNode48<T>>();
176  this->moveHeader(*upgrade);
177  for (int i = 0; i < this->myNumChildren; i++)
178  {
179  upgrade->myChildKeys[myChildKeys[i]] = i + 1;
180  upgrade->myChildren[i] = myChildren[i];
181  myChildren[i] = nullptr;
182  }
183  *ref = upgrade.release();
184  return (*ref)->insertChild(ref, std::move(child));
185  }
186 }
187 
188 template <typename T>
191 {
192  uchar c = child->prefix()[0];
193  int idx = prefixToIndex_(c);
194  if (idx >= 0)
195  return stealChild(ref, idx);
196 
197  return nullptr;
198 }
199 
200 template <typename T>
201 inline UT_ARTNode<T>**
203 {
204  uchar c = prefix[0];
205 
206  int idx = prefixToIndex_(c);
207  if (idx >= 0)
208  {
209  return &myChildren[idx];
210  }
211 
212  return nullptr;
213 }
214 
215 template <typename T>
216 inline UT_ARTNode<T>*
218 {
219  for (; index < this->myNumChildren; index++)
220  {
221  if (myChildren[index] != nullptr)
222  return myChildren[index];
223  }
224  return nullptr;
225 }
226 
227 template <typename T>
228 inline const UT_ARTNode<T>*
230 {
231  for (; index < this->myNumChildren; index++)
232  {
233  if (myChildren[index] != nullptr)
234  return myChildren[index];
235  }
236  return nullptr;
237 }
238 
239 template <typename T>
242 {
243  this->myNumChildren--;
244  UT_ARTNodePtr<parent_t> stolen(myChildren[idx]);
245  myChildren[idx] = myChildren[this->myNumChildren];
246  myChildKeys[idx] = myChildKeys[this->myNumChildren];
247  myChildKeys[this->myNumChildren] = 0;
248  myChildren[this->myNumChildren] = nullptr;
249 
250  if (this->myNumChildren == 2)
251  {
252  auto downgrade = this->template newNode<UT_ARTNode4<T>>();
253  this->moveHeader(*downgrade);
254  memcpy(downgrade->myChildKeys, myChildKeys, 4);
255  for (int i = 0; i < this->myNumChildren; i++)
256  {
257  downgrade->myChildren[i] = myChildren[i];
258  myChildren[i] = nullptr;
259  }
260 
261  UT_ARTNodePtr<parent_t> holder(*ref);
262 
263  *ref = downgrade.release();
264  }
265 
266  return stolen;
267 }
268 
269 // -----------------------------------------------------------------------------
270 // UT_ARTNode48
271 // -----------------------------------------------------------------------------
272 
273 template <typename T>
274 inline bool
276 {
277  return this->myNumChildren == 48;
278 }
279 
280 template <typename T>
281 inline UT_ARTNode<T>**
283 {
284  uchar c = child->prefix()[0];
285  if (this->myNumChildren < 48)
286  {
287  int pos;
288  for (pos = 0; pos < 48; pos++)
289  {
290  if (myChildren[pos] == nullptr)
291  break;
292  }
293  myChildren[pos] = child.release();
294  myChildKeys[c] = pos + 1;
295  this->myNumChildren++;
296 
297  return &myChildren[pos];
298  }
299  else
300  {
301  UT_ARTNodePtr<parent_t> holder(*ref);
302  auto upgrade = this->template newNode<UT_ARTNode256<T>>();
303  this->moveHeader(*upgrade);
304  for (int i = 0; i < 256; i++)
305  {
306  if (myChildKeys[i])
307  {
308  upgrade->myChildren[i] = myChildren[myChildKeys[i] - 1];
309  myChildren[myChildKeys[i] - 1] = nullptr;
310  }
311  }
312 
313  *ref = upgrade.release();
314  return (*ref)->insertChild(ref, std::move(child));
315  }
316 }
317 
318 template <typename T>
321 {
322  uchar c = child->prefix()[0];
323  int idx = myChildKeys[c];
324  if (idx > 0)
325  return stealChild(ref, idx - 1);
326  return nullptr;
327 }
328 
329 template <typename T>
330 inline UT_ARTNode<T>**
332 {
333  uchar c = prefix[0];
334  int idx = myChildKeys[c];
335  if (idx > 0)
336  return &myChildren[idx - 1];
337  return nullptr;
338 }
339 
340 template <typename T>
341 inline UT_ARTNode<T>*
343 {
344  for (; index < 48; index++)
345  {
346  if (myChildren[index] != nullptr)
347  return myChildren[index];
348  }
349  return nullptr;
350 }
351 
352 template <typename T>
353 inline const UT_ARTNode<T>*
355 {
356  for (; index < 48; index++)
357  {
358  if (myChildren[index] != nullptr)
359  return myChildren[index];
360  }
361  return nullptr;
362 }
363 
364 template <typename T>
367 {
368  this->myNumChildren--;
369  parent_ptr_t stolen(myChildren[idx]);
370  uchar c = myChildren[idx]->prefix()[0];
371  myChildKeys[c] = 0;
372  myChildren[idx] = nullptr;
373 
374  // if we dont hold enough children then downgrade to the previous node.
375  // Make sure we dont do this downgrade to close to the previous nodes
376  // max so that we prevent fliping between node16 and node48
377  if (this->myNumChildren == 12)
378  {
379  parent_ptr_t holder(*ref);
380  auto downgrade = this->template newNode<UT_ARTNode16<T>>();
381  this->moveHeader(*downgrade);
382 
383  int cidx = 0;
384  for (int i = 0; i < 256; i++)
385  {
386  int pos = myChildKeys[i];
387  if (pos)
388  {
389  downgrade->myChildKeys[cidx] = i;
390  downgrade->myChildren[cidx] = myChildren[pos - 1];
391  myChildren[pos - 1] = nullptr;
392  cidx++;
393  }
394  }
395 
396  *ref = downgrade.release();
397  return stolen;
398  }
399 
400  return stolen;
401 }
402 
403 // -----------------------------------------------------------------------------
404 // UT_ARTNode256
405 // -----------------------------------------------------------------------------
406 
407 template <typename T>
408 inline bool
410 {
411  return this->myNumChildren == 256;
412 }
413 
414 template <typename T>
415 inline UT_ARTNode<T>**
417 {
418  uchar c = child->prefix()[0];
419  this->myNumChildren++;
420  myChildren[c] = child.release();
421 
422  return &myChildren[c];
423 }
424 
425 template <typename T>
428 {
429  uchar c = child->prefix()[0];
430  return stealChild(ref, c);
431 }
432 
433 template <typename T>
434 inline UT_ARTNode<T>**
436  const UT_StringView& prefix)
437 {
438  uchar c = prefix[0];
439  if (myChildren[c] != nullptr)
440  return &myChildren[c];
441  return nullptr;
442 }
443 
444 template <typename T>
445 inline UT_ARTNode<T>*
447 {
448  // NB: we dont shuffle children when inserting/deleting so we cant use
449  // the child count and instead of have to loop through the entire 256
450  // array.
451  for (; index < 256; index++)
452  {
453  if (myChildren[index] != nullptr)
454  return myChildren[index];
455  }
456  return nullptr;
457 }
458 
459 template <typename T>
460 inline const UT_ARTNode<T>*
462 {
463  for (; index < 256; index++)
464  {
465  if (myChildren[index] != nullptr)
466  return myChildren[index];
467  }
468  return nullptr;
469 }
470 
471 template <typename T>
474 {
475  this->myNumChildren--;
476  parent_ptr_t stolen(myChildren[idx]);
477  myChildren[idx] = nullptr;
478 
479  // If we hold less then the max of the lower node we need to downgrade
480  // ourselves. We dont use the boundary to downgrade to prevent constantly
481  // switching between node48 and node256.
482  if (this->myNumChildren == 37)
483  {
484  parent_ptr_t holder(*ref);
485  auto downgrade = this->template newNode<UT_ARTNode48<T>>();
486  this->moveHeader(*downgrade);
487  int pos = 0;
488  for (int i = 0; i < 256; i++)
489  {
490  if (myChildren[i] != nullptr)
491  {
492  downgrade->myChildren[pos] = myChildren[i];
493  downgrade->myChildKeys[i] = pos + 1;
494  pos++;
495  myChildren[i] = nullptr;
496  }
497  }
498 
499  *ref = downgrade.release();
500  return stolen;
501  }
502 
503  return stolen;
504 }
505 
506 #endif // __UT_ARTMAPIMPL_H__
UT_ARTNodePtr< parent_t > parent_ptr_t
Definition: UT_ARTMap.h:621
parent_t * nextChild(int &index) override
parent_t * nextChild(int &index) override
parent_ptr_t stealChild(parent_t **ref, parent_t *child) override
UT_ARTNodePtr< parent_t > parent_ptr_t
Definition: UT_ARTMap.h:439
parent_ptr_t stealChild(parent_t **ref, parent_t *child) override
**But if you need a or simply need to know when the task has note that the like this
Definition: thread.h:617
parent_t ** findPartialPrefixChild(const UT_StringView &prefix) override
A utility class to do read-only operations on a subset of an existing string.
Definition: UT_StringView.h:39
bool isFull() const override
GLint ref
Definition: glcorearb.h:124
bool isFull() const override
parent_t ** insertChild(parent_t **ref, parent_ptr_t child) override
bool isFull() const override
parent_t ** findPartialPrefixChild(const UT_StringView &prefix) override
UT_ARTNodePtr< parent_t > parent_ptr_t
Definition: UT_ARTMap.h:572
parent_t ** insertChild(parent_t **ref, parent_ptr_t child) override
parent_t ** findPartialPrefixChild(const UT_StringView &prefix) override
Definition: UT_ARTMapImpl.h:87
parent_t ** insertChild(parent_t **ref, parent_ptr_t child) override
parent_ptr_t stealChild(parent_t **ref, parent_t *child) override
Definition: UT_ARTMapImpl.h:67
parent_t ** insertChild(parent_t **ref, parent_ptr_t child) override
Definition: UT_ARTMapImpl.h:29
GLuint index
Definition: glcorearb.h:786
parent_t * nextChild(int &index) override
parent_t * nextChild(int &index) override
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:156
parent_t ** findPartialPrefixChild(const UT_StringView &prefix) override
parent_ptr_t stealChild(parent_t **ref, parent_t *child) override
virtual UT_ARTNode< T > ** insertChild(UT_ARTNode **ref, UT_ARTNodePtr< UT_ARTNode< T >> node)=0
UT_UniquePtr< T, UT_ARTNodeDelete > UT_ARTNodePtr
Definition: UT_ARTMap.h:67
unsigned char uchar
Definition: SYS_Types.h:42
SYS_FORCE_INLINE const UT_StringView & prefix() const
Definition: UT_ARTMap.h:113
bool isFull() const override
Definition: UT_ARTMapImpl.h:22