Class: Furnish::RangeSet
- Inherits:
-
Object
- Object
- Furnish::RangeSet
- Defined in:
- lib/furnish/range_set.rb
Direct Known Subclasses
Instance Attribute Summary collapse
-
#allocated ⇒ Object
readonly
A Palsy::Set of the sum of allocated items.
-
#allocation_type ⇒ Object
readonly
The type of thing we’re allocating.
-
#groups ⇒ Object
readonly
A Palsy::Map of the individual groups of items.
-
#name ⇒ Object
readonly
the name of the registry.
-
#range ⇒ Object
readonly
The range we’re allocating from.
Instance Method Summary collapse
-
#allocate(item) ⇒ Object
Allocates an item without putting it in a group.
-
#allocated?(item) ⇒ Boolean
Predicate to determine whether or not an item is already allocated.
-
#assign_group_items(name, items, raise_if_exists = false) ⇒ Object
Assign one or more items to a group.
-
#deallocate(item) ⇒ Object
Deallocates items from the global allocation pool.
-
#decommission_group(name) ⇒ Object
Remove a group and free its allocated item addresses.
-
#group_items(name) ⇒ Object
Get a set of items for a given group.
-
#initialize(range, allocation_type, name = "default") ⇒ RangeSet
constructor
Allocate something from a range.
-
#remove_from_group(name, items) ⇒ Object
Remove the items from the group provided by name, also deallocates them.
-
#replace_group(name, group) ⇒ Object
Overwrite a group for name with a given group.
-
#unused(name = nil) ⇒ Object
Get the next unused item.
Constructor Details
#initialize(range, allocation_type, name = "default") ⇒ RangeSet
Allocate something from a range. Takes a Range object, a type of allocation (which is coerced into a table name, so be nice!) and namespace for the allocations.
See Furnish::item for an example.
33 34 35 36 37 38 39 40 |
# File 'lib/furnish/range_set.rb', line 33 def initialize(range, allocation_type, name="default") @range = range @allocation_type = allocation_type @name = name @allocated = Palsy::Set.new("furnish_#{allocation_type}_allocations", name) @groups = Palsy::Map.new("furnish_#{allocation_type}_groups", name) end |
Instance Attribute Details
#allocated ⇒ Object (readonly)
A Palsy::Set of the sum of allocated items.
11 12 13 |
# File 'lib/furnish/range_set.rb', line 11 def allocated @allocated end |
#allocation_type ⇒ Object (readonly)
The type of thing we’re allocating. No spaces.
24 25 26 |
# File 'lib/furnish/range_set.rb', line 24 def allocation_type @allocation_type end |
#groups ⇒ Object (readonly)
A Palsy::Map of the individual groups of items. Each item yields a set of string item addresses.
16 17 18 |
# File 'lib/furnish/range_set.rb', line 16 def groups @groups end |
#name ⇒ Object (readonly)
the name of the registry.
7 8 9 |
# File 'lib/furnish/range_set.rb', line 7 def name @name end |
#range ⇒ Object (readonly)
The range we’re allocating from.
20 21 22 |
# File 'lib/furnish/range_set.rb', line 20 def range @range end |
Instance Method Details
#allocate(item) ⇒ Object
Allocates an item without putting it in a group. Useful for placeholders.
Makes no attempt to check if something’s allocated already.
73 74 75 |
# File 'lib/furnish/range_set.rb', line 73 def allocate(item) allocated.add(item.encode("UTF-8")) end |
#allocated?(item) ⇒ Boolean
Predicate to determine whether or not an item is already allocated.
87 88 89 |
# File 'lib/furnish/range_set.rb', line 87 def allocated?(item) allocated.include?(item.encode("UTF-8")) end |
#assign_group_items(name, items, raise_if_exists = false) ⇒ Object
Assign one or more items to a group. This method is additive, so multitemle calls will grow the group, not replace it.
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/furnish/range_set.rb', line 110 def assign_group_items(name, items, raise_if_exists=false) group = group_items(name) if items.kind_of?(Array) items = Set[*items] elsif !items.kind_of?(Set) items = Set[items] end c_allocated = allocated.count c_group = group.count items.each do |item| utf8_item = item.encode("UTF-8") allocated.add(utf8_item) group.add(utf8_item) end if raise_if_exists raise unless group.count == c_group + items.count && allocated.count == c_allocated + items.count end replace_group(name, group) return items end |
#deallocate(item) ⇒ Object
Deallocates items from the global allocation pool. Always succeeds.
80 81 82 |
# File 'lib/furnish/range_set.rb', line 80 def deallocate(item) allocated.delete(item.encode("UTF-8")) end |
#decommission_group(name) ⇒ Object
Remove a group and free its allocated item addresses.
157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/furnish/range_set.rb', line 157 def decommission_group(name) group = group_items(name) group.each do |item| deallocate(item) end groups.delete(name) return name end |
#group_items(name) ⇒ Object
Get a set of items for a given group. Returns a Set object regardless of whether the group exists or not (it will just be empty).
95 96 97 |
# File 'lib/furnish/range_set.rb', line 95 def group_items(name) groups[name] || Set.new end |
#remove_from_group(name, items) ⇒ Object
Remove the items from the group provided by name, also deallocates them.
140 141 142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/furnish/range_set.rb', line 140 def remove_from_group(name, items) group = group_items(name) items.each do |item| utf8_item = item.encode("UTF-8") deallocate(utf8_item) group.delete(utf8_item) end replace_group(name, group) return items end |
#replace_group(name, group) ⇒ Object
Overwrite a group for name with a given group.
102 103 104 |
# File 'lib/furnish/range_set.rb', line 102 def replace_group(name, group) groups[name] = group end |
#unused(name = nil) ⇒ Object
Get the next unused item. Will raise if the range is exahusted
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/furnish/range_set.rb', line 45 def unused(name=nil) net = range.first range.count.times do this_item = net.to_s.encode("UTF-8") begin unless allocated.include?(this_item) return name ? assign_group_items(name, this_item, true).first : this_item end rescue end net = net.succ unless range.include?(net.to_s) net = range.first end end raise "No free #{allocation_type} for subnet #{range.inspect}" end |