2 * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
10 * based on ftp://ftp.cs.cmu.edu/user/sleator/splaying/top-down-splay.c
11 * http://bobo.link.cs.cmu.edu/cgi-bin/splay/splay-cgi.pl
31 intnode (int anInt
) : i (anInt
) {}
37 compareintvoid(void *const &a
, void *const &n
)
39 intnode
*A
= (intnode
*)a
;
40 intnode
*B
= (intnode
*)n
;
45 compareint(intnode
*const &a
, intnode
*const &b
)
54 static void BeginWalk();
56 static bool ExpectedFail
;
57 static void WalkVoid(void *const &, void *);
58 static void WalkNode(intnode
*const &, void *);
59 static void WalkNodeRef(intnode
const &, void *);
60 static void CheckNode(intnode
const &);
63 int SplayCheck::LastValue (0);
64 bool SplayCheck::ExpectedFail (false);
67 SplayCheck::BeginWalk()
73 SplayCheck::WalkVoid(void *const &node
, void *)
75 intnode
*A
= (intnode
*)node
;
80 SplayCheck::CheckNode(intnode
const &A
)
82 if (LastValue
> A
.i
) {
96 SplayCheck::WalkNode (intnode
*const &a
, void *)
102 SplayCheck::WalkNodeRef (intnode
const &a
, void *)
108 destintvoid(void *&data
)
110 intnode
*i
= (intnode
*)data
;
115 destint(intnode
*&data
)
121 compareintref(intnode
const &a
, intnode
const &b
)
127 destintref(intnode
&)
133 std::mt19937 generator
;
134 xuniform_int_distribution
<int> distribution
;
135 auto nextRandom
= std::bind (distribution
, generator
);
138 /* test void * splay containers */
139 splayNode
*top
= NULL
;
141 for (int i
= 0; i
< 100; ++i
) {
142 intnode
*I
= (intnode
*)xcalloc(sizeof(intnode
), 1);
145 top
= top
->insert(I
, compareintvoid
);
147 top
= new splayNode(static_cast<void*>(new intnode(101)));
150 SplayCheck::BeginWalk();
151 top
->walk(SplayCheck::WalkVoid
, NULL
);
153 SplayCheck::BeginWalk();
154 top
->walk(SplayCheck::WalkVoid
, NULL
);
155 top
->destroy(destintvoid
);
158 /* test typesafe splay containers */
161 SplayNode
<intnode
*> *safeTop
= new SplayNode
<intnode
*>(new intnode(101));
163 for ( int i
= 0; i
< 100; ++i
) {
167 safeTop
= safeTop
->insert(I
, compareint
);
170 SplayCheck::BeginWalk();
171 safeTop
->walk(SplayCheck::WalkNode
, NULL
);
173 safeTop
->destroy(destint
);
177 SplayNode
<intnode
> *safeTop
= new SplayNode
<intnode
>(101);
179 for (int i
= 0; i
< 100; ++i
) {
182 safeTop
= safeTop
->insert(I
, compareintref
);
185 SplayCheck::BeginWalk();
186 safeTop
->walk(SplayCheck::WalkNodeRef
, NULL
);
188 safeTop
->destroy(destintref
);
191 /* check the check routine */
193 SplayCheck::BeginWalk();
196 /* check we don't segfault on NULL splay calls */
197 SplayCheck::WalkNodeRef(I
, NULL
);
199 SplayCheck::ExpectedFail
= true;
200 SplayCheck::WalkNodeRef(I
, NULL
);
204 /* check for begin() */
205 Splay
<intnode
> *safeTop
= new Splay
<intnode
>();
207 if (safeTop
->start() != NULL
)
210 if (safeTop
->finish() != NULL
)
213 for (int i
= 0; i
< 100; ++i
) {
217 if (I
.i
> 50 && I
.i
< 10000000)
218 safeTop
->insert(I
, compareintref
);
224 safeTop
->insert (I
, compareintref
);
226 safeTop
->insert (I
, compareintref
);
229 if (!safeTop
->start())
232 if (safeTop
->start()->data
.i
!= 50)
235 if (!safeTop
->finish())
238 if (safeTop
->finish()->data
.i
!= 10000000)
241 safeTop
->destroy(destintref
);
245 Splay
<intnode
*> aSplay
;
247 if (aSplay
.start() != NULL
)
250 if (aSplay
.size() != 0)
253 aSplay
.insert (new intnode(5), compareint
);
255 if (aSplay
.start() == NULL
)
258 if (aSplay
.size() != 1)
261 aSplay
.destroy(destint
);
263 if (aSplay
.start() != NULL
)
266 if (aSplay
.size() != 0)
270 /* TODO: also test the other Splay API */