Module: FractionalIndexer

Defined in:
lib/fractional_indexer.rb,
lib/fractional_indexer/version.rb,
lib/fractional_indexer/order_key.rb,
lib/fractional_indexer/midpointer.rb,
lib/fractional_indexer/decrementer.rb,
lib/fractional_indexer/incrementer.rb,
lib/fractional_indexer/configuration.rb

Defined Under Namespace

Classes: Configuration, Decrementer, Error, Incrementer, Midpointer, OrderKey

Constant Summary collapse

VERSION =
"0.4.0"

Class Method Summary collapse

Class Method Details

.configurationObject



26
27
28
# File 'lib/fractional_indexer.rb', line 26

def self.configuration
  @configuration
end

.configure {|configuration| ... } ⇒ Object

Yields:



20
21
22
23
24
# File 'lib/fractional_indexer.rb', line 20

def self.configure
  yield(configuration) if block_given?

  configuration
end

.decrement(order_key) ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/fractional_indexer.rb', line 93

def self.decrement(order_key)
  # NOTE: edge case
  # If an Order key does not have a fractional part and its integer part is equal to
  # the minimum value (for example, in base_62: 'A00000000000000000000000000'),
  # further decrement operations become impossible and will fail.
  # However, this situation is typically unlikely to occur.
  if order_key.minimum?
    raise Error, "order key not decremented: #{order_key} is the minimum value"
  end
  return order_key.integer + Midpointer.execute("", order_key.fractional) if order_key.minimum_integer?

  decremented_order_key = OrderKey.new(order_key.integer < order_key.key ? order_key.integer : order_key.decrement)
  return decremented_order_key.integer + Midpointer.execute if decremented_order_key.minimum?

  decremented_order_key.key
end

.generate_key(prev_key: nil, next_key: nil) ⇒ Object

Raises:



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/fractional_indexer.rb', line 30

def self.generate_key(prev_key: nil, next_key: nil)
  return OrderKey.zero if prev_key.nil? && next_key.nil?

  raise Error, "prev_key and next_key cannot be empty" if prev_key&.empty? || next_key&.empty?

  if !prev_key.nil? && !next_key.nil? && prev_key >= next_key
    raise Error, "#{prev_key} is not less than #{next_key}"
  end

  prev_order_key = OrderKey.new(prev_key)
  next_order_key = OrderKey.new(next_key)

  return decrement(next_order_key) unless prev_order_key.present?
  return increment(prev_order_key) unless next_order_key.present?

  if prev_order_key.integer == next_order_key.integer
    return prev_order_key.integer + Midpointer.execute(prev_order_key.fractional, next_order_key.fractional)
  end

  incremented_order_key = prev_order_key.increment
  if incremented_order_key < next_key
    incremented_order_key
  else
    prev_order_key.integer + Midpointer.execute(prev_order_key.fractional, nil)
  end
end

.generate_keys(prev_key: nil, next_key: nil, count: 1) ⇒ Object



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
# File 'lib/fractional_indexer.rb', line 57

def self.generate_keys(prev_key: nil, next_key: nil, count: 1)
  return [] if count <= 0
  return [generate_key(prev_key: prev_key, next_key: next_key)] if count == 1

  if next_key.nil?
    base_order_key = generate_key(prev_key: prev_key)
    result = [base_order_key]

    (count - 1).times do
      result << generate_key(prev_key: result.last)
    end

    return result
  end

  if prev_key.nil?
    base_order_key = generate_key(next_key: next_key)
    result = [base_order_key]

    (count - 1).times do
      result << generate_key(next_key: result.last)
    end

    return result.reverse
  end

  mid = count / 2
  base_order_key = generate_key(prev_key: prev_key, next_key: next_key)

  [
    *generate_keys(prev_key: prev_key, next_key: base_order_key, count: mid),
    base_order_key,
    *generate_keys(prev_key: base_order_key, next_key: next_key, count: count - mid - 1),
  ]
end

.increment(order_key) ⇒ Object



110
111
112
113
114
# File 'lib/fractional_indexer.rb', line 110

def self.increment(order_key)
  return order_key.integer + Midpointer.execute(order_key.fractional, "") if order_key.maximum_integer?

  order_key.increment
end