Class: TestIds::BinArray

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

Instance Method Summary collapse

Constructor Details

#initialize ⇒ BinArray

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

#freeze ⇒ Object



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

#max ⇒ Object



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

#min ⇒ Object



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