{"id":22073349,"url":"https://github.com/jp-ellis/rust-skiplist","last_synced_at":"2026-03-14T23:44:40.326Z","repository":{"id":28027631,"uuid":"31522912","full_name":"JP-Ellis/rust-skiplist","owner":"JP-Ellis","description":"Skiplist implementation in rust","archived":false,"fork":false,"pushed_at":"2025-05-15T19:37:23.000Z","size":369,"stargazers_count":95,"open_issues_count":11,"forks_count":16,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-05-16T06:06:46.391Z","etag":null,"topics":["crates","rust","skiplist"],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JP-Ellis.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2015-03-02T04:08:00.000Z","updated_at":"2025-05-15T19:23:54.000Z","dependencies_parsed_at":"2024-06-21T14:14:49.171Z","dependency_job_id":"f530dbe4-8072-4291-8512-5af6aa849b3a","html_url":"https://github.com/JP-Ellis/rust-skiplist","commit_stats":{"total_commits":127,"total_committers":8,"mean_commits":15.875,"dds":0.5354330708661417,"last_synced_commit":"bc44211f7068e1037a2a40a4dbe26a196cfddf3a"},"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JP-Ellis%2Frust-skiplist","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JP-Ellis%2Frust-skiplist/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JP-Ellis%2Frust-skiplist/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JP-Ellis%2Frust-skiplist/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JP-Ellis","download_url":"https://codeload.github.com/JP-Ellis/rust-skiplist/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254478190,"owners_count":22077676,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["crates","rust","skiplist"],"created_at":"2024-11-30T21:18:03.957Z","updated_at":"2026-03-11T01:07:14.039Z","avatar_url":"https://github.com/JP-Ellis.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# skiplist\n\n\u003c!-- markdownlint-disable no-inline-html --\u003e\n\u003cdiv align=\"center\"\u003e\u003ctable\u003e\n    \u003ctr\u003e\n        \u003ctd\u003ePackage\u003c/td\u003e\n        \u003ctd\u003e\n            \u003ca href=\"https://crates.io/crates/skiplist\"\u003e\u003cimg src=\"https://img.shields.io/crates/v/skiplist.svg\" alt=\"Version\"\u003e\u003c/a\u003e\n            \u003ca href=\"https://docs.rs/skiplist/latest/skiplist/\"\u003e\u003cimg src=\"https://img.shields.io/docsrs/skiplist\" alt=\"docs.rs\"\u003e\u003c/a\u003e\n            \u003ca href=\"https://crates.io/crates/skiplist\"\u003e\u003cimg src=\"https://img.shields.io/crates/d/skiplist.svg\" alt=\"Downloads\"\u003e\u003c/a\u003e\n        \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003ctd\u003eCI/CD\u003c/td\u003e\n        \u003ctd\u003e\n            \u003ca href=\"https://github.com/JP-Ellis/rust-skiplist/actions/workflows/test.yml?query=branch:main\"\u003e\u003cimg\n                src=\"https://img.shields.io/github/actions/workflow/status/JP-Ellis/rust-skiplist/test.yml?branch=main\u0026label=test\"\n                alt=\"Test Pipeline\"\u003e\u003c/a\u003e\n            \u003ca href=\"https://github.com/JP-Ellis/rust-skiplist/actions/workflows/release-plz.yml?query=branch:main\"\u003e\u003cimg\n                src=\"https://img.shields.io/github/actions/workflow/status/JP-Ellis/rust-skiplist/release-plz.yml?branch=main\u0026label=release\"\n                alt=\"Release Pipeline\"\u003e\u003c/a\u003e\n            \u003ca href=\"https://codecov.io/gh/JP-Ellis/rust-skiplist\"\u003e\u003cimg\n                src=\"https://codecov.io/gh/JP-Ellis/rust-skiplist/graph/badge.svg?branch=main\"\n                alt=\"Code Coverage\"\u003e\u003c/a\u003e\n        \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003ctd\u003eMeta\u003c/td\u003e\n        \u003ctd\u003e\n            \u003ca href=\"https://github.com/rust-lang/rust-clippy\"\u003e\u003cimg\n                src=\"https://img.shields.io/badge/linting-clippy-0097A7\"\n                alt=\"linting - Clippy\"\u003e\u003c/a\u003e\n            \u003ca href=\"https://github.com/rust-lang/rustfmt\"\u003e\u003cimg\n                src=\"https://img.shields.io/badge/style-rustfmt-0057B8\"\n                alt=\"style - rustfmt\"\u003e\u003c/a\u003e\n            \u003ca href=\"https://github.com/rust-lang/miri\"\u003e\u003cimg\n                src=\"https://img.shields.io/badge/testing-Miri-6A0DAD\"\n                alt=\"testing - Miri\"\u003e\u003c/a\u003e\n            \u003ca href=\"https://crates.io/crates/skiplist\"\u003e\u003cimg src=\"https://img.shields.io/crates/l/skiplist.svg\" alt=\"License\"\u003e\u003c/a\u003e\n        \u003c/td\u003e\n    \u003c/tr\u003e\n\u003c/table\u003e\u003c/div\u003e\n\u003c!-- markdownlint-enable no-inline-html --\u003e\n\nSkip list collections with $O(\\log n)$ average-case performance for access, insertion, and removal. Four variants cover the common use cases: positional sequences, sorted bags, sorted sets, and sorted maps, all with pluggable ordering via a `Comparator` trait.\n\n\u003e [!NOTE]\n\u003e\n\u003e **Version 1.0.0 is a complete rewrite.**\n\u003e\n\u003e The 1.0.0 release shares no code with the 0.x series. The internal architecture, public API, and crate structure have all changed. If you are upgrading from 0.x, treat this as a new dependency and review the documentation from scratch rather than diffing against the old API.\n\n## Adding to your project\n\n```toml\n[dependencies]\nskiplist = \"1\"\n```\n\nTo use the `PartialOrdComparator` (for types that implement `PartialOrd` but not `Ord`, such as `f64`), enable the `partial-ord` feature:\n\n```toml\n[dependencies]\nskiplist = { version = \"1\", features = [\"partial-ord\"] }\n```\n\n\u003e [!WARNING]\n\u003e\n\u003e `PartialOrdComparator` panics at runtime if a comparison returns `None` (e.g. when a `NaN` is inserted or looked up). For floating-point keys, prefer `FnComparator` with `f64::total_cmp`, which provides a true total order with no panics.\n\n## Basic usage\n\n```rust\nuse skiplist::{SkipList, OrderedSkipList, SkipSet, SkipMap};\n\n// Positional sequence - insertion order is preserved\nlet mut list: SkipList\u003ci32\u003e = SkipList::new();\nlist.push_back(10);\nlist.push_back(20);\nlist.insert(1, 15); // insert at index 1\nassert_eq!(list[1], 15);\n\n// Sorted bag - elements are always kept in order, duplicates allowed\nlet mut ordered: OrderedSkipList\u003ci32\u003e = OrderedSkipList::new();\nordered.insert(30);\nordered.insert(10);\nordered.insert(10); // duplicate is kept\nassert_eq!(ordered.len(), 3);\n\n// Sorted set - like OrderedSkipList but duplicates are rejected\nlet mut set: SkipSet\u003ci32\u003e = SkipSet::new();\nset.insert(3);\nset.insert(1);\nset.insert(1); // no-op: already present\nassert_eq!(set.len(), 2);\n\n// Sorted map - unique keys, sorted by key\nlet mut map: SkipMap\u003c\u0026str, i32\u003e = SkipMap::new();\nmap.insert(\"b\", 2);\nmap.insert(\"a\", 1);\nassert_eq!(map.get(\"a\"), Some(\u00261));\n```\n\n### Custom ordering\n\nOrdered collections accept any comparator via the `FnComparator` wrapper - no newtype required:\n\n```rust\nuse skiplist::{OrderedSkipList, comparator::FnComparator};\n\n// Sort strings by length, then lexicographically\nlet cmp = FnComparator(|a: \u0026str, b: \u0026str| {\n    a.len().cmp(\u0026b.len()).then(a.cmp(b))\n});\nlet mut list = OrderedSkipList::with_comparator(cmp);\nlist.insert(\"banana\");\nlist.insert(\"fig\");\nlist.insert(\"apple\");\n// Iteration order: \"fig\", \"apple\", \"banana\"\n```\n\n## Collections\n\n| Collection        | Ordering                 | Duplicates       | Docs                                                                            |\n| ----------------- | ------------------------ | ---------------- | ------------------------------------------------------------------------------- |\n| `SkipList`        | Insertion order          | Yes              | [docs.rs](https://docs.rs/skiplist/latest/skiplist/struct.SkipList.html)        |\n| `OrderedSkipList` | Sorted by comparator     | Yes              | [docs.rs](https://docs.rs/skiplist/latest/skiplist/struct.OrderedSkipList.html) |\n| `SkipSet`         | Sorted by comparator     | No               | [docs.rs](https://docs.rs/skiplist/latest/skiplist/struct.SkipSet.html)         |\n| `SkipMap`         | Sorted by key comparator | No (unique keys) | [docs.rs](https://docs.rs/skiplist/latest/skiplist/struct.SkipMap.html)         |\n\n**`SkipList`** stores elements in insertion order. It does not require elements to implement `Ord`. Use it when you need a positional sequence with cheap $O(\\log n)$ insertion and removal anywhere in the list, not just at the ends.\n\n**`OrderedSkipList`** always keeps elements in sorted order and tolerates duplicates. Unlike `BTreeSet`, inserting the same value twice places two adjacent entries in the list.\n\n**`SkipSet`** wraps `OrderedSkipList` and enforces uniqueness: inserting a value that already exists is a no-op. It mirrors the `BTreeSet` API.\n\n**`SkipMap`** stores unique key-value pairs sorted by key. Inserting a duplicate key replaces the existing value, identical to `BTreeMap` semantics.\n\nFull API documentation is on [docs.rs](https://docs.rs/skiplist/).\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjp-ellis%2Frust-skiplist","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjp-ellis%2Frust-skiplist","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjp-ellis%2Frust-skiplist/lists"}