Innoloft.LexoRank
1.2.1
dotnet add package Innoloft.LexoRank --version 1.2.1
NuGet\Install-Package Innoloft.LexoRank -Version 1.2.1
<PackageReference Include="Innoloft.LexoRank" Version="1.2.1" />
<PackageVersion Include="Innoloft.LexoRank" Version="1.2.1" />
<PackageReference Include="Innoloft.LexoRank" />
paket add Innoloft.LexoRank --version 1.2.1
#r "nuget: Innoloft.LexoRank, 1.2.1"
#:package Innoloft.LexoRank@1.2.1
#addin nuget:?package=Innoloft.LexoRank&version=1.2.1
#tool nuget:?package=Innoloft.LexoRank&version=1.2.1
LexoRank
A .NET implementation of the Atlassian LexoRank algorithm. LexoRank is a ranking system that allows for efficient reordering of items in a list without requiring updates to other items.
Features
- Core LexoRank Logic: Full implementation of buckets, base36 arithmetic, and rank generation.
- Timestamp Conversion: Convert timestamps to LexoRank values to preserve chronological order.
- String-based Calculation: Helper methods to calculate ranks between two strings.
- Thread-Safe: Immutable design ensures safe concurrent access.
- Robust: Handles edge cases and ensures correct rank distribution.
How It Works
LexoRank is a ranking system that uses lexicographically ordered strings to maintain item positions. Unlike traditional integer-based ranking systems, LexoRank allows you to insert items between any two existing items without updating other items in the list.
Key Concepts
Base36 Encoding: LexoRank uses base36 (0-9, a-z) to represent rank values, providing a large namespace for positions.
Buckets: The system uses three buckets (0, 1, 2) to manage rebalancing. When a bucket becomes too dense with items, you can move items to another bucket to maintain spacing.
Between Operation: The core operation calculates a rank between two existing ranks by finding the lexicographic midpoint.
Example
var rank1 = LexoRank.Min(); // "0|000000:"
var rank2 = LexoRank.Max(); // "0|zzzzzz:"
var middle = rank1.Between(rank2); // "0|hzzzzz:"
var next = middle.GenNext(); // "0|i00007:"
Performance Characteristics
- Insert Between: O(1) - No other items need to be updated
- Generate Next/Previous: O(1) - Constant time operation
- String Comparison: O(n) where n is the length of the rank string (typically 8-10 characters)
- Memory: Each rank is approximately 8-10 bytes as a string
- Thread Safety: All operations are thread-safe due to immutable design
When to Rebalance
While LexoRank minimizes updates, you may need to rebalance when:
- Ranks become very long (>20 characters) due to many insertions
- A bucket becomes too dense
- You want to optimize for shorter rank strings
Rebalancing involves moving items to a different bucket or regenerating ranks with better spacing.
Installation
Install the package via NuGet:
dotnet add package Innoloft.LexoRank
Usage
Basic Usage
using LexoRank;
// Get the minimum and maximum ranks
var min = LexoRank.Min();
var max = LexoRank.Max();
// Get the middle rank
var middle = LexoRank.Middle();
// Generate the next rank
var next = middle.GenNext();
// Generate the previous rank
var prev = middle.GenPrev();
// Calculate a rank between two ranks
var between = min.Between(max);
Timestamp to LexoRank
You can convert a DateTime to a LexoRank. This is useful for initializing ranks based on creation time.
var now = DateTime.UtcNow;
var rank = LexoRank.FromTimestamp(now);
String-based Calculation
If you are storing ranks as strings and want to calculate a new rank between two existing rank strings:
string prevRank = "0|000000:";
string nextRank = "0|zzzzzz:";
// Calculate rank between prev and next
var newRank = LexoRank.CalculateBetween(prevRank, nextRank);
// Calculate rank at the beginning (before nextRank)
var startRank = LexoRank.CalculateBetween(null, nextRank);
// Calculate rank at the end (after prevRank)
var endRank = LexoRank.CalculateBetween(prevRank, null);
Buckets
LexoRank uses buckets to manage rebalancing. This implementation supports the standard 3 buckets (0, 1, 2).
// Get the bucket of a rank
var bucket = rank.Bucket;
// Move to the next bucket
var nextBucketRank = rank.InNextBucket();
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
License
MIT
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- No dependencies.
-
net10.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.