Class: Narabikae::Position

Inherits:
Object
  • Object
show all
Defined in:
lib/narabikae/position.rb

Instance Method Summary collapse

Constructor Details

#initialize(record, option) ⇒ Position

Initializes a new instance of the Position class.

Parameters:

  • record (Object)

    Active Record object.

  • option (Option)


7
8
9
10
# File 'lib/narabikae/position.rb', line 7

def initialize(record, option)
  @record = record
  @option = option
end

Instance Method Details

#create_last_positionString

Generates a new key for the last position

Returns:

  • (String)

    The newly generated key for the last position.



15
16
17
# File 'lib/narabikae/position.rb', line 15

def create_last_position
  FractionalIndexer.generate_key(prev_key: current_last_position)
end

#find_position_after(target, **args) ⇒ String?

Finds the position after the specified target. If generated key is invalid(ex: it already exists), a new key is generated until the challenge count reaches the limit. challenge count is 10 by default.

Parameters:

  • target (#send(field))
  • args (Hash)

    Additional arguments.

Options Hash (**args):

  • :challenge (Integer)

    The number of times to attempt finding a valid position.

Returns:

  • (String, nil)

    The generated key for the position after the target, or nil if no valid position is found.



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/narabikae/position.rb', line 28

def find_position_after(target, **args)
  merged_args = { challenge: 10 }.merge(args)
  # when target is nil, try to generate key from the last position
  key = FractionalIndexer.generate_key(
          prev_key: target&.send(option.field) || current_last_position
        )
  return key if valid?(key)

  (merged_args[:challenge] || 0).times do
    key += random_fractional
    return key if valid?(key)
  end

  nil
rescue FractionalIndexer::Error
  nil
end

#find_position_before(target, **args) ⇒ String?

Finds the position before the target position. If generated key is invalid(ex: it already exists), a new key is generated until the challenge count reaches the limit. challenge count is 10 by default.

Examples:

position = Position.new
position.find_position_before(target, challenge: 5)

Parameters:

  • target (#send(field))
  • args (Hash)

    Additional arguments.

Options Hash (**args):

  • :challenge (Integer)

    The number of times to attempt finding a valid position.

Returns:

  • (String, nil)

    The generated key for the position before the target, or nil if no valid position is found.



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/narabikae/position.rb', line 60

def find_position_before(target, **args)
  merged_args = { challenge: 10 }.merge(args)
  # when target is nil, try to generate key from the first position
  key = FractionalIndexer.generate_key(
          next_key: target&.send(option.field) || current_first_position
        )
  return key if valid?(key)

  (merged_args[:challenge] || 0).times do
    key += random_fractional
    return key if valid?(key)
  end

  nil
rescue FractionalIndexer::Error
  nil
end

#find_position_between(prev_target, next_target, **args) ⇒ string?

Finds the position between two targets.

Parameters:

  • prev_target (#send(field))

    The previous target.

  • next_target (#send(field))

    The next target.

  • args (Hash)

    Additional arguments.

Options Hash (**args):

  • :challenge (Integer)

    The number of times to attempt finding a valid position.

Returns:

  • (string, nil)

    The position between the two targets, or nil if no valid position is found.



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/narabikae/position.rb', line 85

def find_position_between(prev_target, next_target, **args)
  return find_position_before(next_target, **args) if prev_target.blank?
  return find_position_after(prev_target, **args)  if next_target.blank?

  merged_args = { challenge: 10 }.merge(args)

  prev_key, next_key = [ prev_target.send(option.field), next_target.send(option.field) ].minmax
  key = FractionalIndexer.generate_key(
          prev_key: prev_key,
          next_key: next_key,
        )
  return key if valid?(key)

  (merged_args[:challenge] || 0).times do
    key += random_fractional
    return key if valid?(key)
  end

  nil
rescue FractionalIndexer::Error
  nil
end