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.



5
6
7
# File 'lib/test_ids/bin_array.rb', line 5

def initialize
  @store = []
end

Instance Method Details

#<<(val) ⇒ Object



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

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)


19
20
21
# File 'lib/test_ids/bin_array.rb', line 19

def empty?
  @store.empty?
end

#freezeObject



23
24
25
# File 'lib/test_ids/bin_array.rb', line 23

def freeze
  @store.freeze
end

#include?(bin) ⇒ Boolean

Returns true if the array contains the given bin number

Returns:

  • (Boolean)


28
29
30
31
32
# File 'lib/test_ids/bin_array.rb', line 28

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.



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

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
      fail "Unknown bin array object type (#{o.class}): #{o}" unless 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
  end
end

#maxObject



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

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

#minObject



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

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.



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
99
100
# File 'lib/test_ids/bin_array.rb', line 38

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
    @next = if v.is_a?(Range)
              v.min
            else
              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



134
135
136
# File 'lib/test_ids/bin_array.rb', line 134

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

#yield_allObject

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



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

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