]>
git.ipfire.org Git - thirdparty/squid.git/blob - include/splay.h
15 typedef int SPLAYCMP(Value
const &a
, Value
const &b
);
16 typedef void SPLAYFREE(Value
&);
17 typedef void SPLAYWALKEE(Value
const & nodedata
, void *state
);
18 static void DefaultFree (Value
&aValue
) {delete aValue
;}
20 SplayNode
<V
> (Value
const &);
22 mutable SplayNode
<V
> *left
;
23 mutable SplayNode
<V
> *right
;
24 void destroy(SPLAYFREE
*);
25 void walk(SPLAYWALKEE
*, void *callerState
);
26 bool empty() const { return this == NULL
; }
27 SplayNode
<V
> const * start() const;
28 SplayNode
<V
> const * finish() const;
30 SplayNode
<V
> * remove(const Value data
, SPLAYCMP
* compare
);
32 SplayNode
<V
> * insert(Value data
, SPLAYCMP
* compare
);
34 template <class FindValue
> SplayNode
<V
> * splay(const FindValue
&data
, int( * compare
)(FindValue
const &a
, Value
const &b
)) const;
37 typedef SplayNode
<void *> splayNode
;
40 class SplayConstIterator
;
51 typedef int SPLAYCMP(Value
const &a
, Value
const &b
);
52 typedef void SPLAYFREE(Value
&);
53 typedef SplayIterator
<V
> iterator
;
54 typedef const SplayConstIterator
<V
> const_iterator
;
55 Splay():head(NULL
), elements (0) {}
57 mutable SplayNode
<V
> * head
;
58 template <class FindValue
> Value
const *find (FindValue
const &, int( * compare
)(FindValue
const &a
, Value
const &b
)) const;
59 void insert(Value
const &, SPLAYCMP
*compare
);
61 void remove(Value
const &, SPLAYCMP
*compare
);
63 void destroy(SPLAYFREE
*);
65 SplayNode
<V
> const * start() const;
67 SplayNode
<V
> const * finish() const;
71 const_iterator
begin() const;
73 const_iterator
end() const;
78 SQUIDCEXTERN
int splayLastResult
;
80 SQUIDCEXTERN splayNode
*splay_insert(void *, splayNode
*, splayNode::SPLAYCMP
*);
82 SQUIDCEXTERN splayNode
*splay_delete(const void *, splayNode
*, splayNode::SPLAYCMP
*);
84 SQUIDCEXTERN splayNode
*splay_splay(const void **, splayNode
*, splayNode::SPLAYCMP
*);
86 SQUIDCEXTERN
void splay_destroy(splayNode
*, splayNode::SPLAYFREE
*);
88 SQUIDCEXTERN
void splay_walk(splayNode
*, splayNode::SPLAYWALKEE
*, void *callerState
);
92 SplayNode
<V
>::SplayNode (Value
const &someData
) : data(someData
), left(NULL
), right (NULL
) {}
96 SplayNode
<V
>::walk(SPLAYWALKEE
* walkee
, void *state
)
102 left
->walk(walkee
, state
);
107 right
->walk(walkee
, state
);
112 SplayNode
<V
>::start() const
115 return left
->start();
122 SplayNode
<V
>::finish() const
125 return right
->finish();
132 SplayNode
<V
>::destroy(SPLAYFREE
* free_func
)
138 left
->destroy(free_func
);
141 right
->destroy(free_func
);
150 SplayNode
<V
>::remove(Value
const dataToRemove
, SPLAYCMP
* compare
)
155 SplayNode
<V
> *result
= splay(dataToRemove
, compare
);
157 if (splayLastResult
== 0) { /* found it */
158 SplayNode
<V
> *newTop
;
160 if (result
->left
== NULL
) {
161 newTop
= result
->right
;
163 newTop
= result
->left
->splay(dataToRemove
, compare
);
165 newTop
->right
= result
->right
;
166 result
->right
= NULL
;
173 return result
; /* It wasn't there */
178 SplayNode
<V
>::insert(Value dataToInsert
, SPLAYCMP
* compare
)
180 /* create node to insert */
181 SplayNode
<V
> *newNode
= new SplayNode
<V
>(dataToInsert
);
184 splayLastResult
= -1;
185 newNode
->left
= newNode
->right
= NULL
;
189 SplayNode
<V
> *newTop
= splay(dataToInsert
, compare
);
191 if (splayLastResult
< 0) {
192 newNode
->left
= newTop
->left
;
193 newNode
->right
= newTop
;
196 } else if (splayLastResult
> 0) {
197 newNode
->right
= newTop
->right
;
198 newNode
->left
= newTop
;
199 newTop
->right
= NULL
;
202 /* duplicate entry */
209 template<class FindValue
>
211 SplayNode
<V
>::splay(FindValue
const &dataToFind
, int( * compare
)(FindValue
const &a
, Value
const &b
)) const
214 /* can't have compared successfully :} */
215 splayLastResult
= -1;
219 Value temp
= Value();
220 SplayNode
<V
> N(temp
);
224 N
.left
= N
.right
= NULL
;
227 SplayNode
<V
> *top
= const_cast<SplayNode
<V
> *>(this);
230 splayLastResult
= compare(dataToFind
, top
->data
);
232 if (splayLastResult
< 0) {
233 if (top
->left
== NULL
)
236 if ((splayLastResult
= compare(dataToFind
, top
->left
->data
)) < 0) {
237 y
= top
->left
; /* rotate right */
238 top
->left
= y
->right
;
242 if (top
->left
== NULL
)
246 r
->left
= top
; /* link right */
249 } else if (splayLastResult
> 0) {
250 if (top
->right
== NULL
)
253 if ((splayLastResult
= compare(dataToFind
, top
->right
->data
)) > 0) {
254 y
= top
->right
; /* rotate left */
255 top
->right
= y
->left
;
259 if (top
->right
== NULL
)
263 l
->right
= top
; /* link left */
271 l
->right
= top
->left
; /* assemble */
272 r
->left
= top
->right
;
279 template <class FindValue
>
280 typename Splay
<V
>::Value
const *
281 Splay
<V
>::find (FindValue
const &value
, int( * compare
)(FindValue
const &a
, Value
const &b
)) const
283 head
= head
->splay(value
, compare
);
285 if (splayLastResult
!= 0)
293 Splay
<V
>::insert(Value
const &value
, SPLAYCMP
*compare
)
295 assert (!find (value
, compare
));
296 head
= head
->insert(value
, compare
);
302 Splay
<V
>::remove(Value
const &value
, SPLAYCMP
*compare
)
304 assert (find (value
, compare
));
306 head
= head
->remove(value
, compare
);
313 Splay
<V
>:: start() const
316 return head
->start();
323 Splay
<V
>:: finish() const
326 return head
->finish();
333 Splay
<V
>:: destroy(SPLAYFREE
*free_func
)
336 head
->destroy(free_func
);
345 Splay
<V
>::size() const
351 const SplayConstIterator
<V
>
352 Splay
<V
>::begin() const
354 return const_iterator(head
);
358 const SplayConstIterator
<V
>
359 Splay
<V
>::end() const
361 return const_iterator(NULL
);
365 class SplayConstIterator
369 typedef const V value_type
;
370 SplayConstIterator (SplayNode
<V
> *aNode
);
371 bool operator == (SplayConstIterator
const &right
) const;
372 SplayConstIterator
operator ++ (int dummy
);
373 SplayConstIterator
&operator ++ ();
374 V
const & operator * () const;
378 void addLeftPath(SplayNode
<V
> *aNode
);
379 void init(SplayNode
<V
> *);
380 Stack
<SplayNode
<V
> *> toVisit
;
384 SplayConstIterator
<V
>::SplayConstIterator (SplayNode
<V
> *aNode
)
391 SplayConstIterator
<V
>::operator == (SplayConstIterator
const &right
) const
393 return toVisit
.top() == right
.toVisit
.top();
397 SplayConstIterator
<V
> &
398 SplayConstIterator
<V
>::operator ++ ()
405 SplayConstIterator
<V
>
406 SplayConstIterator
<V
>::operator ++ (int dummy
)
408 SplayConstIterator
<V
> result
= *this;
413 /* advance is simple enough:
414 * if the stack is empty, we're done.
415 * otherwise, pop the last visited node
416 * then, pop the next node to visit
417 * if that has a right child, add it and it's
419 * then add the node back.
423 SplayConstIterator
<V
>::advance()
425 if (toVisit
.size() == 0)
430 if (toVisit
.size() == 0)
433 SplayNode
<V
> *currentNode
= toVisit
.pop();
435 addLeftPath(currentNode
->right
);
437 toVisit
.push_back(currentNode
);
442 SplayConstIterator
<V
>::addLeftPath(SplayNode
<V
> *aNode
)
448 toVisit
.push_back(aNode
);
450 } while (aNode
!= NULL
);
455 SplayConstIterator
<V
>::init(SplayNode
<V
> *head
)
462 SplayConstIterator
<V
>::operator * () const
464 /* can't dereference when past the end */
466 if (toVisit
.size() == 0)
467 fatal ("Attempt to dereference SplayConstIterator past-the-end\n");
469 return toVisit
.top()->data
;
472 #endif /* cplusplus */
474 #endif /* SQUID_SPLAY_H */