Fractional Indexer
efficient data insertion and sorting through fractional indexing
This gem is designed to achieve "Realtime editing of ordered sequences" as featured in a Figma blog post.
Specifically, it implements Fractional Indexing as a means of managing order, realized through strings. By managing indexes as strings, it significantly delays the occurrence of index duplication that can arise when implementing Fractional Indexing with floating-point numbers. Additionally, using strings allows for the representation of a much larger range of numbers in a single digit compared to decimal numbers (by default, a single digit is represented in base-62).
This gem was implemented based on the excellent article "Implementing Fractional Indexing." I would like to express my gratitude to David Greenspan, the author of the article.
Installation
Add this line to your application's Gemfile:
gem 'fractional_indexer'
And then execute:
bundle
Or install it yourself as:
gem install fractional_indexer
Usage
Generate Order key
To generate an order key, use the FractionalIndexer.generate_key
method.
This method can take two arguments: prev_key and next_key, both of which can be either nil or a string (excluding empty strings).
The characters that can be used in the strings are available for review in FractionalIndexer.configuration.digits
.
require 'fractional_indexer'
FractionalIndexer.generate_key
FractionalIndexer.generate_key(prev_key: 'a0')
FractionalIndexer.generate_key(next_key: 'a0')
FractionalIndexer.generate_key(prev_key: 'a0', next_key: 'a2')
FractionalIndexer.generate_key(prev_key: 'a2', next_key: 'a1')
FractionalIndexer.generate_key(prev_key: 'a1', next_key: 'a1')
Generate Multiple Order keys
To generate multiple order keys, use the FractionalIndexer.generate_keys
method.
require 'fractional_indexer'
FractionalIndexer.generate_keys(prev_key: "b11", count: 5)
FractionalIndexer.generate_keys(next_key: "b11", count: 5)
FractionalIndexer.generate_keys(prev_key: "b10", next_key: "b11", count: 5)
Configure
base
You can set the base (number system) used to represent each digit.
The possible values are :base_10, :base_62, and :base_94. (The default is :base_62)
Note: base_10 is primarily intended for operational verification and debugging purposes.
require 'fractional_indexer'
FractionalIndexer.configure do |config|
config.base = :base_10
end
FractionalIndexer.configuration.digits.join
FractionalIndexer.configure do |config|
config.base = :base_62
end
FractionalIndexer.configuration.digits.join
FractionalIndexer.configure do |config|
config.base = :base_94
end
FractionalIndexer.configuration.digits.join
Order key
This section explains the structure of the string that represents an Order Key.
An Order Key string is broadly divided into two parts: the integer part and the fractional part.
Note: For ease of understanding, the explanation from here on will be based on the decimal system ('0' ~ '9')
Integer Part
The integer part of the Order Key begins with a mandatory prefix
that indicates the number of digits. This prefix is represented by one of the letters A to Z or a to z.
a is 1 digit, b is 2 digits, c is 3 digits ...... and z represents 26 digits.
The number of characters following the prefix must match the number of digits indicated by the prefix.
For example, if the prefix is a, a valid key could be 'a8', and if the prefix is c, a valid key could be 'c135'.
'a9'
'b10'
'b9'
'c123'
'c12'
Additionally, leveraging the characteristic that uppercase letters have a lower ASCII value than lowercase letters, a to z represent positive integers, while A to Z represent negative integers.
Fractional Part
The Fractional Part refers to the portion of the string that follows the Integer Part, excluding the Integer Part itself.
'a3012'
The Fractional Part cannot end with the first character of the base being used (e.g., '0' in base_10). This rule mirrors the mathematical principle that, for example, 0.3 and 0.30 represent the same value.
'a32'
'a320'
This section clarifies the concept and rules regarding the Fractional Part of an Order Key, with examples to illustrate what constitutes a valid or invalid Fractional Part.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/kazu-2020/fractional_indexer.
License
The gem is available as open source under the terms of the MIT License.