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.
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