Skip to content

Remove swift-collections dependency - #948

Merged
pblazej merged 13 commits into
livekit:mainfrom
dfed:patch-1
Mar 31, 2026
Merged

Remove swift-collections dependency#948
pblazej merged 13 commits into
livekit:mainfrom
dfed:patch-1

Conversation

@dfed

@dfed dfed commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Replace DequeModule and OrderedCollections imports with minimal internal implementations (Deque, OrderedDictionary, OrderedSet) in Sources/LiveKit/Support/DataStructures/
  • Remove swift-collections from Package.swift, Package@swift-6.0.swift, and LiveKitClient.podspec
  • Unblocks consumers from being pinned to old swift-collections versions due to library evolution mode / XCFramework compatibility constraints

Details

The actual API surface used was tiny — 3 types, ~14 call sites, all internal. The new implementations are ~180 lines total, matching the existing pattern of lightweight data structures in the repo (RingBuffer, MapTable, TTLDictionary).

Test plan

  • xcodebuild build -scheme LiveKit -destination 'platform=macOS' succeeds
  • xcodebuild test -scheme LiveKit -only-testing LiveKitCoreTests -destination 'platform=macOS' — all non-E2E tests pass (E2E tests require local server)
  • CI passes

🤖 Generated with Claude Code

Comment thread Package.swift Outdated
@hiroshihorie
hiroshihorie requested a review from pblazej March 17, 2026 10:28
@pblazej

pblazej commented Mar 17, 2026

Copy link
Copy Markdown
Contributor

Could you inspect the CI build errors? @dfed

Hint: the key is binary distribution (it was downgraded for a reason); the closest comment I could find was apple/swift-collections#546 (comment)

Haven't tested it tho

@pblazej

pblazej commented Mar 17, 2026

Copy link
Copy Markdown
Contributor

After a short test, I see 2 obstacles:

  • newer versions do not officially support Swift 5.x toolchain (that won't be an issue soon)
  • more importantly, they rely on experimental features and will break library evolution mode, which is crucial for building a xcframework on top of LK - this is a strict requirement for us

I'm happy to merge it once we resolve the latter.

@dfed

dfed commented Mar 17, 2026

Copy link
Copy Markdown
Contributor Author

Got it. @pblazej would y'all be interested in a PR that copy/pasted the existing implementation of Deque, OrderedDictionary, and OrderedSet from Swift Collections as internal types such that y'all can remove swift-collections as a dependency? Ideally depending on LiveKit wouldn't restrict adopting apps from using the latest libs from Apple. Happy to update this PR

@dfed
dfed marked this pull request as draft March 17, 2026 17:56
@dfed dfed changed the title Update swift-collections package version range Remove swift-collections dependency Mar 17, 2026
Comment thread Sources/LiveKit/Support/DataStructures/Deque.swift
Comment thread Sources/LiveKit/Support/DataStructures/Deque.swift
Comment thread Sources/LiveKit/Support/DataStructures/OrderedDictionary.swift
Comment thread Sources/LiveKit/Support/DataStructures/OrderedSet.swift
@pblazej

pblazej commented Mar 18, 2026

Copy link
Copy Markdown
Contributor

@dfed thank you for going the extra mile here!

The problem with binary distribution is pretty common across Apple libs e.g. apple/swift-nio#2897 and already happened to use with swift-logging that we dropped vs bare OSLog.

I think porting the minimal API is better than carrying "a big part of the lib" under Apache as our usage is pretty narrow, the impact of future optimizations (leveraging ownership etc.) is probably negligible.

2 things:

  • please rebase on main to include Package@swift-6.2
  • you can run https://github.com/apple/swift-collections-benchmark against them to see if there are any bottlenecks vs the reference impl
    • or I'll do it as a part of review - I'm talking mostly about DataChannelPair <- Deque

@pblazej

pblazej commented Mar 18, 2026

Copy link
Copy Markdown
Contributor
bench-deque

collection-bench.zip

Attaching my results - nothing to worry about 🎉

The rest is micro-optimization like:

  // Before (integer division)
  let tail = (head + count_) % buffer.count

  // After (bitwise AND — same result when buffer.count is power of 2)
  let tail = (head + count_) & (buffer.count - 1)

Comment thread Sources/LiveKit/Support/DataStructures/Deque.swift Outdated
Comment thread Sources/LiveKit/Support/DataStructures/OrderedDictionary.swift
Comment thread Sources/LiveKit/Support/DataStructures/Deque.swift Outdated
Comment thread Sources/LiveKit/Support/DataStructures/Deque.swift Outdated
Comment thread Sources/LiveKit/Support/DataStructures/Deque.swift
@pblazej
pblazej marked this pull request as ready for review March 26, 2026 08:02
@pblazej

pblazej commented Mar 26, 2026

Copy link
Copy Markdown
Contributor

@dfed can we finalize this PR? I've got some reports on other consumers blocked by that, don't want to duplicate your great work.

dfed and others added 8 commits March 28, 2026 13:34
Replace DequeModule and OrderedCollections with minimal internal
implementations covering only the APIs actually used (~14 call sites).
This unblocks consumers from being pinned to old swift-collections
versions due to library evolution mode compatibility constraints.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Array.removeFirst() is O(n), making the processSendQueue drain
loop O(n²). Switch to a circular buffer backed by [Element?] with
head pointer tracking for O(1) amortized append and removeFirst.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use bitwise AND instead of modulo in Deque (power-of-two optimization)
- Change fatalError to preconditionFailure to match Array behavior
- Handle duplicate keys in OrderedDictionary init(uniqueKeysWithValues:)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@dfed

dfed commented Mar 28, 2026

Copy link
Copy Markdown
Contributor Author

Rebased on main (picks up Package@swift-6.2.swift), removed swift-collections from that file in d5da9f1, and applied all your suggestions in 6f144a8. Should be ready for another look!

dfed and others added 4 commits March 28, 2026 14:45
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

@pblazej pblazej left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉

@pblazej
pblazej merged commit 4933952 into livekit:main Mar 31, 2026
44 of 46 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants