~ubuntu-branches/ubuntu/wily/trafficserver/wily

« back to all changes in this revision

Viewing changes to lib/ts/IpMap.h

  • Committer: Package Import Robot
  • Author(s): Adam Conrad
  • Date: 2012-12-17 22:28:16 UTC
  • mfrom: (5.1.8 raring-proposed)
  • Revision ID: package-import@ubuntu.com-20121217222816-7xwjsx5k76zkb63d
Tags: 3.2.0-1ubuntu1
* Revert FreeBSD strerror_r() fixes that give errors with glibc 2.16.
* Apply patch from Konstantinos Margaritis to define barriers on ARM.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# if ! defined(TS_IP_MAP_HEADER)
 
2
# define TS_IP_MAP_HEADER
 
3
 
 
4
# include "ink_platform.h"
 
5
# include "ink_port.h"
 
6
# include <ts/ink_inet.h>
 
7
# include <ts/IntrusiveDList.h>
 
8
# include <ts/ink_assert.h>
 
9
 
 
10
/** @file
 
11
 
 
12
    Map of IP addresses to client data.
 
13
 
 
14
    @section license License
 
15
 
 
16
    Licensed to the Apache Software Foundation (ASF) under one
 
17
    or more contributor license agreements.  See the NOTICE file
 
18
    distributed with this work for additional information
 
19
    regarding copyright ownership.  The ASF licenses this file
 
20
    to you under the Apache License, Version 2.0 (the
 
21
    "License"); you may not use this file except in compliance
 
22
    with the License.  You may obtain a copy of the License at
 
23
 
 
24
      http://www.apache.org/licenses/LICENSE-2.0
 
25
 
 
26
    Unless required by applicable law or agreed to in writing, software
 
27
    distributed under the License is distributed on an "AS IS" BASIS,
 
28
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
29
    See the License for the specific language governing permissions and
 
30
    limitations under the License.
 
31
*/
 
