proposal: Add ordered_list (Order-Statistic Tree) to container Package in Go
Closed this issue · 1 comments
Proposal Details
Proposal: Add ordered_list (Order-Statistic Tree) to container Package in Go
Author: Mostafa Khairy (proposal draft)
Goal: Add an ordered_list implementation (Order-Statistic Tree — OST) to the standard container family to provide an efficient, well-tested data structure that supports indexed access and order statistics in O(log n) time.
🧩 Problem Statement / Motivation
The Go container package currently includes heap, list, and ring.
However, none of these provide:
- Fast indexed access by rank (e.g., “get the k-th smallest element”)
- Fast computation of the rank of an existing key
- Efficient ordered splits/joins
- Stable
O(log n)insertion and deletion while maintaining sorted order
Developers often need structures that maintain sorted sequences with fast selection and ranking — for example:
- Maintaining a sorted leaderboard
- Implementing paginated ordered sets
- Querying median or percentile values dynamically
- Supporting algorithms requiring the k-th element efficiently
An Order-Statistic Tree (a balanced BST like a Red-Black Tree or AVL tree, augmented with subtree sizes) naturally supports Select(k) and Rank(key) in O(log n) time.
Adding a canonical, well-documented implementation to Go’s standard library would reduce fragmentation and improve reliability.
🎯 Design Goals
- Performance:
O(log n)for insert, delete, select, and rank. - Simplicity: A minimal, idiomatic API consistent with other
containertypes. - Type Safety: Support for generics (Go 1.18+).
- Deterministic Iteration: Ordered traversal from smallest to largest.
- Non-Concurrent by Default: No internal synchronization.
- Compact API Surface: Only essential methods.
- Well Tested and Benchmarked.
📦 Proposed Package Name
- Option A (Recommended):
container/ordered - Option B:
container/ost
This proposal uses container/ordered in examples.
🧱 Proposed API
package ordered
// OrderedList[T] is an order-statistic tree of values of type T.
type OrderedList[T any] struct {}
// Less defines the comparator function used to maintain order.
type Less[T any] func(a, b T) bool
// New creates an empty OrderedList with the specified comparator.
func New[T any](less Less[T]) *OrderedList[T]
// Insert adds a value to the list (duplicates allowed).
func (ol *OrderedList[T]) Insert(value T)
// RemoveOne deletes one instance of value if it exists.
func (ol *OrderedList[T]) RemoveOne(value T) bool
// RemoveAt removes the element at index i and returns it.
func (ol *OrderedList[T]) RemoveAt(i int) T
// Get returns the element at index i.
func (ol *OrderedList[T]) Get(i int) T
// Rank returns the number of elements strictly less than value.
func (ol *OrderedList[T]) Rank(value T) int
// Len returns the total number of elements.
func (ol *OrderedList[T]) Len() int
// Min and Max return the smallest and largest elements respectively.
func (ol *OrderedList[T]) Min() T
func (ol *OrderedList[T]) Max() T
// Iterate traverses elements in ascending order.
func (ol *OrderedList[T]) Iterate(fn func(i int, v T) bool)
// Clear removes all elements.
func (ol *OrderedList[T]) Clear()see https://go.dev/doc/faq#x_in_std
right now there's no evidence that there's a strong need for this across the ecosystem.