1
/* $Id: tstRTAvl.cpp $ */
3
* IPRT Testcase - AVL trees.
7
* Copyright (C) 2006-2010 Oracle Corporation
9
* This file is part of VirtualBox Open Source Edition (OSE), as
10
* available from http://www.virtualbox.org. This file is free software;
11
* you can redistribute it and/or modify it under the terms of the GNU
12
* General Public License (GPL) as published by the Free Software
13
* Foundation, in version 2 as it comes in the "COPYING" file of the
14
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17
* The contents of this file may alternatively be used under the terms
18
* of the Common Development and Distribution License Version 1.0
19
* (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20
* VirtualBox OSE distribution, in which case the provisions of the
21
* CDDL are applicable instead of those of the GPL.
23
* You may elect to license modified versions of this file under the
24
* terms and conditions of either the GPL or the CDDL or both.
27
/*******************************************************************************
29
*******************************************************************************/
33
#include <iprt/initterm.h>
35
#include <iprt/rand.h>
36
#include <iprt/stdarg.h>
37
#include <iprt/string.h>
38
#include <iprt/test.h>
41
/*******************************************************************************
42
* Structures and Typedefs *
43
*******************************************************************************/
44
typedef struct TRACKER
46
/** The max key value (exclusive). */
48
/** The last allocated key. */
49
uint32_t LastAllocatedKey;
50
/** The number of set bits in the bitmap. */
52
/** The bitmap size. */
54
/** Bitmap containing the allocated nodes. */
59
/*******************************************************************************
61
*******************************************************************************/
62
static RTTEST g_hTest;
63
static RTRAND g_hRand;
67
* Creates a new tracker.
69
* @returns Pointer to the new tracker.
70
* @param MaxKey The max key value for the tracker. (exclusive)
72
static PTRACKER TrackerCreate(uint32_t MaxKey)
74
uint32_t cbBitmap = (MaxKey + sizeof(uint32_t) * sizeof(uint8_t) - 1) / sizeof(uint8_t);
75
PTRACKER pTracker = (PTRACKER)RTMemAllocZ(RT_OFFSETOF(TRACKER, abBitmap[cbBitmap]));
78
pTracker->MaxKey = MaxKey;
79
pTracker->LastAllocatedKey = MaxKey;
80
pTracker->cbBitmap = cbBitmap;
81
Assert(pTracker->cSetBits == 0);
90
* @param pTracker The tracker.
92
static void TrackerDestroy(PTRACKER pTracker)
99
* Inserts a key range into the tracker.
101
* @returns success indicator.
102
* @param pTracker The tracker.
103
* @param Key The first key in the range.
104
* @param KeyLast The last key in the range. (inclusive)
106
static bool TrackerInsert(PTRACKER pTracker, uint32_t Key, uint32_t KeyLast)
108
bool fRc = !ASMBitTestAndSet(pTracker->abBitmap, Key);
110
pTracker->cSetBits++;
111
while (KeyLast != Key)
113
if (!ASMBitTestAndSet(pTracker->abBitmap, KeyLast))
114
pTracker->cSetBits++;
124
* Removes a key range from the tracker.
126
* @returns success indicator.
127
* @param pTracker The tracker.
128
* @param Key The first key in the range.
129
* @param KeyLast The last key in the range. (inclusive)
131
static bool TrackerRemove(PTRACKER pTracker, uint32_t Key, uint32_t KeyLast)
133
bool fRc = ASMBitTestAndClear(pTracker->abBitmap, Key);
135
pTracker->cSetBits--;
136
while (KeyLast != Key)
138
if (ASMBitTestAndClear(pTracker->abBitmap, KeyLast))
139
pTracker->cSetBits--;
149
* Random key range allocation.
151
* @returns success indicator.
152
* @param pTracker The tracker.
153
* @param pKey Where to store the first key in the allocated range.
154
* @param pKeyLast Where to store the first key in the allocated range.
155
* @param cMaxKey The max range length.
156
* @remark The caller has to call TrackerInsert.
158
static bool TrackerNewRandomEx(PTRACKER pTracker, uint32_t *pKey, uint32_t *pKeyLast, uint32_t cMaxKeys)
163
uint32_t Key = RTRandAdvU32Ex(g_hRand, 0, pTracker->MaxKey - 1);
164
if (ASMBitTest(pTracker->abBitmap, Key))
166
if (pTracker->cSetBits >= pTracker->MaxKey)
169
int Key2 = ASMBitNextClear(pTracker->abBitmap, pTracker->MaxKey, Key);
174
/* we're missing a ASMBitPrevClear function, so just try another, lower, value.*/
177
const uint32_t KeyPrev = Key;
178
Key = RTRandAdvU32Ex(g_hRand, 0, KeyPrev - 1);
179
if (!ASMBitTest(pTracker->abBitmap, Key))
181
Key2 = ASMBitNextClear(pTracker->abBitmap, RT_ALIGN_32(KeyPrev, 32), Key);
192
* Determine the range.
195
if (cMaxKeys == 1 || !pKeyLast)
199
uint32_t cKeys = RTRandAdvU32Ex(g_hRand, 0, RT_MIN(pTracker->MaxKey - Key, cMaxKeys - 1));
200
KeyLast = Key + cKeys;
201
int Key2 = ASMBitNextSet(pTracker->abBitmap, RT_ALIGN_32(KeyLast, 32), Key);
203
&& (unsigned)Key2 <= KeyLast)
218
* Random single key allocation.
220
* @returns success indicator.
221
* @param pTracker The tracker.
222
* @param pKey Where to store the allocated key.
223
* @remark The caller has to call TrackerInsert.
225
static bool TrackerNewRandom(PTRACKER pTracker, uint32_t *pKey)
227
return TrackerNewRandomEx(pTracker, pKey, NULL, 1);
232
* Random single key 'lookup'.
234
* @returns success indicator.
235
* @param pTracker The tracker.
236
* @param pKey Where to store the allocated key.
237
* @remark The caller has to call TrackerRemove.
239
static bool TrackerFindRandom(PTRACKER pTracker, uint32_t *pKey)
241
uint32_t Key = RTRandAdvU32Ex(g_hRand, 0, pTracker->MaxKey - 1);
242
if (!ASMBitTest(pTracker->abBitmap, Key))
244
if (!pTracker->cSetBits)
247
int Key2 = ASMBitNextSet(pTracker->abBitmap, pTracker->MaxKey, Key);
252
/* we're missing a ASMBitPrevSet function, so here's a quick replacement hack. */
253
uint32_t *pu32Start = (uint32_t *)&pTracker->abBitmap[0];
254
uint32_t *pu32Cur = (uint32_t *)&pTracker->abBitmap[Key >> 8];
255
while (pu32Cur >= pu32Start)
259
*pKey = ASMBitLastSetU32(*pu32Cur) - 1 + (uint32_t)((pu32Cur - pu32Start) * 32);
264
Key2 = ASMBitFirstSet(pTracker->abBitmap, pTracker->MaxKey);
267
RTTestIFailed("cSetBits=%u - but ASMBitFirstSet failed to find any", pTracker->cSetBits);
280
bool TrackerAllocSeq(PTRACKER pTracker, uint32_t *pKey, uint32_t *pKeyLast, uint32_t cMaxKeys)
287
* Prints an unbuffered char.
288
* @param ch The char.
290
static void ProgressChar(char ch)
292
//RTTestIPrintf(RTTESTLVL_INFO, "%c", ch);
293
RTTestIPrintf(RTTESTLVL_SUB_TEST, "%c", ch);
297
* Prints a progress indicator label.
298
* @param cMax The max number of operations (exclusive).
299
* @param pszFormat The format string.
300
* @param ... The arguments to the format string.
302
DECLINLINE(void) ProgressPrintf(unsigned cMax, const char *pszFormat, ...)
308
va_start(va, pszFormat);
309
//RTTestIPrintfV(RTTESTLVL_INFO, pszFormat, va);
310
RTTestIPrintfV(RTTESTLVL_SUB_TEST, pszFormat, va);
316
* Prints a progress indicator dot.
317
* @param iCur The current operation. (can be descending too)
318
* @param cMax The max number of operations (exclusive).
320
DECLINLINE(void) Progress(unsigned iCur, unsigned cMax)
324
if (!(iCur % (cMax / 20)))
329
static int avlogcphys(unsigned cMax)
332
* Simple linear insert and remove.
335
RTTestISubF("oGCPhys(%d): linear left", cMax);
336
PAVLOGCPHYSTREE pTree = (PAVLOGCPHYSTREE)RTMemAllocZ(sizeof(*pTree));
338
for (i = 0; i < cMax; i++)
341
PAVLOGCPHYSNODECORE pNode = (PAVLOGCPHYSNODECORE)RTMemAlloc(sizeof(*pNode));
343
if (!RTAvloGCPhysInsert(pTree, pNode))
345
RTTestIFailed("linear left insert i=%d\n", i);
349
AVLOGCPHYSNODECORE Node = *pNode;
350
if (RTAvloGCPhysInsert(pTree, &Node))
352
RTTestIFailed("linear left negative insert i=%d\n", i);
357
ProgressPrintf(cMax, "~");
358
for (i = 0; i < cMax; i++)
361
PAVLOGCPHYSNODECORE pNode = RTAvloGCPhysRemove(pTree, i);
364
RTTestIFailed("linear left remove i=%d\n", i);
367
memset(pNode, 0xcc, sizeof(*pNode));
371
pNode = RTAvloGCPhysRemove(pTree, i);
374
RTTestIFailed("linear left negative remove i=%d\n", i);
380
* Simple linear insert and remove from the right.
383
RTTestISubF("oGCPhys(%d): linear right", cMax);
384
for (i = 0; i < cMax; i++)
387
PAVLOGCPHYSNODECORE pNode = (PAVLOGCPHYSNODECORE)RTMemAlloc(sizeof(*pNode));
389
if (!RTAvloGCPhysInsert(pTree, pNode))
391
RTTestIFailed("linear right insert i=%d\n", i);
395
AVLOGCPHYSNODECORE Node = *pNode;
396
if (RTAvloGCPhysInsert(pTree, &Node))
398
RTTestIFailed("linear right negative insert i=%d\n", i);
403
ProgressPrintf(cMax, "~");
407
PAVLOGCPHYSNODECORE pNode = RTAvloGCPhysRemove(pTree, i);
410
RTTestIFailed("linear right remove i=%d\n", i);
413
memset(pNode, 0xcc, sizeof(*pNode));
417
pNode = RTAvloGCPhysRemove(pTree, i);
420
RTTestIFailed("linear right negative remove i=%d\n", i);
426
* Linear insert but root based removal.
429
RTTestISubF("oGCPhys(%d): linear root", cMax);
430
for (i = 0; i < cMax; i++)
433
PAVLOGCPHYSNODECORE pNode = (PAVLOGCPHYSNODECORE)RTMemAlloc(sizeof(*pNode));
435
if (!RTAvloGCPhysInsert(pTree, pNode))
437
RTTestIFailed("linear root insert i=%d\n", i);
441
AVLOGCPHYSNODECORE Node = *pNode;
442
if (RTAvloGCPhysInsert(pTree, &Node))
444
RTTestIFailed("linear root negative insert i=%d\n", i);
449
ProgressPrintf(cMax, "~");
453
PAVLOGCPHYSNODECORE pNode = (PAVLOGCPHYSNODECORE)((intptr_t)pTree + *pTree);
454
RTGCPHYS Key = pNode->Key;
455
pNode = RTAvloGCPhysRemove(pTree, Key);
458
RTTestIFailed("linear root remove i=%d Key=%d\n", i, (unsigned)Key);
461
memset(pNode, 0xcc, sizeof(*pNode));
465
pNode = RTAvloGCPhysRemove(pTree, Key);
468
RTTestIFailed("linear root negative remove i=%d Key=%d\n", i, (unsigned)Key);
474
RTTestIFailed("sparse remove didn't remove it all!\n");
479
* Make a sparsely populated tree and remove the nodes using best fit in 5 cycles.
481
const unsigned cMaxSparse = RT_ALIGN(cMax, 32);
482
if (cMaxSparse >= 10000)
483
RTTestISubF("oGCPhys(%d): sparse", cMax);
484
for (i = 0; i < cMaxSparse; i += 8)
486
Progress(i, cMaxSparse);
487
PAVLOGCPHYSNODECORE pNode = (PAVLOGCPHYSNODECORE)RTMemAlloc(sizeof(*pNode));
489
if (!RTAvloGCPhysInsert(pTree, pNode))
491
RTTestIFailed("sparse insert i=%d\n", i);
495
AVLOGCPHYSNODECORE Node = *pNode;
496
if (RTAvloGCPhysInsert(pTree, &Node))
498
RTTestIFailed("sparse negative insert i=%d\n", i);
503
/* Remove using best fit in 5 cycles. */
504
ProgressPrintf(cMaxSparse, "~");
506
for (j = 0; j < 4; j++)
508
for (i = 0; i < cMaxSparse; i += 8 * 4)
510
Progress(i, cMax); // good enough
511
PAVLOGCPHYSNODECORE pNode = RTAvloGCPhysRemoveBestFit(pTree, i, true);
514
RTTestIFailed("sparse remove i=%d j=%d\n", i, j);
517
if (pNode->Key - (unsigned long)i >= 8 * 4)
519
RTTestIFailed("sparse remove i=%d j=%d Key=%d\n", i, j, (unsigned)pNode->Key);
522
memset(pNode, 0xdd, sizeof(*pNode));
528
RTTestIFailed("sparse remove didn't remove it all!\n");
532
ProgressPrintf(cMaxSparse, "\n");
537
int avlogcphysRand(unsigned cMax, unsigned cMax2)
539
PAVLOGCPHYSTREE pTree = (PAVLOGCPHYSTREE)RTMemAllocZ(sizeof(*pTree));
546
RTTestISubF("oGCPhys(%d, %d): random", cMax, cMax2);
547
PTRACKER pTracker = TrackerCreate(cMax2);
550
RTTestIFailed("failed to create %d tracker!\n", cMax2);
554
/* Insert a number of nodes in random order. */
555
for (i = 0; i < cMax; i++)
559
if (!TrackerNewRandom(pTracker, &Key))
561
RTTestIFailed("failed to allocate node no. %d\n", i);
562
TrackerDestroy(pTracker);
565
PAVLOGCPHYSNODECORE pNode = (PAVLOGCPHYSNODECORE)RTMemAlloc(sizeof(*pNode));
567
if (!RTAvloGCPhysInsert(pTree, pNode))
569
RTTestIFailed("random insert i=%d Key=%#x\n", i, Key);
573
AVLOGCPHYSNODECORE Node = *pNode;
574
if (RTAvloGCPhysInsert(pTree, &Node))
576
RTTestIFailed("linear negative insert i=%d Key=%#x\n", i, Key);
579
TrackerInsert(pTracker, Key, Key);
583
/* delete the nodes in random order. */
584
ProgressPrintf(cMax, "~");
589
if (!TrackerFindRandom(pTracker, &Key))
591
RTTestIFailed("failed to find free node no. %d\n", i);
592
TrackerDestroy(pTracker);
596
PAVLOGCPHYSNODECORE pNode = RTAvloGCPhysRemove(pTree, Key);
599
RTTestIFailed("random remove i=%d Key=%#x\n", i, Key);
602
if (pNode->Key != Key)
604
RTTestIFailed("random remove i=%d Key=%#x pNode->Key=%#x\n", i, Key, (unsigned)pNode->Key);
607
TrackerRemove(pTracker, Key, Key);
608
memset(pNode, 0xdd, sizeof(*pNode));
613
RTTestIFailed("random remove didn't remove it all!\n");
616
ProgressPrintf(cMax, "\n");
617
TrackerDestroy(pTracker);
624
int avlrogcphys(void)
629
PAVLROGCPHYSTREE pTree = (PAVLROGCPHYSTREE)RTMemAllocZ(sizeof(*pTree));
631
AssertCompileSize(AVLOGCPHYSNODECORE, 24);
632
AssertCompileSize(AVLROGCPHYSNODECORE, 32);
634
RTTestISubF("RTAvlroGCPhys");
637
* Simple linear insert, get and remove.
640
for (i = 0; i < 65536; i += 4)
642
PAVLROGCPHYSNODECORE pNode = (PAVLROGCPHYSNODECORE)RTMemAlloc(sizeof(*pNode));
644
pNode->KeyLast = i + 3;
645
if (!RTAvlroGCPhysInsert(pTree, pNode))
647
RTTestIFailed("linear insert i=%d\n", (unsigned)i);
652
AVLROGCPHYSNODECORE Node = *pNode;
653
for (j = i + 3; j > i - 32; j--)
655
for (k = i; k < i + 32; k++)
657
Node.Key = RT_MIN(j, k);
658
Node.KeyLast = RT_MAX(k, j);
659
if (RTAvlroGCPhysInsert(pTree, &Node))
661
RTTestIFailed("linear negative insert i=%d j=%d k=%d\n", i, j, k);
669
for (i = 0; i < 65536; i += 4)
671
PAVLROGCPHYSNODECORE pNode = RTAvlroGCPhysGet(pTree, i);
674
RTTestIFailed("linear get i=%d\n", i);
677
if (pNode->Key > i || pNode->KeyLast < i)
679
RTTestIFailed("linear get i=%d Key=%d KeyLast=%d\n", i, (unsigned)pNode->Key, (unsigned)pNode->KeyLast);
683
for (j = 0; j < 4; j++)
685
if (RTAvlroGCPhysRangeGet(pTree, i + j) != pNode)
687
RTTestIFailed("linear range get i=%d j=%d\n", i, j);
693
if ( RTAvlroGCPhysGet(pTree, i + 1)
694
|| RTAvlroGCPhysGet(pTree, i + 2)
695
|| RTAvlroGCPhysGet(pTree, i + 3))
697
RTTestIFailed("linear negative get i=%d + n\n", i);
704
for (i = 0; i < 65536; i += 4)
706
PAVLROGCPHYSNODECORE pNode = RTAvlroGCPhysRemove(pTree, i);
709
RTTestIFailed("linear remove i=%d\n", i);
712
memset(pNode, 0xcc, sizeof(*pNode));
716
if ( RTAvlroGCPhysRemove(pTree, i)
717
|| RTAvlroGCPhysRemove(pTree, i + 1)
718
|| RTAvlroGCPhysRemove(pTree, i + 2)
719
|| RTAvlroGCPhysRemove(pTree, i + 3))
721
RTTestIFailed("linear negative remove i=%d + n\n", i);
727
* Make a sparsely populated tree.
729
for (i = 0; i < 65536; i += 8)
731
PAVLROGCPHYSNODECORE pNode = (PAVLROGCPHYSNODECORE)RTMemAlloc(sizeof(*pNode));
733
pNode->KeyLast = i + 3;
734
if (!RTAvlroGCPhysInsert(pTree, pNode))
736
RTTestIFailed("sparse insert i=%d\n", i);
740
AVLROGCPHYSNODECORE Node = *pNode;
741
const RTGCPHYS jMin = i > 32 ? i - 32 : 1;
742
const RTGCPHYS kMax = i + 32;
743
for (j = pNode->KeyLast; j >= jMin; j--)
745
for (k = pNode->Key; k < kMax; k++)
747
Node.Key = RT_MIN(j, k);
748
Node.KeyLast = RT_MAX(k, j);
749
if (RTAvlroGCPhysInsert(pTree, &Node))
751
RTTestIFailed("sparse negative insert i=%d j=%d k=%d\n", i, j, k);
759
* Get and Remove using range matching in 5 cycles.
761
for (j = 0; j < 4; j++)
763
for (i = 0; i < 65536; i += 8 * 4)
766
RTGCPHYS KeyBase = i + j * 8;
767
PAVLROGCPHYSNODECORE pNode = RTAvlroGCPhysGet(pTree, KeyBase);
770
RTTestIFailed("sparse get i=%d j=%d KeyBase=%d\n", i, j, (unsigned)KeyBase);
773
if (pNode->Key > KeyBase || pNode->KeyLast < KeyBase)
775
RTTestIFailed("sparse get i=%d j=%d KeyBase=%d pNode->Key=%d\n", i, j, (unsigned)KeyBase, (unsigned)pNode->Key);
778
for (k = KeyBase; k < KeyBase + 4; k++)
780
if (RTAvlroGCPhysRangeGet(pTree, k) != pNode)
782
RTTestIFailed("sparse range get i=%d j=%d k=%d\n", i, j, k);
788
for (k = i + j; k < KeyBase + 8; k++)
791
&& RTAvlroGCPhysGet(pTree, k))
793
RTTestIFailed("sparse negative get i=%d j=%d k=%d\n", i, j, k);
797
for (k = i + j; k < KeyBase; k++)
799
if (RTAvlroGCPhysRangeGet(pTree, k))
801
RTTestIFailed("sparse negative range get i=%d j=%d k=%d\n", i, j, k);
805
for (k = KeyBase + 4; k < KeyBase + 8; k++)
807
if (RTAvlroGCPhysRangeGet(pTree, k))
809
RTTestIFailed("sparse negative range get i=%d j=%d k=%d\n", i, j, k);
815
RTGCPHYS Key = KeyBase + ((i / 19) % 4);
816
if (RTAvlroGCPhysRangeRemove(pTree, Key) != pNode)
818
RTTestIFailed("sparse remove i=%d j=%d Key=%d\n", i, j, (unsigned)Key);
821
memset(pNode, 0xdd, sizeof(*pNode));
827
RTTestIFailed("sparse remove didn't remove it all!\n");
833
* Realworld testcase.
837
AVLROGCPHYSTREE Tree;
838
AVLROGCPHYSNODECORE aNode[4];
844
s1.aNode[0].Key = 0x00030000;
845
s1.aNode[0].KeyLast = 0x00030fff;
846
s1.aNode[1].Key = 0x000a0000;
847
s1.aNode[1].KeyLast = 0x000bffff;
848
s1.aNode[2].Key = 0xe0000000;
849
s1.aNode[2].KeyLast = 0xe03fffff;
850
s1.aNode[3].Key = 0xfffe0000;
851
s1.aNode[3].KeyLast = 0xfffe0ffe;
852
for (i = 0; i < RT_ELEMENTS(s1.aNode); i++)
854
PAVLROGCPHYSNODECORE pNode = &s1.aNode[i];
855
if (!RTAvlroGCPhysInsert(&s1.Tree, pNode))
857
RTTestIFailed("real insert i=%d\n", i);
860
if (RTAvlroGCPhysInsert(&s1.Tree, pNode))
862
RTTestIFailed("real negative insert i=%d\n", i);
865
if (RTAvlroGCPhysGet(&s1.Tree, pNode->Key) != pNode)
867
RTTestIFailed("real get (1) i=%d\n", i);
870
if (RTAvlroGCPhysGet(&s1.Tree, pNode->KeyLast) != NULL)
872
RTTestIFailed("real negative get (2) i=%d\n", i);
875
if (RTAvlroGCPhysRangeGet(&s1.Tree, pNode->Key) != pNode)
877
RTTestIFailed("real range get (1) i=%d\n", i);
880
if (RTAvlroGCPhysRangeGet(&s1.Tree, pNode->Key + 1) != pNode)
882
RTTestIFailed("real range get (2) i=%d\n", i);
885
if (RTAvlroGCPhysRangeGet(&s1.Tree, pNode->KeyLast) != pNode)
887
RTTestIFailed("real range get (3) i=%d\n", i);
894
for (i = 0; i < RT_ELEMENTS(s3.aNode); i++)
896
PAVLROGCPHYSNODECORE pNode = &s3.aNode[i];
897
if (RTAvlroGCPhysGet(&s3.Tree, pNode->Key) != pNode)
899
RTTestIFailed("real get (10) i=%d\n", i);
902
if (RTAvlroGCPhysRangeGet(&s3.Tree, pNode->Key) != pNode)
904
RTTestIFailed("real range get (10) i=%d\n", i);
911
if (RTAvlroGCPhysGet(&s3.Tree, j) != NULL)
913
RTTestIFailed("real negative get (11) i=%d j=%#x\n", i, j);
916
if (RTAvlroGCPhysRangeGet(&s3.Tree, j) != pNode)
918
RTTestIFailed("real range get (11) i=%d j=%#x\n", i, j);
921
} while (j++ < pNode->KeyLast);
930
RTTestISubF("RTAvlUL");
933
* Simple linear insert and remove.
935
PAVLULNODECORE pTree = 0;
938
for (i = 0; i < 65536; i++)
940
PAVLULNODECORE pNode = (PAVLULNODECORE)RTMemAlloc(sizeof(*pNode));
942
if (!RTAvlULInsert(&pTree, pNode))
944
RTTestIFailed("linear insert i=%d\n", i);
948
AVLULNODECORE Node = *pNode;
949
if (RTAvlULInsert(&pTree, &Node))
951
RTTestIFailed("linear negative insert i=%d\n", i);
956
for (i = 0; i < 65536; i++)
958
PAVLULNODECORE pNode = RTAvlULRemove(&pTree, i);
961
RTTestIFailed("linear remove i=%d\n", i);
964
pNode->pLeft = (PAVLULNODECORE)0xaaaaaaaa;
965
pNode->pRight = (PAVLULNODECORE)0xbbbbbbbb;
966
pNode->uchHeight = 'e';
970
pNode = RTAvlULRemove(&pTree, i);
973
RTTestIFailed("linear negative remove i=%d\n", i);
979
* Make a sparsely populated tree.
981
for (i = 0; i < 65536; i += 8)
983
PAVLULNODECORE pNode = (PAVLULNODECORE)RTMemAlloc(sizeof(*pNode));
985
if (!RTAvlULInsert(&pTree, pNode))
987
RTTestIFailed("linear insert i=%d\n", i);
991
AVLULNODECORE Node = *pNode;
992
if (RTAvlULInsert(&pTree, &Node))
994
RTTestIFailed("linear negative insert i=%d\n", i);
1000
* Remove using best fit in 5 cycles.
1003
for (j = 0; j < 4; j++)
1005
for (i = 0; i < 65536; i += 8 * 4)
1007
PAVLULNODECORE pNode = RTAvlULRemoveBestFit(&pTree, i, true);
1008
//PAVLULNODECORE pNode = RTAvlULRemove(&pTree, i + j * 8);
1011
RTTestIFailed("sparse remove i=%d j=%d\n", i, j);
1014
pNode->pLeft = (PAVLULNODECORE)0xdddddddd;
1015
pNode->pRight = (PAVLULNODECORE)0xcccccccc;
1016
pNode->uchHeight = 'E';
1031
int rc = RTTestInitAndCreate("tstRTAvl", &hTest);
1034
RTTestBanner(hTest);
1037
rc = RTRandAdvCreateParkMiller(&g_hRand);
1040
RTTestIFailed("RTRandAdvCreateParkMiller -> %Rrc", rc);
1041
return RTTestSummaryAndDestroy(hTest);
1048
RTTestSub(hTest, "oGCPhys(32..2048)");
1049
for (i = 32; i < 2048; i++)
1057
RTTestISubF("oGCPhys(32..2048, *1K)");
1058
for (i = 32; i < 4096; i++)
1059
if (avlogcphysRand(i, i + _1K))
1061
for (; i <= _4M; i *= 2)
1062
if (avlogcphysRand(i, i * 8))
1071
return RTTestSummaryAndDestroy(hTest);