32
 
 
33
namespace ts { namespace detail {
 
34
 
 
35
  /** Interval class.
 
36
      This holds an interval based on a metric @a T along with
 
37
      client data.
 
38
  */
 
39
  template <
 
40
    typename T, ///< Metric for span.
 
41
    typename A  = T const& ///< Argument type.
 
42
  > struct Interval {
 
43
    typedef T Metric; ///< Metric (storage) type.
 
44
    typedef A ArgType; ///< Type used to pass instances of @c Metric.
 
45
 
 
46
    Interval() {} ///< Default constructor.
 
47
    /// Construct with values.
 
48
    Interval(
 
49
      ArgType min, ///< Minimum value in span.
 
50
      ArgType max ///< Maximum value in span.
 
51
    ) : _min(min), _max(max) {}
 
52
    Metric _min; ///< Minimum value in span.
 
53
    Metric _max; ///< Maximum value in span.
 
54
  };
 
55
 
 
56
  class Ip4Map; // Forward declare.
 
57
  class Ip6Map; // Forward declare.
 
58
 
 
59
  /** A node in a red/black tree.
 
60
 
 
61
      This class provides only the basic tree operations. The client
 
62
      must provide the search and decision logic. This enables this
 
63
      class to be a base class for templated nodes with much less code
 
64
      duplication.
 
65
  */
 
66
  struct RBNode {
 
67
    typedef RBNode self; ///< self reference type
 
68
 
 
69
    /// Node colors
 
70
    typedef enum { RED, BLACK } Color;
 
71
 
 
72
    /// Directional constants
 
73
    typedef enum { NONE, LEFT, RIGHT } Direction;
 
74
 
 
75
    /// Get a child by direction.
 
76
    /// @return The child in the direction @a d if it exists,
 
77
    /// @c NULL if not.
 
78
    self* getChild(
 
79
      Direction d //!< The direction of the desired child
 
80
    ) const;
 
81
 
 
82
    /** Determine which child a node is
 
83
        @return @c LEFT if @a n is the left child,
 
84
        @c RIGHT if @a n is the right child,
 
85
        @c NONE if @a n is not a child
 
86
    */
 
87
    Direction getChildDirection(
 
88
      self* const& n //!< The presumed child node
 
89
    ) const {
 
90
      return (n == _left) ? LEFT : (n == _right) ? RIGHT : NONE;
 
91
    }
 
92
 
 
93
    /** Get the parent node.
 
94
        @return A Node* to the parent node or a @c nil Node* if no parent.
 
95
    */
 
96
    self* getParent() const { return const_cast<self*>(_parent); }
 
97
 
 
98
    /// @return The color of the node.
 
99
    Color getColor() const { return _color; }
 
100
 
 
101
    /** Reverse a direction
 
102
        @return @c LEFT if @a d is @c RIGHT, @c RIGHT if @a d is @c LEFT,
 
103
        @c NONE otherwise.
 
104
    */
 
105
    Direction flip(Direction d) {
 
106
      return LEFT == d ? RIGHT : RIGHT == d ? LEFT : NONE;
 
107
    }
 
108
 
 
109
    /** Perform internal validation checks.
 
110
        @return 0 on failure, black height of the tree on success.
 
111
    */
 
112
    int validate();
 
113
 
 
114
    /// Default constructor.
 
115
    RBNode()
 
116
      : _color(RED)
 
117
      , _parent(0)
 
118
      , _left(0)
 
119
      , _right(0)
 
120
      , _next(0)
 
121
      , _prev(0) {
 
122
    }
 
123
 
 
124
    /// Destructor (force virtual).
 
125
    virtual ~RBNode() { }
 
126
 
 
127
    /** Rotate the subtree rooted at this node.
 
128
        The node is rotated in to the position of one of its children.
 
129
        Which child is determined by the direction parameter @a d. The
 
130
        child in the other direction becomes the new root of the subtree.
 
131
 
 
132
        If the parent pointer is set, then the child pointer of the original
 
133
        parent is updated so that the tree is left in a consistent state.
 
134
 
 
135
        @note If there is no child in the other direction, the rotation
 
136
        fails and the original node is returned. It is @b not required
 
137
        that a child exist in the direction specified by @a d.
 
138
 
 
139
        @return The new root node for the subtree.
 
140
    */
 
141
    self* rotate(
 
142
      Direction d //!< The direction to rotate
 
143
    );
 
144
 
 
145
    /** Set the child node in direction @a d to @a n.
 
146
        The @a d child is set to the node @a n. The pointers in this
 
147
        node and @a n are set correctly. This can only be called if
 
148
        there is no child node already present.
 
149
 
 
150
        @return @a n.
 
151
    */
 
152
    self* setChild(
 
153
      self* n, //!< The node to set as the child
 
154
      Direction d //!< The direction of the child
 
155
    );
 
156
 
 
157
    /** Remove this node from the tree.
 
158
        The tree is rebalanced after removal.
 
159
        @return The new root node.
 
160
    */
 
161
    self* remove();
 
162
 
 
163
    void clearChild(Direction dir) {
 
164
      if (LEFT == dir) _left = 0;
 
165
      else if (RIGHT == dir) _right = 0;
 
166
    }
 
167
 
 
168
    /** @name Subclass hook methods */
 
169
    //@{
 
170
    /** Structural change notification.
 
171
        This method is called if the structure of the subtree rooted at
 
172
        this node was changed.
 
173
                        
 
174
        This is intended a hook. The base method is empty so that subclasses
 
175
        are not required to override.
 
176
    */
 
177
    virtual void structureFixup() {}
 
178
 
 
179
    /** Called from @c validate to perform any additional validation checks.
 
180
        Clients should chain this if they wish to perform additional checks.
 
181
        @return @c true if the validation is successful, @c false otherwise.
 
182
        @note The base method simply returns @c true.
 
183
    */
 
184
    virtual bool structureValidate() { return true; }
 
185
    //@}
 
186
 
 
187
    /** Replace this node with another node.
 
188
        This is presumed to be non-order modifying so the next reference
 
189
        is @b not updated.
 
190
    */
 
191
    void replaceWith(
 
192
      self* n //!< Node to put in place of this node.
 
193
    );
 
194
 
 
195
    //! Rebalance the tree starting at this node
 
196
    /** The tree is rebalanced so that all of the invariants are
 
197
        true. The (potentially new) root of the tree is returned.
 
198
 
 
199
        @return The root node of the tree after the rebalance.
 
200
    */
 
201
    self* rebalanceAfterInsert();
 
202
                
 
203
    /** Rebalance the tree after a deletion.
 
204
        Called on the lowest modified node.
 
205
        @return The new root of the tree.
 
206
    */
 
207
    self* rebalanceAfterRemove(
 
208
      Color c, //!< The color of the removed node.
 
209
      Direction d //!< Direction of removed node from parent
 
210
    );
 
211
 
 
212
    //! Invoke @c structure_fixup() on this node and all of its ancestors.
 
213
    self* rippleStructureFixup();
 
214
 
 
215
    Color _color;  ///< node color
 
216
    self* _parent; ///< parent node (needed for rotations)
 
217
    self* _left;   ///< left child
 
218
    self* _right;  ///< right child
 
219
    self* _next; ///< Next node.
 
220
    self* _prev; ///< Previous node.
 
221
  };
 
222
 
 
223
}} // namespace ts::detail
 
