A Kotlin Multiplatform library that generates lexicographically sortable keys for application-defined ordering (e.g., drag-and-drop lists).
Each key is a canonical variable-length byte sequence ending in 0x80. By generating new keys from neighboring items (before / after / between), most inserts can be handled without rewriting the entire list.
import dev.pon.fractionalindexing.FractionalIndex
import dev.pon.fractionalindexing.FractionalIndexGenerator
val center = FractionalIndex.default()
val left = FractionalIndexGenerator.before(center)
val right = FractionalIndexGenerator.after(center)
val mid = FractionalIndexGenerator
.between(left, right)
.getOrThrow()
check(left < mid && mid < right)
Example App
A Kotlin Multiplatform example module is available at example/.
Run the drag-and-drop list demo with ./gradlew :example:jvmRun.
import dev.pon.fractionalindexing.after
import dev.pon.fractionalindexing.before
import dev.pon.fractionalindexing.between
val center = FractionalIndex.default()
val left = center.before()
val right = center.after()
val mid = left.between(right).getOrThrow()
Parse and Encode
val indexFromHex = FractionalIndex.fromHexString("7f80").getOrThrow()
val indexFromSortableBase64 = FractionalIndex.fromSortableBase64String("Us-").getOrThrow()
val indexFromBase64 = FractionalIndex.fromBase64String("f4A=").getOrThrow()
val hex = indexFromHex.toHexString() // "7f80"val sortableBase64 = indexFromSortableBase64.toSortableBase64String() // "Us-"val base64 = indexFromBase64.toBase64String() // "f4A="
fromBytes / fromHexString / fromSortableBase64String / fromBase64String accept canonical library format only.
Ending with 0x80 is necessary but not sufficient: the first byte is also a format tag.
Malformed or non-canonical keys (for example 0080, ff80, ) return failure.
Changes to the key format or generation algorithm that break compatibility with previously generated keys are treated as breaking changes (major version bump).
Changes that only affect the exact canonical keys produced by future calls are not considered breaking as long as existing keys remain valid and continue to sort correctly.
Algorithmic output changes may still be called out in release notes.
Note: Upgrading to a new major version may require migrating your existing database records to maintain the correct sort order.
API Compatibility Check
CI runs ./gradlew :library:checkKotlinAbi --no-configuration-cache to detect binary-incompatible public API changes.
When intentionally changing public API, regenerate the baseline with ./gradlew :library:updateKotlinAbi --no-configuration-cache and commit the updated ABI dump files under library/api/.
Performance Regression Check
Relative and absolute performance regression checks run in regular JVM tests.
CI publishes the measured JVM perf profile and memory observation in the main test workflow so regressions are visible on PRs.