Skip to content

Dynamically stores additive values and get arbitrary sub-range sums in O(log(n)) time.

License

Notifications You must be signed in to change notification settings

eonil/swift-segment-query

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SegmentQuery

Eonil, 2019.

Build Status

Dynamically stores additive values and get arbitrary sub-range sums in O(log(n)) time.

This is an implementation of something called "segment-tree" or "interval-tree". You insert/remove lengths of consecutive segments and query positions on it. I'm not sure which one is correct name.

How to Use

Add dependency.

.package(url: "https://github.com/eonil/swift-segment-query", .branch("master")),

And use.

import SegmentQuery

var x = SegmentQuery<Int>()

/// Append segment lengths.
x.append(contentsOf: [111,222,333])

/// Get subrange sum.
let s = x[1..<3].sum
assert(s == 222+333)

/// Get start/end offsets of a segment 1.
let a = x[..<1].sum
let b = x[...1].sum
let c = a..<b

/// Get index of segment and in-segment-offset from an offset.
let (a,b) = x.location(at: 230)
assert(a == 1)
assert(b == 8)

Requirements

  • Swift 5.x.
  • Swift Package Manager.

Complexity

  • O(log(n)) for element query/insert/update/remove and sub-sum query.

Performance

I couldn't find other segment query library written in Swift for comparison. Instead, I performed insert/remove performance comparison with well-known B-Tree library written by Lőrentey. This is one-by-one random Int number insert/remove at random location on 64-bit macOS,

With list of 128K values,

  • 4x faster than Swift.Array.
  • Very close speed to BTree.List.

With list of 1 million values,

  • 4x faster than BTree.List.

Run SegmentQueryBenchmark to get numbers on your machine.

Implementation

  • B-Tree based with no key stored.
  • Only values are stored.
  • Values are stored only on leafs.
  • Buffer sizes are optimized for ordered list behavior with dynamic automatic sum.

Missing Features

  • Balancing after remove. (Now only insertion is balanced by B-Tree insertion algorithm)
  • Bulk insert/remove implementation.
  • Sequential element iteration in O(n) time. Now it's O(n log n).
  • Sub-sum indexing in each node. We can store sub-sum for each branch/leaf node children to perform binary search to get an item. There is a trade-off, but I didn't try due to lack of time.

Credit & License

Copyright(C) Eonil 2019. All rights reserved. Using of this code is licensed under "MIT License".

About

Dynamically stores additive values and get arbitrary sub-range sums in O(log(n)) time.

Topics

Resources

License

Stars

Watchers

Forks

Packages