224
 
 
225
/** Map from IP addresses to client data.
 
226
 
 
227
    Conceptually this class maps the entire space of IP addresses to
 
228
    client data. Client data is stored as a @c (void*). Memory
 
229
    management of the data is left to the client. The interface
 
230
    supports marking ranges of addresses with a specific client
 
231
    data. Marking takes a painter's algorithm approach -- any marking
 
232
    overwrites any previous marking on an address. Details of marking
 
233
    calls are discarded and only the final results are kept. That is,
 
234
    a client cannot unmark expliticly any previous marking. Only a
 
235
    specific range of addresses can be unmarked.
 
236
 
 
237
    Both IPv4 and IPv6 are supported in the same map. Mixed ranges are
 
238
    not supported (any particular range of addresses must be a single
 
239
    protocol but ranges of both types can be in the map).
 
240
 
 
241
    Use @c mark to mark / set / add addresses to the map.
 
242
    Use @c unmark to unset addresses (setting the client data to 0 does
 
243
    @b not remove the address -- this is for the convenience of clients
 
244
    that do not need data, only membership). @c contains tests for
 
245
    membership and retrieves the client data.
 
246
 
 
247
    Ranges can be marked and unmarked arbitrarily. The internal
 
248
    representation keeps a minimal set of ranges to describe the
 
249
    current addresses. Search time is O(log n) where n is the number
 
250
    of disjoint ranges. Marking and unmarking can take O(log n) and
 
251
    may require memory allocation / deallocation although this is
 
252
    minimized.
 
253
 
 
254
*/
 
