swiftiply 0.6.1.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTORS +2 -0
  3. data/README.md +62 -0
  4. data/bin/{mongrel_rails → evented_mongrel_rails} +6 -14
  5. data/bin/swiftiplied_mongrel_rails +246 -0
  6. data/bin/swiftiply +136 -116
  7. data/bin/swiftiply_mongrel_rails +2 -2
  8. data/bin/swiftiplyctl +283 -0
  9. data/cleanup.sh +5 -0
  10. data/ext/deque/extconf.rb +162 -0
  11. data/ext/deque/swiftcore/rubymain.cpp +435 -0
  12. data/ext/fastfilereader/extconf.rb +2 -2
  13. data/ext/fastfilereader/mapper.cpp +2 -0
  14. data/ext/map/extconf.rb +161 -0
  15. data/ext/map/rubymain.cpp +500 -0
  16. data/ext/splaytree/extconf.rb +161 -0
  17. data/ext/splaytree/swiftcore/rubymain.cpp +580 -0
  18. data/ext/splaytree/swiftcore/splay_map.h +635 -0
  19. data/ext/splaytree/swiftcore/splay_set.h +575 -0
  20. data/ext/splaytree/swiftcore/splay_tree.h +1127 -0
  21. data/external/httpclient.rb +231 -0
  22. data/external/package.rb +13 -13
  23. data/setup.rb +18 -2
  24. data/src/swiftcore/Swiftiply.rb +417 -773
  25. data/src/swiftcore/Swiftiply/backend_protocol.rb +213 -0
  26. data/src/swiftcore/Swiftiply/cache_base.rb +49 -0
  27. data/src/swiftcore/Swiftiply/cache_base_mixin.rb +52 -0
  28. data/src/swiftcore/Swiftiply/cluster_managers/rest_based_cluster_manager.rb +9 -0
  29. data/src/swiftcore/Swiftiply/cluster_protocol.rb +70 -0
  30. data/src/swiftcore/Swiftiply/config.rb +370 -0
  31. data/src/swiftcore/Swiftiply/config/rest_updater.rb +26 -0
  32. data/src/swiftcore/Swiftiply/constants.rb +101 -0
  33. data/src/swiftcore/Swiftiply/content_cache_entry.rb +44 -0
  34. data/src/swiftcore/Swiftiply/content_response.rb +45 -0
  35. data/src/swiftcore/Swiftiply/control_protocol.rb +49 -0
  36. data/src/swiftcore/Swiftiply/dynamic_request_cache.rb +41 -0
  37. data/src/swiftcore/Swiftiply/etag_cache.rb +64 -0
  38. data/src/swiftcore/Swiftiply/file_cache.rb +46 -0
  39. data/src/swiftcore/Swiftiply/hash_cache_base.rb +22 -0
  40. data/src/swiftcore/Swiftiply/http_recognizer.rb +267 -0
  41. data/src/swiftcore/Swiftiply/loggers/Analogger.rb +21 -0
  42. data/src/swiftcore/Swiftiply/loggers/stderror.rb +13 -0
  43. data/src/swiftcore/Swiftiply/mocklog.rb +10 -0
  44. data/src/swiftcore/Swiftiply/proxy.rb +15 -0
  45. data/src/swiftcore/Swiftiply/proxy_backends/keepalive.rb +286 -0
  46. data/src/swiftcore/Swiftiply/proxy_backends/traditional.rb +286 -0
  47. data/src/swiftcore/Swiftiply/proxy_backends/traditional/redis_directory.rb +87 -0
  48. data/src/swiftcore/Swiftiply/proxy_backends/traditional/static_directory.rb +69 -0
  49. data/src/swiftcore/Swiftiply/proxy_bag.rb +716 -0
  50. data/src/swiftcore/Swiftiply/rest_based_cluster_manager.rb +15 -0
  51. data/src/swiftcore/Swiftiply/splay_cache_base.rb +21 -0
  52. data/src/swiftcore/Swiftiply/support_pagecache.rb +6 -3
  53. data/src/swiftcore/Swiftiply/swiftiply_2_http_proxy.rb +7 -0
  54. data/src/swiftcore/Swiftiply/swiftiply_client.rb +20 -5
  55. data/src/swiftcore/Swiftiply/version.rb +5 -0
  56. data/src/swiftcore/evented_mongrel.rb +26 -8
  57. data/src/swiftcore/hash.rb +43 -0
  58. data/src/swiftcore/method_builder.rb +28 -0
  59. data/src/swiftcore/streamer.rb +46 -0
  60. data/src/swiftcore/swiftiplied_mongrel.rb +91 -23
  61. data/src/swiftcore/types.rb +20 -3
  62. data/swiftiply.gemspec +14 -8
  63. data/test/TC_Deque.rb +152 -0
  64. data/test/TC_ProxyBag.rb +147 -166
  65. data/test/TC_Swiftiply.rb +576 -169
  66. data/test/TC_Swiftiply/mongrel/evented_hello.rb +1 -1
  67. data/test/TC_Swiftiply/mongrel/swiftiplied_hello.rb +1 -1
  68. data/test/TC_Swiftiply/test_serve_static_file_xsendfile/sendfile_client.rb +27 -0
  69. data/test/TC_Swiftiply/test_ssl/bin/validate_ssl_capability.rb +21 -0
  70. data/test/TC_Swiftiply/test_ssl/test.cert +16 -0
  71. data/test/TC_Swiftiply/test_ssl/test.key +15 -0
  72. data/{bin → test/bin}/echo_client +0 -0
  73. metadata +136 -94
  74. data/README +0 -126
  75. 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