swiftiply 0.6.1.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CONTRIBUTORS +2 -0
- data/README.md +62 -0
- data/bin/{mongrel_rails → evented_mongrel_rails} +6 -14
- data/bin/swiftiplied_mongrel_rails +246 -0
- data/bin/swiftiply +136 -116
- data/bin/swiftiply_mongrel_rails +2 -2
- data/bin/swiftiplyctl +283 -0
- data/cleanup.sh +5 -0
- data/ext/deque/extconf.rb +162 -0
- data/ext/deque/swiftcore/rubymain.cpp +435 -0
- data/ext/fastfilereader/extconf.rb +2 -2
- data/ext/fastfilereader/mapper.cpp +2 -0
- data/ext/map/extconf.rb +161 -0
- data/ext/map/rubymain.cpp +500 -0
- data/ext/splaytree/extconf.rb +161 -0
- data/ext/splaytree/swiftcore/rubymain.cpp +580 -0
- data/ext/splaytree/swiftcore/splay_map.h +635 -0
- data/ext/splaytree/swiftcore/splay_set.h +575 -0
- data/ext/splaytree/swiftcore/splay_tree.h +1127 -0
- data/external/httpclient.rb +231 -0
- data/external/package.rb +13 -13
- data/setup.rb +18 -2
- data/src/swiftcore/Swiftiply.rb +417 -773
- data/src/swiftcore/Swiftiply/backend_protocol.rb +213 -0
- data/src/swiftcore/Swiftiply/cache_base.rb +49 -0
- data/src/swiftcore/Swiftiply/cache_base_mixin.rb +52 -0
- data/src/swiftcore/Swiftiply/cluster_managers/rest_based_cluster_manager.rb +9 -0
- data/src/swiftcore/Swiftiply/cluster_protocol.rb +70 -0
- data/src/swiftcore/Swiftiply/config.rb +370 -0
- data/src/swiftcore/Swiftiply/config/rest_updater.rb +26 -0
- data/src/swiftcore/Swiftiply/constants.rb +101 -0
- data/src/swiftcore/Swiftiply/content_cache_entry.rb +44 -0
- data/src/swiftcore/Swiftiply/content_response.rb +45 -0
- data/src/swiftcore/Swiftiply/control_protocol.rb +49 -0
- data/src/swiftcore/Swiftiply/dynamic_request_cache.rb +41 -0
- data/src/swiftcore/Swiftiply/etag_cache.rb +64 -0
- data/src/swiftcore/Swiftiply/file_cache.rb +46 -0
- data/src/swiftcore/Swiftiply/hash_cache_base.rb +22 -0
- data/src/swiftcore/Swiftiply/http_recognizer.rb +267 -0
- data/src/swiftcore/Swiftiply/loggers/Analogger.rb +21 -0
- data/src/swiftcore/Swiftiply/loggers/stderror.rb +13 -0
- data/src/swiftcore/Swiftiply/mocklog.rb +10 -0
- data/src/swiftcore/Swiftiply/proxy.rb +15 -0
- data/src/swiftcore/Swiftiply/proxy_backends/keepalive.rb +286 -0
- data/src/swiftcore/Swiftiply/proxy_backends/traditional.rb +286 -0
- data/src/swiftcore/Swiftiply/proxy_backends/traditional/redis_directory.rb +87 -0
- data/src/swiftcore/Swiftiply/proxy_backends/traditional/static_directory.rb +69 -0
- data/src/swiftcore/Swiftiply/proxy_bag.rb +716 -0
- data/src/swiftcore/Swiftiply/rest_based_cluster_manager.rb +15 -0
- data/src/swiftcore/Swiftiply/splay_cache_base.rb +21 -0
- data/src/swiftcore/Swiftiply/support_pagecache.rb +6 -3
- data/src/swiftcore/Swiftiply/swiftiply_2_http_proxy.rb +7 -0
- data/src/swiftcore/Swiftiply/swiftiply_client.rb +20 -5
- data/src/swiftcore/Swiftiply/version.rb +5 -0
- data/src/swiftcore/evented_mongrel.rb +26 -8
- data/src/swiftcore/hash.rb +43 -0
- data/src/swiftcore/method_builder.rb +28 -0
- data/src/swiftcore/streamer.rb +46 -0
- data/src/swiftcore/swiftiplied_mongrel.rb +91 -23
- data/src/swiftcore/types.rb +20 -3
- data/swiftiply.gemspec +14 -8
- data/test/TC_Deque.rb +152 -0
- data/test/TC_ProxyBag.rb +147 -166
- data/test/TC_Swiftiply.rb +576 -169
- data/test/TC_Swiftiply/mongrel/evented_hello.rb +1 -1
- data/test/TC_Swiftiply/mongrel/swiftiplied_hello.rb +1 -1
- data/test/TC_Swiftiply/test_serve_static_file_xsendfile/sendfile_client.rb +27 -0
- data/test/TC_Swiftiply/test_ssl/bin/validate_ssl_capability.rb +21 -0
- data/test/TC_Swiftiply/test_ssl/test.cert +16 -0
- data/test/TC_Swiftiply/test_ssl/test.key +15 -0
- data/{bin → test/bin}/echo_client +0 -0
- metadata +136 -94
- data/README +0 -126
- data/ext/swiftiply_parse/parse.rl +0 -90
@@ -0,0 +1,1127 @@
|
|
1
|
+
// splay_tree.h -- implementation af a STL complatible splay tree.
|
2
|
+
//
|
3
|
+
// Copyright (c) 2004 Ralf Mattethat, Danish Technological Institute, Informatics
|
4
|
+
//
|
5
|
+
// Permission to copy, use, modify, sell and distribute this software
|
6
|
+
// is granted provided this copyright notice appears in all copies.
|
7
|
+
// This software is provided "as is" without express or implied
|
8
|
+
// warranty, and with no claim as to its suitability for any purpose.
|
9
|
+
//
|
10
|
+
// Please send questions, comments, complaints, performance data, etc to
|
11
|
+
// ralf.mattethat@teknologisk.dk
|
12
|
+
|
13
|
+
#ifndef SPLAY_TREE_H_RMA05022003
|
14
|
+
#define SPLAY_TREE_H_RMA05022003
|
15
|
+
|
16
|
+
#include <cstddef>
|
17
|
+
#include <iterator>
|
18
|
+
#include <utility>
|
19
|
+
#include <memory>
|
20
|
+
#include <iostream>
|
21
|
+
#include <string>
|
22
|
+
|
23
|
+
/* Requirements for element type
|
24
|
+
* must be copy-constructible
|
25
|
+
* destructor must not throw exception
|
26
|
+
|
27
|
+
Methods marked with note A only throws an exception if the predicate throws
|
28
|
+
an exception. If an exception is thrown the call has no effect on the
|
29
|
+
containers state
|
30
|
+
|
31
|
+
iterators are only invalidated, if the element pointed to by the iterator
|
32
|
+
is deleted. The same goes for element references
|
33
|
+
|
34
|
+
|
35
|
+
Implementation:
|
36
|
+
splay_tree is an implementation of a binary search tree. The tree is self
|
37
|
+
balancing using the spay algorithm as described in
|
38
|
+
|
39
|
+
"Self-Adjusting Binary Search Trees
|
40
|
+
by Daniel Dominic Sleator and Robert Endre Tarjan
|
41
|
+
AT&T Bell Laboratories, Murray Hill, NJ
|
42
|
+
Jorunal of the ACM, Vol 32, no 3, July 1985, pp 652-686
|
43
|
+
|
44
|
+
A node in the search tree has references to its children and its parent. This
|
45
|
+
is to allow traversal of the whole tree from a given node making the
|
46
|
+
implementation of iterator a pointer to a node.
|
47
|
+
At the top of the tree a node is used specially. This node's parent pointer
|
48
|
+
is pointing to the root of the tree. It's left and right pointer points to the
|
49
|
+
leftmost and rightmost node in the tree respectively. This node is used to
|
50
|
+
represent the end-iterator.
|
51
|
+
|
52
|
+
+---------+
|
53
|
+
tree_ ------------------------------>| |
|
54
|
+
| |
|
55
|
+
+-----------(left)-------| |-------(right)--------+
|
56
|
+
| +---------+ |
|
57
|
+
| | |
|
58
|
+
| | (parent) |
|
59
|
+
| | |
|
60
|
+
| | |
|
61
|
+
| +---------+ |
|
62
|
+
root of tree ..|.......................>| | |
|
63
|
+
| | D | |
|
64
|
+
| | | |
|
65
|
+
| +---------+ |
|
66
|
+
| / \ |
|
67
|
+
| / \ |
|
68
|
+
| / \ |
|
69
|
+
| / \ |
|
70
|
+
| / \ |
|
71
|
+
| +---------+ +---------+ |
|
72
|
+
| | | | | |
|
73
|
+
| | B | | F | |
|
74
|
+
| | | | | |
|
75
|
+
| +---------+ +---------+ |
|
76
|
+
| / \ / \ |
|
77
|
+
| / \ / \ |
|
78
|
+
| / \ / \ |
|
79
|
+
| +---------+ +---------+ +---------+ +---------+ |
|
80
|
+
+-->| | | | | | | |<--+
|
81
|
+
| A | | C | | E | | G |
|
82
|
+
| | | | | | | |
|
83
|
+
+---------+ +---------+ +---------+ +---------+
|
84
|
+
|
85
|
+
Figure 1: Representation of data
|
86
|
+
|
87
|
+
*/
|
88
|
+
|
89
|
+
namespace swiftcore
|
90
|
+
{
|
91
|
+
namespace detail
|
92
|
+
{
|
93
|
+
|
94
|
+
// contains logic manipulating the tree structure
|
95
|
+
class splay_tree_base
|
96
|
+
{
|
97
|
+
protected:
|
98
|
+
|
99
|
+
struct node_base
|
100
|
+
{
|
101
|
+
node_base* parent;
|
102
|
+
node_base* left;
|
103
|
+
node_base* right;
|
104
|
+
|
105
|
+
node_base() throw()
|
106
|
+
: parent( 0 ), left( 0 ), right( 0 )
|
107
|
+
{ }
|
108
|
+
|
109
|
+
node_base( node_base* p, node_base* l, node_base* r ) throw()
|
110
|
+
: parent( p ), left( l ), right( r )
|
111
|
+
{ }
|
112
|
+
|
113
|
+
// return pointer to the node preceding this node
|
114
|
+
node_base* previous()
|
115
|
+
{
|
116
|
+
node_base* n = this;
|
117
|
+
|
118
|
+
if( n->parent == 0 || n->parent == n->right || ( n->right != 0 && n->right->parent != n ) )
|
119
|
+
{
|
120
|
+
n = n->right; // sentinel (end) node
|
121
|
+
}
|
122
|
+
else if( n->left != 0 )
|
123
|
+
{
|
124
|
+
n = n->left;
|
125
|
+
while( n->right != 0 )
|
126
|
+
{
|
127
|
+
n = n->right;
|
128
|
+
}
|
129
|
+
}
|
130
|
+
else
|
131
|
+
{
|
132
|
+
node_base* p = n->parent;
|
133
|
+
while( n == p->left )
|
134
|
+
{
|
135
|
+
n = p;
|
136
|
+
p = p->parent;
|
137
|
+
}
|
138
|
+
n = p;
|
139
|
+
}
|
140
|
+
|
141
|
+
return n;
|
142
|
+
}
|
143
|
+
|
144
|
+
// return pointer to the node succeding this node
|
145
|
+
node_base* next()
|
146
|
+
{
|
147
|
+
node_base* n = this;
|
148
|
+
|
149
|
+
if( n->right != 0 )
|
150
|
+
{
|
151
|
+
n = n->right;
|
152
|
+
while( n->left != 0 )
|
153
|
+
{
|
154
|
+
n = n->left;
|
155
|
+
}
|
156
|
+
}
|
157
|
+
else
|
158
|
+
{
|
159
|
+
// NOTE: infinite loop if end-iterator is incremented
|
160
|
+
node_base* p = n->parent;
|
161
|
+
while( n == p->right )
|
162
|
+
{
|
163
|
+
n = p;
|
164
|
+
p = p->parent;
|
165
|
+
}
|
166
|
+
if( n->right != p )
|
167
|
+
{
|
168
|
+
n = p;
|
169
|
+
}
|
170
|
+
}
|
171
|
+
|
172
|
+
return n;
|
173
|
+
}
|
174
|
+
};
|
175
|
+
|
176
|
+
protected:
|
177
|
+
|
178
|
+
splay_tree_base() : data_( 0 ) { }
|
179
|
+
|
180
|
+
// update parent pointers for child nodes | complexity : constant | exception : nothrow
|
181
|
+
static void link_to_parent( node_base* n )
|
182
|
+
{
|
183
|
+
if( n->left != 0 )
|
184
|
+
{
|
185
|
+
n->left->parent = n;
|
186
|
+
}
|
187
|
+
|
188
|
+
if( n->right != 0 )
|
189
|
+
{
|
190
|
+
n->right->parent = n;
|
191
|
+
}
|
192
|
+
}
|
193
|
+
|
194
|
+
// insert new_node after n | complexity : constant | exception : nothrow
|
195
|
+
void insert_after( node_base* n, node_base* new_node )
|
196
|
+
{
|
197
|
+
if( n->right != 0 )
|
198
|
+
{
|
199
|
+
n->right->parent = new_node;
|
200
|
+
}
|
201
|
+
else
|
202
|
+
{
|
203
|
+
data_->right = new_node;
|
204
|
+
}
|
205
|
+
|
206
|
+
n->right = new_node;
|
207
|
+
}
|
208
|
+
|
209
|
+
// insert new_node to the left of n | complexity : constant | exception : nothrow
|
210
|
+
void insert_left( node_base* n, node_base* new_node )
|
211
|
+
{
|
212
|
+
n->left = 0;
|
213
|
+
|
214
|
+
link_to_parent( new_node );
|
215
|
+
|
216
|
+
data_->parent = new_node;
|
217
|
+
if( new_node->left == 0 )
|
218
|
+
{
|
219
|
+
data_->left = new_node;
|
220
|
+
}
|
221
|
+
}
|
222
|
+
|
223
|
+
// insert new_node to the right of n| complexity : constant | exception : nothrow
|
224
|
+
void insert_right( node_base* n, node_base* new_node )
|
225
|
+
{
|
226
|
+
n->right = 0;
|
227
|
+
|
228
|
+
link_to_parent( new_node );
|
229
|
+
|
230
|
+
data_->parent = new_node;
|
231
|
+
if( new_node->right == 0 )
|
232
|
+
{
|
233
|
+
data_->right = new_node;
|
234
|
+
}
|
235
|
+
}
|
236
|
+
|
237
|
+
// delete node | complexity : constant | exception : nothrow
|
238
|
+
void erase( node_base* t )
|
239
|
+
{
|
240
|
+
node_base* n = t->right;
|
241
|
+
|
242
|
+
if( t->left != 0 )
|
243
|
+
{
|
244
|
+
node_base* l = t->previous();
|
245
|
+
|
246
|
+
splay( l , t );
|
247
|
+
|
248
|
+
n = t->left;
|
249
|
+
|
250
|
+
n->right = t->right;
|
251
|
+
if( n->right != 0 )
|
252
|
+
{
|
253
|
+
n->right->parent = n;
|
254
|
+
}
|
255
|
+
}
|
256
|
+
|
257
|
+
if( n != 0 )
|
258
|
+
{
|
259
|
+
n->parent = t->parent;
|
260
|
+
}
|
261
|
+
|
262
|
+
if( t->parent == data_ )
|
263
|
+
{
|
264
|
+
data_->parent = n;
|
265
|
+
}
|
266
|
+
else if( t->parent->left == t )
|
267
|
+
{
|
268
|
+
t->parent->left = n;
|
269
|
+
}
|
270
|
+
else // must be ( t->parent->right == t )
|
271
|
+
{
|
272
|
+
t->parent->right = n;
|
273
|
+
}
|
274
|
+
|
275
|
+
if( data_->left == t )
|
276
|
+
{
|
277
|
+
data_->left = find_leftmost();
|
278
|
+
}
|
279
|
+
if( data_->right == t )
|
280
|
+
{
|
281
|
+
data_->right = find_rightmost();
|
282
|
+
}
|
283
|
+
}
|
284
|
+
|
285
|
+
// rotate node t with left child | complexity : constant | exception : nothrow
|
286
|
+
static void rotate_left( node_base*& t )
|
287
|
+
{
|
288
|
+
node_base* x = t->right;
|
289
|
+
t->right = x->left;
|
290
|
+
if( t->right != 0 )
|
291
|
+
{
|
292
|
+
t->right->parent = t;
|
293
|
+
}
|
294
|
+
x->left = t;
|
295
|
+
t->parent = x;
|
296
|
+
t = x;
|
297
|
+
}
|
298
|
+
|
299
|
+
// rotate node t with right child | complexity : constant | exception : nothrow
|
300
|
+
static void rotate_right( node_base*& t )
|
301
|
+
{
|
302
|
+
node_base* x = t->left;
|
303
|
+
t->left = x->right;
|
304
|
+
if( t->left != 0 )
|
305
|
+
{
|
306
|
+
t->left->parent = t;
|
307
|
+
}
|
308
|
+
x->right = t;
|
309
|
+
t->parent = x;
|
310
|
+
t = x;
|
311
|
+
}
|
312
|
+
|
313
|
+
// break link to left child node and attach it to left tree pointed to by l | complexity : constant | exception : nothrow
|
314
|
+
static void link_left( node_base*& t, node_base*& l )
|
315
|
+
{
|
316
|
+
l->right = t;
|
317
|
+
t->parent = l;
|
318
|
+
l = t;
|
319
|
+
t = t->right;
|
320
|
+
}
|
321
|
+
|
322
|
+
// break link to right child node and attach it to right tree pointed to by r | complexity : constant | exception : nothrow
|
323
|
+
static void link_right( node_base*& t, node_base*& r )
|
324
|
+
{
|
325
|
+
r->left = t;
|
326
|
+
t->parent = r;
|
327
|
+
r = t;
|
328
|
+
t = t->left;
|
329
|
+
}
|
330
|
+
|
331
|
+
// assemble the three sub-trees into new tree pointed to by t | complexity : constant | exception : nothrow
|
332
|
+
static void assemble( node_base* t, node_base* l, node_base* r, const node_base& null_node )
|
333
|
+
{
|
334
|
+
l->right = t->left;
|
335
|
+
r->left = t->right;
|
336
|
+
|
337
|
+
if( l->right != 0 )
|
338
|
+
{
|
339
|
+
l->right->parent = l;
|
340
|
+
}
|
341
|
+
|
342
|
+
if( r->left != 0 )
|
343
|
+
{
|
344
|
+
r->left->parent = r;
|
345
|
+
}
|
346
|
+
|
347
|
+
t->left = null_node.right;
|
348
|
+
t->right = null_node.left;
|
349
|
+
link_to_parent( t );
|
350
|
+
}
|
351
|
+
|
352
|
+
// bottom-up splay, use data_ as parent for n | complexity : logaritmic | exception : nothrow
|
353
|
+
void splay( node_base* n ) const
|
354
|
+
{
|
355
|
+
if( n == data_ )
|
356
|
+
{
|
357
|
+
n = data_->right;
|
358
|
+
}
|
359
|
+
|
360
|
+
splay( n, data_ );
|
361
|
+
}
|
362
|
+
|
363
|
+
private:
|
364
|
+
|
365
|
+
// rotate n with its parent | complexity : constant | exception : nothrow
|
366
|
+
void rotate( node_base* n ) const
|
367
|
+
{
|
368
|
+
node_base* p = n->parent;
|
369
|
+
node_base* g = p->parent;
|
370
|
+
|
371
|
+
if( p->left == n )
|
372
|
+
{
|
373
|
+
p->left = n->right;
|
374
|
+
if( p->left != 0 )
|
375
|
+
{
|
376
|
+
p->left->parent = p;
|
377
|
+
}
|
378
|
+
n->right = p;
|
379
|
+
}
|
380
|
+
else // must be ( p->right == n )
|
381
|
+
{
|
382
|
+
p->right = n->left;
|
383
|
+
if( p->right != 0 )
|
384
|
+
{
|
385
|
+
p->right->parent = p;
|
386
|
+
}
|
387
|
+
n->left = p;
|
388
|
+
}
|
389
|
+
|
390
|
+
p->parent = n;
|
391
|
+
n->parent = g;
|
392
|
+
|
393
|
+
if( g == data_ )
|
394
|
+
{
|
395
|
+
g->parent = n;
|
396
|
+
}
|
397
|
+
else if( g->left == p )
|
398
|
+
{
|
399
|
+
g->left = n;
|
400
|
+
}
|
401
|
+
else //must be ( g->right == p )
|
402
|
+
{
|
403
|
+
g->right = n;
|
404
|
+
}
|
405
|
+
}
|
406
|
+
|
407
|
+
// bottom-up splay, use t as parent for n | complexity : logaritmic | exception : nothrow
|
408
|
+
void splay( node_base* n, node_base* t ) const
|
409
|
+
{
|
410
|
+
if( n == t ) return;
|
411
|
+
|
412
|
+
for( ;; )
|
413
|
+
{
|
414
|
+
node_base* p = n->parent;
|
415
|
+
|
416
|
+
if( p == t )
|
417
|
+
break;
|
418
|
+
|
419
|
+
node_base* g = p->parent;
|
420
|
+
|
421
|
+
if( g == t )
|
422
|
+
{ // zig
|
423
|
+
rotate( n );
|
424
|
+
}
|
425
|
+
else if( ( p->left == n && g->left == p ) || ( p->right == n && g->right == p ) )
|
426
|
+
{ // zig-zig
|
427
|
+
rotate( p );
|
428
|
+
rotate( n );
|
429
|
+
}
|
430
|
+
else
|
431
|
+
{ // zig-zag
|
432
|
+
rotate( n );
|
433
|
+
rotate( n );
|
434
|
+
}
|
435
|
+
}
|
436
|
+
}
|
437
|
+
|
438
|
+
// find the left most node in tree | complexity : logaritmic | exception : nothrow
|
439
|
+
node_base* find_leftmost() const
|
440
|
+
{
|
441
|
+
node_base* n = data_->parent;
|
442
|
+
if( n == 0 )
|
443
|
+
return data_;
|
444
|
+
|
445
|
+
while( n->left != 0 )
|
446
|
+
{
|
447
|
+
n = n->left;
|
448
|
+
}
|
449
|
+
|
450
|
+
return n;
|
451
|
+
}
|
452
|
+
|
453
|
+
// find the right most node in tree | complexity : logaritmic | exception : nothrow
|
454
|
+
node_base* find_rightmost() const
|
455
|
+
{
|
456
|
+
node_base* n = data_->parent;
|
457
|
+
if( n == 0 )
|
458
|
+
return data_;
|
459
|
+
|
460
|
+
while( n->right != 0 )
|
461
|
+
{
|
462
|
+
n = n->right;
|
463
|
+
}
|
464
|
+
|
465
|
+
return n;
|
466
|
+
}
|
467
|
+
|
468
|
+
protected:
|
469
|
+
node_base* data_;
|
470
|
+
};
|
471
|
+
|
472
|
+
template <typename K, typename T, typename Key, typename Compare, typename Allocator>
|
473
|
+
class splay_tree : private splay_tree_base
|
474
|
+
{
|
475
|
+
|
476
|
+
struct node : splay_tree_base::node_base
|
477
|
+
{
|
478
|
+
T element;
|
479
|
+
|
480
|
+
node( const T& item, node_base* p, node_base* l, node_base* r )
|
481
|
+
: node_base( p, l, r ), element( item )
|
482
|
+
{ }
|
483
|
+
|
484
|
+
private:
|
485
|
+
node& operator= ( const node& ); // to disable warning C4512 (compiler bug)
|
486
|
+
};
|
487
|
+
|
488
|
+
// return key part of value in node
|
489
|
+
const K& key_from_node( const node_base* n ) const { return Key()( static_cast<const node*>( n )->element ); }
|
490
|
+
|
491
|
+
public:
|
492
|
+
// container
|
493
|
+
typedef K key_type;
|
494
|
+
typedef T value_type;
|
495
|
+
typedef Compare key_compare;
|
496
|
+
typedef typename Allocator::reference reference;
|
497
|
+
typedef typename Allocator::const_reference const_reference;
|
498
|
+
typedef typename Allocator::size_type size_type;
|
499
|
+
typedef typename Allocator::difference_type difference_type;
|
500
|
+
|
501
|
+
typedef Allocator allocator_type;
|
502
|
+
typedef typename Allocator::pointer pointer;
|
503
|
+
typedef typename Allocator::const_pointer const_pointer;
|
504
|
+
|
505
|
+
// container
|
506
|
+
class iterator_base
|
507
|
+
{
|
508
|
+
protected:
|
509
|
+
iterator_base() : item_( 0 ) { }
|
510
|
+
iterator_base( node_base* e ) : item_( e ) { }
|
511
|
+
|
512
|
+
public:
|
513
|
+
bool operator== ( const iterator_base& iter ) const { return item_ == iter.item_; }
|
514
|
+
bool operator!= ( const iterator_base& iter ) const { return item_ != iter.item_; }
|
515
|
+
|
516
|
+
protected:
|
517
|
+
node_base* item_;
|
518
|
+
};
|
519
|
+
|
520
|
+
class const_iterator;
|
521
|
+
|
522
|
+
class iterator : public std::iterator<std::bidirectional_iterator_tag, value_type, difference_type, pointer, reference>,
|
523
|
+
public iterator_base
|
524
|
+
{
|
525
|
+
friend class splay_tree<K, T, Key, Compare, Allocator>;
|
526
|
+
friend class const_iterator;
|
527
|
+
|
528
|
+
iterator( node_base* e ) : iterator_base( e ) { }
|
529
|
+
|
530
|
+
public:
|
531
|
+
typedef std::bidirectional_iterator_tag iterator_category;
|
532
|
+
typedef T value_type;
|
533
|
+
typedef typename Allocator::reference reference;
|
534
|
+
typedef typename Allocator::pointer pointer;
|
535
|
+
typedef typename Allocator::difference_type difference_type;
|
536
|
+
|
537
|
+
iterator() { }
|
538
|
+
|
539
|
+
reference operator* () const { return static_cast<node*>( this->item_ )->element; }
|
540
|
+
pointer operator-> () const { return &**this; }
|
541
|
+
|
542
|
+
iterator& operator++ () { this->item_ = this->item_->next(); return *this; }
|
543
|
+
iterator operator++ ( int ) { iterator tmp( *this ); this->item_ = this->item_->next(); return tmp; }
|
544
|
+
|
545
|
+
iterator& operator-- () { this->item_ = this->item_->previous(); return *this; }
|
546
|
+
iterator operator-- ( int ) { iterator tmp( *this ); this->item_ = this->item_->previous(); return tmp; }
|
547
|
+
};
|
548
|
+
|
549
|
+
class const_iterator : public std::iterator<std::bidirectional_iterator_tag, value_type, difference_type, const_pointer, const_reference>,
|
550
|
+
public iterator_base
|
551
|
+
{
|
552
|
+
friend class splay_tree<K, T, Key, Compare, Allocator>;
|
553
|
+
friend class iterator;
|
554
|
+
|
555
|
+
const_iterator( node_base* e ) : iterator_base( e ) { }
|
556
|
+
|
557
|
+
public:
|
558
|
+
typedef std::bidirectional_iterator_tag iterator_category;
|
559
|
+
typedef T value_type;
|
560
|
+
typedef typename Allocator::const_reference reference;
|
561
|
+
typedef typename Allocator::const_pointer pointer;
|
562
|
+
typedef typename Allocator::difference_type difference_type;
|
563
|
+
|
564
|
+
const_iterator() { }
|
565
|
+
const_iterator( const iterator& it ) : iterator_base( it.item_ ) { }
|
566
|
+
|
567
|
+
reference operator* () const { return static_cast<node*>( this->item_ )->element; }
|
568
|
+
pointer operator-> () const { return &**this; }
|
569
|
+
|
570
|
+
const_iterator& operator++ () { this->item_ = this->item_->next(); return *this; }
|
571
|
+
const_iterator operator++ ( int ) { const_iterator tmp( *this ); this->item_ = this->item_->next(); return tmp; }
|
572
|
+
|
573
|
+
const_iterator& operator-- () { this->item_ = this->item_->previous(); return *this; }
|
574
|
+
const_iterator operator-- ( int ) { const_iterator tmp( *this ); this->item_ = this->item_->previous(); return tmp; }
|
575
|
+
};
|
576
|
+
|
577
|
+
|
578
|
+
/////////////////////////////////////////////////////////////////
|
579
|
+
// construct/copy/destroy:
|
580
|
+
|
581
|
+
// container | complexity : constant | exception :
|
582
|
+
explicit splay_tree( const key_compare& comp, const allocator_type& a )
|
583
|
+
: size_( 0 ), maxsz_( 1024 ), comp_( comp ), allocator_( a ), node_allocator_( a )
|
584
|
+
{
|
585
|
+
data_ = node_allocator_.allocate( 1, 0 );
|
586
|
+
|
587
|
+
new ( data_ ) node_base( 0 , data_, data_ );
|
588
|
+
}
|
589
|
+
|
590
|
+
// container | complexity : linear | exception : nothrow
|
591
|
+
~splay_tree()
|
592
|
+
{
|
593
|
+
clear();
|
594
|
+
data_->~node_base();
|
595
|
+
node_allocator_.deallocate( static_cast<node*>( data_ ), 1 );
|
596
|
+
}
|
597
|
+
|
598
|
+
// | complexity : constant | exception : nothrow
|
599
|
+
allocator_type get_allocator() const { return allocator_; }
|
600
|
+
|
601
|
+
|
602
|
+
/////////////////////////////////////////////////////////////////
|
603
|
+
// iterators:
|
604
|
+
|
605
|
+
// container | complexity : constant | exception : nothrow
|
606
|
+
iterator begin() { return iterator( data_->left ); }
|
607
|
+
const_iterator begin() const { return const_iterator( data_->left ); }
|
608
|
+
iterator end() { return iterator( data_ ); }
|
609
|
+
const_iterator end() const { return const_iterator( data_ ); }
|
610
|
+
iterator parent() { return iterator( data_->parent ); }
|
611
|
+
const_iterator parent() const { return const_iterator( data_->parent ); }
|
612
|
+
|
613
|
+
|
614
|
+
/////////////////////////////////////////////////////////////////
|
615
|
+
// capacity:
|
616
|
+
|
617
|
+
// container | complexity : constant | exception : nothrow
|
618
|
+
bool empty() const { return size_ == 0; }
|
619
|
+
|
620
|
+
// container | complexity : constant | exception : nothrow
|
621
|
+
size_type size() const { return size_; }
|
622
|
+
|
623
|
+
void set_max_permitted_size(int sz) {
|
624
|
+
maxsz_ = ((sz < 0) ? 0 : sz);
|
625
|
+
}
|
626
|
+
|
627
|
+
int get_max_permitted_size() {
|
628
|
+
return maxsz_;
|
629
|
+
}
|
630
|
+
|
631
|
+
// container | complexity : constant | exception : nothrow
|
632
|
+
size_type max_size() const { return allocator_.max_size(); }
|
633
|
+
|
634
|
+
|
635
|
+
/////////////////////////////////////////////////////////////////
|
636
|
+
// modifiers:
|
637
|
+
|
638
|
+
// associative sequence | complexity : logarithmic | exception : strong
|
639
|
+
std::pair<iterator, bool> insert_unique( const value_type& x )
|
640
|
+
{
|
641
|
+
bool inserted = false;
|
642
|
+
|
643
|
+
splay( Key()( x ) );
|
644
|
+
node_base* n = data_->parent;
|
645
|
+
|
646
|
+
if( n == 0 )
|
647
|
+
{ // empty tree
|
648
|
+
node* new_node = construct( x, data_, 0, 0 );
|
649
|
+
data_->parent = data_->left = data_->right = new_node;
|
650
|
+
size_ = 1;
|
651
|
+
inserted = true;
|
652
|
+
}
|
653
|
+
else if( comp_( Key()( x ), key_from_node( n ) ) )
|
654
|
+
{
|
655
|
+
node* new_node = construct( x, data_, n->left, n );
|
656
|
+
insert_left( n, new_node );
|
657
|
+
++size_;
|
658
|
+
inserted = true;
|
659
|
+
}
|
660
|
+
else if( comp_( key_from_node( n ), Key()( x ) ) )
|
661
|
+
{
|
662
|
+
node* new_node = construct( x, data_, n, n->right );
|
663
|
+
insert_right( n, new_node );
|
664
|
+
++size_;
|
665
|
+
inserted = true;
|
666
|
+
}
|
667
|
+
|
668
|
+
if (size_ > maxsz_)
|
669
|
+
erase_childfree_nodes();
|
670
|
+
|
671
|
+
return std::pair<iterator, bool>( iterator( data_->parent ), inserted );
|
672
|
+
}
|
673
|
+
|
674
|
+
// associative sequence | complexity : constant/logarithmic | exception : strong
|
675
|
+
iterator insert_unique( iterator position, const value_type& x )
|
676
|
+
{ // complexity should be amortized constant time if x is inserted right after position
|
677
|
+
|
678
|
+
if( position != end() && comp_( key_from_node( position.item_ ), Key()( x ) ) )
|
679
|
+
{ // 'position' is before x
|
680
|
+
splay_tree_base::splay( position.item_ );
|
681
|
+
|
682
|
+
iterator next = position;
|
683
|
+
++next;
|
684
|
+
|
685
|
+
if( next == end() || comp_( Key()( x ), key_from_node( next.item_ ) ) )
|
686
|
+
{
|
687
|
+
return iterator( insert_after( position.item_, x ) );
|
688
|
+
}
|
689
|
+
else if( !comp_( key_from_node( next.item_ ), Key()( x ) ) )
|
690
|
+
{ // x already inserted
|
691
|
+
return next;
|
692
|
+
}
|
693
|
+
}
|
694
|
+
|
695
|
+
// 'position' didn�t point the right place
|
696
|
+
return insert_unique( x ).first;
|
697
|
+
}
|
698
|
+
|
699
|
+
// associative sequence | complexity : NlogN | exception : weak
|
700
|
+
template <typename InputIterator>
|
701
|
+
void insert_unique( InputIterator first, InputIterator last )
|
702
|
+
{
|
703
|
+
iterator pos = end();
|
704
|
+
for( InputIterator it = first; it != last; ++it )
|
705
|
+
{
|
706
|
+
pos = insert_unique( pos, *it );
|
707
|
+
}
|
708
|
+
}
|
709
|
+
|
710
|
+
// associative sequence | complexity : logarithmic | exception : strong
|
711
|
+
iterator insert_equal( const value_type& x )
|
712
|
+
{
|
713
|
+
splay( Key()( x ) );
|
714
|
+
node_base* n = data_->parent;
|
715
|
+
|
716
|
+
if( n == 0 )
|
717
|
+
{ // empty tree
|
718
|
+
node* new_node = construct( x, data_, 0, 0 );
|
719
|
+
data_->parent = data_->left = data_->right = new_node;
|
720
|
+
size_ = 1;
|
721
|
+
}
|
722
|
+
else if( comp_( Key()( x ), key_from_node( n ) ) )
|
723
|
+
{
|
724
|
+
node* new_node = construct( x, data_, n->left, n );
|
725
|
+
insert_left( n, new_node );
|
726
|
+
++size_;
|
727
|
+
}
|
728
|
+
else
|
729
|
+
{
|
730
|
+
node* new_node = construct( x, data_, n, n->right );
|
731
|
+
insert_right( n, new_node );
|
732
|
+
++size_;
|
733
|
+
}
|
734
|
+
|
735
|
+
if (size_ > maxsz_)
|
736
|
+
erase_childfree_nodes();
|
737
|
+
return iterator( data_->parent );
|
738
|
+
}
|
739
|
+
|
740
|
+
// associative sequence | complexity : constant(a)/logarithmic | exception : strong
|
741
|
+
iterator insert_equal( iterator position, const value_type& x )
|
742
|
+
{ // complexity should be amortized constant time if x is inserted right after position
|
743
|
+
|
744
|
+
if( position != end() && !comp_( Key()( x ), key_from_node( position.item_ ) ) )
|
745
|
+
{ // 'position' isn't after x
|
746
|
+
splay_tree_base::splay( position.item_ );
|
747
|
+
|
748
|
+
iterator next = position;
|
749
|
+
++next;
|
750
|
+
|
751
|
+
if( next == end() || !comp_( key_from_node( next.item_ ), Key()( x ) ) )
|
752
|
+
{
|
753
|
+
return iterator( insert_after( position.item_, x ) );
|
754
|
+
}
|
755
|
+
}
|
756
|
+
|
757
|
+
// 'position' didn�t point the right place
|
758
|
+
return insert_equal( x );
|
759
|
+
}
|
760
|
+
|
761
|
+
// associative sequence | complexity : NlogN | exception : weak
|
762
|
+
template <typename InputIterator>
|
763
|
+
void insert_equal( InputIterator first, InputIterator last )
|
764
|
+
{
|
765
|
+
iterator pos = end();
|
766
|
+
for( InputIterator it = first; it != last; ++it )
|
767
|
+
{
|
768
|
+
pos = insert_equal( pos, *it );
|
769
|
+
}
|
770
|
+
}
|
771
|
+
|
772
|
+
// associative sequence | complexity : logarithmic | exception : strong, note A
|
773
|
+
size_type erase( const key_type& x )
|
774
|
+
{
|
775
|
+
std::pair<iterator,iterator> p = equal_range( x );
|
776
|
+
size_type n = std::distance( p.first, p.second );
|
777
|
+
erase( p.first, p.second );
|
778
|
+
return n;
|
779
|
+
}
|
780
|
+
|
781
|
+
// associative sequence | complexity : constant | exception : nothrow
|
782
|
+
void erase( iterator position )
|
783
|
+
{
|
784
|
+
node_base* t = position.item_;
|
785
|
+
|
786
|
+
splay_tree_base::erase( t );
|
787
|
+
|
788
|
+
--size_;
|
789
|
+
destroy( t );
|
790
|
+
}
|
791
|
+
|
792
|
+
// associative sequence | complexity : linear | exception : nothrow
|
793
|
+
void erase( iterator first, iterator last )
|
794
|
+
{
|
795
|
+
if( first == begin() && last == end() )
|
796
|
+
{
|
797
|
+
clear();
|
798
|
+
}
|
799
|
+
else
|
800
|
+
{
|
801
|
+
for( iterator it = first; it != last; )
|
802
|
+
{
|
803
|
+
erase( it++ );
|
804
|
+
}
|
805
|
+
}
|
806
|
+
}
|
807
|
+
|
808
|
+
// associative sequence | complexity : linear | exception : nothrow
|
809
|
+
void clear()
|
810
|
+
{
|
811
|
+
node_base* n = data_->left;
|
812
|
+
|
813
|
+
while( n != data_ )
|
814
|
+
{
|
815
|
+
if( n->left != 0 )
|
816
|
+
{
|
817
|
+
n = n->left;
|
818
|
+
}
|
819
|
+
else if( n->right != 0 )
|
820
|
+
{
|
821
|
+
n = n->right;
|
822
|
+
}
|
823
|
+
else
|
824
|
+
{
|
825
|
+
node_base* p = n->parent;
|
826
|
+
if( p->left == n )
|
827
|
+
{
|
828
|
+
p->left = 0;
|
829
|
+
}
|
830
|
+
else // must be ( p->right == n )
|
831
|
+
{
|
832
|
+
p->right = 0;
|
833
|
+
}
|
834
|
+
|
835
|
+
destroy( n );
|
836
|
+
n = p;
|
837
|
+
}
|
838
|
+
}
|
839
|
+
data_->parent = 0;
|
840
|
+
data_->left = data_->right = data_;
|
841
|
+
size_ = 0;
|
842
|
+
}
|
843
|
+
|
844
|
+
// container | complexity : constant | exception : nothrow
|
845
|
+
void swap( splay_tree& x )
|
846
|
+
{
|
847
|
+
std::swap( data_, x.data_ );
|
848
|
+
std::swap( size_, x.size_ );
|
849
|
+
|
850
|
+
std::swap( comp_, x.comp_ );
|
851
|
+
}
|
852
|
+
|
853
|
+
|
854
|
+
/////////////////////////////////////////////////////////////////
|
855
|
+
// observers:
|
856
|
+
|
857
|
+
// associative sequence | complexity : constant | exception : nothrow
|
858
|
+
key_compare key_comp() const { return comp_; }
|
859
|
+
|
860
|
+
|
861
|
+
/////////////////////////////////////////////////////////////////
|
862
|
+
// splay tree operations:
|
863
|
+
|
864
|
+
// associative sequence | complexity : logarithmic | exception : strong, note A
|
865
|
+
iterator find( const key_type& x )
|
866
|
+
{
|
867
|
+
splay( x );
|
868
|
+
return iterator( internal_find( x ) );
|
869
|
+
}
|
870
|
+
|
871
|
+
// associative sequence | complexity : logarithmic | exception : strong, note A
|
872
|
+
const_iterator find( const key_type& x ) const
|
873
|
+
{
|
874
|
+
splay( x );
|
875
|
+
return const_iterator( internal_find( x ) );
|
876
|
+
}
|
877
|
+
|
878
|
+
// associative sequence | complexity : logarithmic | exception : strong, note A
|
879
|
+
size_type count( const key_type& x ) const
|
880
|
+
{
|
881
|
+
std::pair<const_iterator, const_iterator> p = equal_range( x );
|
882
|
+
return std::distance( p.first, p.second );
|
883
|
+
}
|
884
|
+
|
885
|
+
// associative sequence | complexity : logarithmic | exception : strong, note A
|
886
|
+
iterator lower_bound( const key_type& x )
|
887
|
+
{
|
888
|
+
//splay( x );
|
889
|
+
//return iterator( internal_lower_bound( x ) );
|
890
|
+
node_base* n = internal_lower_bound( x );
|
891
|
+
splay_tree_base::splay( n );
|
892
|
+
return iterator( n );
|
893
|
+
}
|
894
|
+
|
895
|
+
// associative sequence | complexity : logarithmic | exception : strong, note A
|
896
|
+
const_iterator lower_bound( const key_type& x ) const
|
897
|
+
{
|
898
|
+
node_base* n = internal_lower_bound( x );
|
899
|
+
splay_tree_base::splay( n );
|
900
|
+
return const_iterator( n );
|
901
|
+
}
|
902
|
+
|
903
|
+
// associative sequence | complexity : logarithmic | exception : strong, note A
|
904
|
+
iterator upper_bound( const key_type& x )
|
905
|
+
{
|
906
|
+
node_base* n = internal_upper_bound( x );
|
907
|
+
splay_tree_base::splay( n );
|
908
|
+
return iterator( n );
|
909
|
+
}
|
910
|
+
|
911
|
+
// associative sequence | complexity : logarithmic | exception : strong, note A
|
912
|
+
const_iterator upper_bound( const key_type& x ) const
|
913
|
+
{
|
914
|
+
node_base* n = internal_upper_bound( x );
|
915
|
+
splay_tree_base::splay( n );
|
916
|
+
return const_iterator( n );
|
917
|
+
}
|
918
|
+
|
919
|
+
// associative sequence | complexity : logarithmic | exception : strong, note A
|
920
|
+
std::pair<iterator, iterator> equal_range( const key_type& x )
|
921
|
+
{
|
922
|
+
return std::make_pair( lower_bound( x ), upper_bound( x ) );
|
923
|
+
}
|
924
|
+
|
925
|
+
// associative sequence | complexity : logarithmic | exception : strong, note A
|
926
|
+
std::pair<const_iterator, const_iterator> equal_range( const key_type& x ) const
|
927
|
+
{
|
928
|
+
return std::make_pair( lower_bound( x ), upper_bound( x ) );
|
929
|
+
}
|
930
|
+
|
931
|
+
// | complexity: linear
|
932
|
+
void erase_childfree_nodes() {
|
933
|
+
node_base* n;
|
934
|
+
iterator it = begin();
|
935
|
+
iterator oit;
|
936
|
+
iterator last = end();
|
937
|
+
for (; it != last;) {
|
938
|
+
n = it.item_;
|
939
|
+
if (n->left == 0 && n->right == 0) {
|
940
|
+
oit = it++;
|
941
|
+
erase(oit);
|
942
|
+
} else {
|
943
|
+
it++;
|
944
|
+
}
|
945
|
+
}
|
946
|
+
}
|
947
|
+
|
948
|
+
private:
|
949
|
+
|
950
|
+
// return a newly allocate node holding the value x | complexity : constant | exception : strong
|
951
|
+
node* construct( const value_type& x, node_base* p, node_base* l, node_base* r )
|
952
|
+
{
|
953
|
+
node* n = node_allocator_.allocate( 1, 0 );
|
954
|
+
|
955
|
+
try
|
956
|
+
{
|
957
|
+
new ( n ) node( x, p, l, r );
|
958
|
+
}
|
959
|
+
catch( ... )
|
960
|
+
{
|
961
|
+
node_allocator_.deallocate( n, 1 );
|
962
|
+
throw;
|
963
|
+
}
|
964
|
+
|
965
|
+
return n;
|
966
|
+
}
|
967
|
+
|
968
|
+
// deallocate node pointed to by n | complexity : constant | exception : nothrow
|
969
|
+
void destroy( node_base* n )
|
970
|
+
{
|
971
|
+
node* p = static_cast<node*>( n );
|
972
|
+
node_allocator_.destroy( p );
|
973
|
+
node_allocator_.deallocate( p, 1 );
|
974
|
+
}
|
975
|
+
|
976
|
+
// insert new node after n | complexity : constant | exception : strong
|
977
|
+
node_base* insert_after( node_base* n, const value_type& x )
|
978
|
+
{
|
979
|
+
node* new_node = construct( x, n, 0, n->right );
|
980
|
+
splay_tree_base::insert_after( n, new_node );
|
981
|
+
++size_;
|
982
|
+
return new_node;
|
983
|
+
}
|
984
|
+
|
985
|
+
// find node with key x | complexity : logaritmic | exception : strong, note A
|
986
|
+
node_base* internal_find( const key_type& x ) const
|
987
|
+
{
|
988
|
+
node_base* n = data_->parent;
|
989
|
+
|
990
|
+
while( n != 0 )
|
991
|
+
{
|
992
|
+
if( comp_( x, key_from_node( n ) ) )
|
993
|
+
{
|
994
|
+
n = n->left;
|
995
|
+
}
|
996
|
+
else if( comp_( key_from_node( n ), x ) )
|
997
|
+
{
|
998
|
+
n = n->right;
|
999
|
+
}
|
1000
|
+
else
|
1001
|
+
{
|
1002
|
+
break;
|
1003
|
+
}
|
1004
|
+
}
|
1005
|
+
|
1006
|
+
if( n == 0 )
|
1007
|
+
{
|
1008
|
+
n = data_;
|
1009
|
+
}
|
1010
|
+
|
1011
|
+
return n;
|
1012
|
+
}
|
1013
|
+
|
1014
|
+
// find first node with key not less than x | complexity : logaritmic | exception : strong, note A
|
1015
|
+
node_base* internal_lower_bound( const key_type& x ) const
|
1016
|
+
{
|
1017
|
+
node_base* p = data_;
|
1018
|
+
node_base* n = data_->parent;
|
1019
|
+
|
1020
|
+
while( n != 0 )
|
1021
|
+
{
|
1022
|
+
if( !comp_( key_from_node( n ), x ) )
|
1023
|
+
{
|
1024
|
+
p = n;
|
1025
|
+
n = n->left;
|
1026
|
+
}
|
1027
|
+
else
|
1028
|
+
{
|
1029
|
+
n = n->right;
|
1030
|
+
}
|
1031
|
+
}
|
1032
|
+
|
1033
|
+
return p;
|
1034
|
+
}
|
1035
|
+
|
1036
|
+
// find first node with key greater than x | complexity : logaritmic | exception : strong, note A
|
1037
|
+
node_base* internal_upper_bound( const key_type& x ) const
|
1038
|
+
{
|
1039
|
+
node_base* p = data_;
|
1040
|
+
node_base* n = data_->parent;
|
1041
|
+
|
1042
|
+
while( n != 0 )
|
1043
|
+
{
|
1044
|
+
if( comp_( x, key_from_node( n ) ) )
|
1045
|
+
{
|
1046
|
+
p = n;
|
1047
|
+
n = n->left;
|
1048
|
+
}
|
1049
|
+
else
|
1050
|
+
{
|
1051
|
+
n = n->right;
|
1052
|
+
}
|
1053
|
+
}
|
1054
|
+
|
1055
|
+
return p;
|
1056
|
+
}
|
1057
|
+
|
1058
|
+
// top-down splay, use t as root | complexity : logaritmic | exception : strong, note A
|
1059
|
+
void splay( const key_type& i, node_base*& t ) const
|
1060
|
+
{
|
1061
|
+
node_base null_node;
|
1062
|
+
node_base* l = &null_node;
|
1063
|
+
node_base* r = &null_node;
|
1064
|
+
|
1065
|
+
for( ;; )
|
1066
|
+
{
|
1067
|
+
if( comp_( i, key_from_node( t ) ) )
|
1068
|
+
{
|
1069
|
+
if( t->left == 0 )
|
1070
|
+
break;
|
1071
|
+
|
1072
|
+
if( comp_( i, key_from_node( t->left ) ) )
|
1073
|
+
{
|
1074
|
+
rotate_right( t );
|
1075
|
+
|
1076
|
+
if( t->left == 0 )
|
1077
|
+
break;
|
1078
|
+
}
|
1079
|
+
|
1080
|
+
link_right( t, r );
|
1081
|
+
}
|
1082
|
+
else if( comp_( key_from_node( t ), i ) )
|
1083
|
+
{
|
1084
|
+
if( t->right == 0 )
|
1085
|
+
break;
|
1086
|
+
|
1087
|
+
if( comp_( key_from_node( t->right ), i ) )
|
1088
|
+
{
|
1089
|
+
rotate_left( t );
|
1090
|
+
|
1091
|
+
if( t->right == 0 )
|
1092
|
+
break;
|
1093
|
+
}
|
1094
|
+
|
1095
|
+
link_left( t, l );
|
1096
|
+
}
|
1097
|
+
else
|
1098
|
+
{
|
1099
|
+
break;
|
1100
|
+
}
|
1101
|
+
}
|
1102
|
+
|
1103
|
+
assemble( t, l, r, null_node );
|
1104
|
+
}
|
1105
|
+
|
1106
|
+
// top-down splay | complexity : logaritmic | exception : strong, note A
|
1107
|
+
void splay( const key_type& x ) const
|
1108
|
+
{
|
1109
|
+
if( data_->parent != 0 )
|
1110
|
+
{
|
1111
|
+
splay( x, data_->parent );
|
1112
|
+
data_->parent->parent = data_;
|
1113
|
+
}
|
1114
|
+
}
|
1115
|
+
|
1116
|
+
private:
|
1117
|
+
size_type size_;
|
1118
|
+
int maxsz_;
|
1119
|
+
key_compare comp_;
|
1120
|
+
allocator_type allocator_;
|
1121
|
+
typename allocator_type::template rebind<node>::other node_allocator_;
|
1122
|
+
};
|
1123
|
+
|
1124
|
+
} // namespace detail
|
1125
|
+
} // namespace swiftcore
|
1126
|
+
|
1127
|
+
#endif // SPLAY_TREE_H_RMA05022003
|