255
 
 
256
class IpMap {
 
257
public:
 
258
  typedef IpMap self; ///< Self reference type.
 
259
 
 
260
  class iterator; // forward declare.
 
261
  
 
262
  /** Public API for intervals in the map.
 
263
  */
 
264
  class Node : protected ts::detail::RBNode {
 
265
    friend class iterator;
 
266
    friend class IpMap;
 
267
  public:
 
268
    typedef Node self; ///< Self reference type.
 
269
    /// Default constructor.
 
270
    Node() : _data(0) {}
 
271
    /// Construct with @a data.
 
272
    Node(void* data) : _data(data) {}
 
273
    /// @return Client data for the node.
 
274
    virtual void* data() { return _data; }
 
275
    /// Set client data.
 
276
    virtual self& setData(
 
277
      void* data ///< Client data pointer to store.
 
278
    ) {
 
279
      _data = data;
 
280
      return *this;
 
281
    }
 
282
    /// @return Minimum value of the interval.
 
283
    virtual sockaddr const* min() const = 0;
 
284
    /// @return Maximum value of the interval.
 
285
    virtual sockaddr const* max() const = 0;
 
286
  protected:
 
287
    void* _data; ///< Client data.
 
288
  };
 
289
 
 
290
  /** Iterator over nodes / intervals.
 
291
 
 
292
      The iteration is over all nodes, regardless of which node is
 
293
      used to create the iterator. The node passed to the constructor
 
294
      just sets the current location.
 
295
  */
 
296
  class iterator {
 
297
    friend class IpMap;
 
298
  public:
 
299
    typedef iterator self; ///< Self reference type.
 
300
    typedef Node value_type; ///< Referenced type for iterator.
 
301
    typedef int difference_type; ///< Distance type.
 
302
    typedef Node* pointer; ///< Pointer to referent.
 
303
    typedef Node& reference; ///< Reference to referent.
 
304
    typedef std::bidirectional_iterator_tag iterator_category;
 
305
    /// Default constructor.
 
306
    iterator() : _tree(0), _node(0) {}
 
307
 
 
308
    reference operator* (); //!< value operator
 
309
    pointer operator -> (); //!< dereference operator
 
310
    self& operator++(); //!< next node (prefix)
 
311
    self operator++(int); //!< next node (postfix)
 
312
    self& operator--(); ///< previous node (prefix)
 
313
    self operator--(int); ///< next node (postfix)
 
314
 
 
315
    /** Equality.
 
316
        @return @c true if the iterators refer to the same node.
 
317
    */
 
318
    bool operator==(self const& that) const;
 
319
    /** Inequality.
 
320
        @return @c true if the iterators refer to different nodes.
 
321
    */
 
322
    bool operator!=(self const& that) const { return ! (*this == that); }
 
323
  private:
 
324
    /// Construct a valid iterator.
 
325
    iterator(IpMap* tree, Node* node) : _tree(tree), _node(node) {}
 
326
      IpMap* _tree; ///< Container.
 
327
      Node* _node; //!< Current node.
 
328
    };
 
329
 
 
330
  IpMap(); ///< Default constructor.
 
331
  ~IpMap(); ///< Destructor.
 
332
 
 
333
  /** Mark a range.
 
334
      All addresses in the range [ @a min , @a max ] are marked with @a data.
 
335
      @return This object.
 
336
  */
 
337
  self& mark(
 
338
    sockaddr const* min, ///< Minimum value in range.
 
339
    sockaddr const* max, ///< Maximum value in range.
 
340
    void* data = 0     ///< Client data payload.
 
341
  );
 
342
 
 
343
  /** Mark a range.
 
344
      All addresses in the range [ @a min , @a max ] are marked with @a data.
 
345
      @note Convenience overload for IPv4 addresses.
 
346
      @return This object.
 
347
  */
 
348
  self& mark(
 
349
    in_addr_t min, ///< Minimum address (network order).
 
350
    in_addr_t max, ///< Maximum address (network order).
 
351
    void* data = 0 ///< Client data.
 
352
  );
 
353
 
 
354
  /** Mark an IPv4 address @a addr with @a data.
 
355
      This is equivalent to calling @c mark(addr, addr, data).
 
356
      @note Convenience overload for IPv4 addresses.
 
357
      @return This object.
 
358
  */
 
359
  self& mark(
 
360
    in_addr_t addr, ///< Address (network order).
 
361
    void* data = 0 ///< Client data.
 
362
  );
 
363
 
 
364
  /** Mark a range.
 
365
      All addresses in the range [ @a min , @a max ] are marked with @a data.
 
366
      @note Convenience overload.
 
367
      @return This object.
 
368
  */
 
369
  self& mark(
 
370
    IpEndpoint const* min, ///< Minimum address (network order).
 
371
    IpEndpoint const* max, ///< Maximum address (network order).
 
372
    void* data = 0 ///< Client data.
 
373
  );
 
374
 
 
375
  /** Mark an IPv6 address @a addr with @a data.
 
376
      This is equivalent to calling @c mark(addr, addr, data).
 
377
      @note Convenience overload.
 
378
      @return This object.
 
379
  */
 
380
  self& mark(
 
381
    IpEndpoint const* addr, ///< Address (network order).
 
382
    void* data = 0 ///< Client data.
 
383
  );
 
384
 
 
385
  /** Unmark addresses.
 
386
 
 
387
      All addresses in the range [ @a min , @a max ] are cleared
 
388
      (removed from the map), no longer marked.
 
389
 
 
390
      @return This object.
 
391
  */
 
392
  self& unmark(
 
393
    sockaddr const* min, ///< Minimum value.
 
394
    sockaddr const* max  ///< Maximum value.
 
395
  );
 
396
  /// Unmark addresses (overload).
 
397
  self& unmark(
 
398
    IpEndpoint const* min,
 
399
    IpEndpoint const* max
 
400
  );
 
401
  /// Unmark overload.
 
402
  self& unmark(
 
403
    in_addr_t min, ///< Minimum of range to unmark.
 
404
    in_addr_t max  ///< Maximum of range to unmark.
 
405
  );
 
406
 
 
407
  /** Fill addresses.
 
408
 
 
409
      This background fills using the range. All addresses in the
 
410
      range that are @b not present in the map are added. No
 
411
      previously present address is changed.
 
412
 
 
413
      @note This is useful for filling in first match tables.
 
414
 
 
415
      @return This object.
 
416
  */
 
417
  self& fill(
 
418
    sockaddr const* min,
 
419
    sockaddr const* max,
 
420
    void* data = 0
 
421
  );
 
422
  /// Fill addresses (overload).
 
423
  self& fill(
 
424
    IpEndpoint const* min,
 
425
    IpEndpoint const* max,
 
426
    void* data = 0
 
427
  );
 
428
  /// Fill addresses (overload).
 
429
  self& fill(
 
430
    in_addr_t min,
 
431
    in_addr_t max,
 
432
    void* data = 0
 
433
  );
 
434
 
 
435
  /** Test for membership.
 
436
 
 
437
      @return @c true if the address is in the map, @c false if not.
 
438
      If the address is in the map and @a ptr is not @c NULL, @c *ptr
 
439
      is set to the client data for the address.
 
440
  */
 
441
  bool contains(
 
442
    sockaddr const* target, ///< Search target (network order).
 
443
    void **ptr = 0 ///< Client data return.
 
444
  ) const;
 
445
 
 
446
  /** Test for membership.
 
447
 
 
448
      @note Covenience overload for IPv4.
 
449
 
 
450
      @return @c true if the address is in the map, @c false if not.
 
451
      If the address is in the map and @a ptr is not @c NULL, @c *ptr
 
452
      is set to the client data for the address.
 
453
  */
 
454
  bool contains(
 
455
    in_addr_t target, ///< Search target (network order).
 
456
    void **ptr = 0 ///< Client data return.
 
457
  ) const;
 
458
 
 
459
  bool contains(
 
460
    IpEndpoint const* target, ///< Search target (network order).
 
461
    void **ptr = 0 ///< Client data return.
 
462
  ) const;
 
463
 
 
464
  /** Remove all addresses from the map.
 
465
 
 
466
      @note This is much faster than @c unmark.
 
467
      @return This object.
 
468
  */
 
469
  self& clear();
 
470
 
 
471
  /// Iterator for first element.
 
472
  iterator begin();
 
473
  /// Iterator past last element.
 
474
  iterator end();
 
475
  /// @return Number of distinct ranges in the map.
 
476
  size_t getCount() const;
 
477
 
 
478
  /** Validate internal data structures.
 
479
      @note Intended for debugging, not general client use.
 
480
  */
 
481
  void validate();
 
482
 
 
483
  /// Print all spans.
 
484
  /// @return This map.
 
485
  //  self& print();
 
486
 
 
487
protected:
 
488
  /// Force the IPv4 map to exist.
 
489
  /// @return The IPv4 map.
 
490
  ts::detail::Ip4Map* force4();
 
491
  /// Force the IPv6 map to exist.
 
492
  /// @return The IPv6 map.
 
493
  ts::detail::Ip6Map* force6();
 
494
  
 
495
  ts::detail::Ip4Map* _m4; ///< Map of IPv4 addresses.
 
496
  ts::detail::Ip6Map* _m6; ///< Map of IPv6 addresses.
 
497
  
 
498
};
 
