Class: TestIds::BinArray

Inherits:
Object
  • Object
show all
Defined in:
lib/test_ids/bin_array.rb

Instance Method Summary collapse

Constructor Details

#initializeBinArray

Returns a new instance of BinArray.



3
4
5
# File 'lib/test_ids/bin_array.rb', line 3

def initialize
  @store = []
end

Instance Method Details

#<<(val) ⇒ Object



7
8
9
10
11
12
13
14
15
# File 'lib/test_ids/bin_array.rb', line 7

def <<(val)
  @store << val
  @store = @store.sort do |a, b|
    a = a.min if a.is_a?(Range)
    b = b.min if b.is_a?(Range)
    a <=> b
  end
  nil
end

#empty?Boolean

Returns:

  • (Boolean)


17
18
19
# File 'lib/test_ids/bin_array.rb', line 17

def empty?
  @store.empty?
end

#freezeObject



21
22
23
# File 'lib/test_ids/bin_array.rb', line 21

def freeze
  @store.freeze
end

#include?(bin) ⇒ Boolean

Returns true if the array contains the given bin number

Returns:

  • (Boolean)


26
27
28
29
30
# File 'lib/test_ids/bin_array.rb', line 26

def include?(bin)
  @store.any? do |v|
    v == bin || (v.is_a?(Range) && bin >= v.min && bin <= v.max)
  end
end

#load_from_serialized(o) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/test_ids/bin_array.rb', line 137

def load_from_serialized(o)
  @store = []
  o.each do |i|
    if i.is_a?(Numeric) || i.is_a?(Range)
      self.<<(i)
    elsif i.is_a?(String)
      # JSON does not serialize ranges well, take care of it here
      if i =~ /^(\d+)\.\.(\d+)$/
        self.<<((Regexp.last_match(1).to_i)..(Regexp.last_match(2).to_i))
      else
        fail "Unknown bin array object type (#{o.class}): #{o}"
      end
    else
      fail "Unknown bin array object type (#{o.class}): #{o}"
    end
  end
end

#maxObject



109
110
111
112
113
114
115
116
# File 'lib/test_ids/bin_array.rb', line 109

def max
  v = @store.last
  if v.is_a?(Range)
    v.max
  else
    v
  end
end

#minObject



100
101
102
103
104
105
106
107
# File 'lib/test_ids/bin_array.rb', line 100

def min
  v = @store.first
  if v.is_a?(Range)
    v.min
  else
    v
  end
end

#next(options = {}) ⇒ Object

Returns the next bin in the array, starting from the first and remembering the last bin when called the next time. A bin can optionally be supplied in which case the internal pointer will be reset and the next bin that occurs after the given number will be returned.



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/test_ids/bin_array.rb', line 36

def next(options = {})
  if options[:after]
    after = options[:after]
    # Need to work out the pointer here as it is probably out of sync with the
    # last value now
    @pointer = nil
    i = 0
    until @pointer
      v = @store[i]
      if v
        if after == v || (v.is_a?(Range) && after >= v.min && after <= v.max)
          @pointer = i
          @next = after
        elsif after < min_val(v)
          @pointer = previous_pointer(i)
          @next = min_val(v) - 1
        end
      else
        # Gone past the end of the array
        @pointer = @store.size - 1
        @next = min_val(@store[0]) - 1
      end
      i += 1
    end
  end
  if @next
    @pointer ||= 0
    if @store[@pointer].is_a?(Range) && @next != @store[@pointer].max
      @next += 1
    else
      @pointer += 1
      # Return nil when we get to the end of the array
      if @pointer == @store.size
        @pointer -= 1
        return nil
      end
      @next = @store[@pointer]
      @next = @next.min if @next.is_a?(Range)
    end
  else
    v = @store.first
    if v.is_a?(Range)
      @next = v.min
    else
      @next = v
    end
  end
  if options[:size] && options[:size] > 1
    # Check that all the numbers in the range to be reserved are included in the allocation,
    # if not call again
    included = true
    options[:size].times { |i| included = false unless include?(@next + i) }
    if included
      n = @next
      @next = @next + options[:size] - 1
      n
    else
      self.next(after: @next, size: options[:size])
    end
  else
    @next
  end
end

#to_json(*a) ⇒ Object



132
133
134
# File 'lib/test_ids/bin_array.rb', line 132

def to_json(*a)
  @store.to_json(*a)
end

#yield_allObject

Yields all number to the given block, one at a time



119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/test_ids/bin_array.rb', line 119

def yield_all
  p = @pointer
  nx = @next
  @pointer = nil
  @next = nil
  while n = self.next
    yield n
  end
  @pointer = p
  @next = nx
  nil
end