Class: Furnish::RangeSet

Inherits:
Object
  • Object
show all
Defined in:
lib/furnish/range_set.rb

Direct Known Subclasses

IP

Instance Attribute Summary collapse

Instance Method Summary collapse

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

#allocatedObject (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_typeObject (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

#groupsObject (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

#nameObject (readonly)

the name of the registry.



7
8
9
# File 'lib/furnish/range_set.rb', line 7

def name
  @name
end

#rangeObject (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.

Returns:

  • (Boolean)


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