499
 
 
500
inline IpMap& IpMap::mark(in_addr_t addr, void* data) {
 
501
  return this->mark(addr, addr, data);
 
502
}
 
503
 
 
504
inline IpMap& IpMap::mark(IpEndpoint const* addr, void* data) {
 
505
  return this->mark(&addr->sa, &addr->sa, data);
 
506
}
 
507
 
 
508
inline IpMap& IpMap::mark(IpEndpoint const* min, IpEndpoint const* max, void* data) {
 
509
  return this->mark(&min->sa, &max->sa, data);
 
510
}
 
511
 
 
512
inline IpMap& IpMap::unmark(IpEndpoint const* min, IpEndpoint const* max) {
 
513
  return this->unmark(&min->sa, &max->sa);
 
514
}
 
515
 
 
516
inline IpMap& IpMap::fill(IpEndpoint const* min, IpEndpoint const* max, void* data) {
 
517
  return this->fill(&min->sa, &max->sa, data);
 
518
}
 
519
 
 
520
inline bool IpMap::contains(IpEndpoint const* target, void** ptr) const {
 
521
  return this->contains(&target->sa, ptr);
 
522
}
 
523
 
 
524
inline IpMap::iterator
 
525
IpMap::end() {
 
526
  return iterator(this, 0);
 
527
}
 
528
 
 
529
inline IpMap::iterator
 
530
IpMap::iterator::operator ++ (int) {
 
531
  iterator old(*this);
 
532
  ++*this;
 
533
  return old;
 
534
}
 
535
 
 
536
inline IpMap::iterator
 
537
IpMap::iterator::operator--(int) {
 
538
  self tmp(*this);
 
539
  --*this;
 
540
  return tmp;
 
541
}
 
542
 
 
543
inline bool
 
544
IpMap::iterator::operator == (iterator const& that) const {
 
545
  return _tree == that._tree && _node == that._node;
 
546
}
 
547
 
 
548
inline IpMap::iterator::reference
 
549
IpMap::iterator::operator * () {
 
550
  return *_node;
 
551
}
 
552
 
 
553
inline IpMap::iterator::pointer
 
554
IpMap::iterator::operator -> () {
 
555
  return _node;
 
556
}
 
557
 
 
558
inline IpMap::IpMap() : _m4(0), _m6(0) {}
 
559
 
 
560
# endif // TS_IP_MAP_HEADER