Skip to content

Commit

Permalink
Make most of Rope inlinable
Browse files Browse the repository at this point in the history
  • Loading branch information
lorentey committed Apr 10, 2023
1 parent 83bc546 commit 454c84b
Show file tree
Hide file tree
Showing 28 changed files with 624 additions and 311 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ extension _HashNode {
@usableFromInline
@frozen
internal struct Builder {
@usableFromInline typealias Element = _HashNode.Element
@usableFromInline internal typealias Element = _HashNode.Element

@usableFromInline
@frozen
Expand Down
35 changes: 30 additions & 5 deletions Sources/RopeModule/Rope/Basics/Rope+Builder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ extension Rope {
}

extension Rope {
@frozen // Not really! This module isn't ABI stable.
public struct Builder {
// ║ ║
// ║ ║ ║ ║
Expand All @@ -34,26 +35,31 @@ extension Rope {
// →prefixTrees→ ↑ ↑ ←suffixTrees←
// prefix suffix

private var _prefixTrees: [Rope] = []
private var _prefixLeaf: Rope._Node?
var _prefix: Rope._Item?
@usableFromInline internal var _prefixTrees: [Rope] = []
@usableFromInline internal var _prefixLeaf: Rope._Node?

@usableFromInline internal var _prefix: Rope._Item?

var _suffix: Rope._Item?
var _suffixTrees: [Rope] = []
@usableFromInline internal var _suffix: Rope._Item?
@usableFromInline internal var _suffixTrees: [Rope] = []

@inlinable
public init() {}

@inlinable
public var isPrefixEmpty: Bool {
if _prefix != nil { return false }
if let leaf = self._prefixLeaf, !leaf.isEmpty { return false }
return _prefixTrees.isEmpty
}

@inlinable
public var isSuffixEmpty: Bool {
if _suffix != nil { return false }
return _suffixTrees.isEmpty
}

@inlinable
public var prefixSummary: Summary {
var sum = Summary.zero
for sapling in _prefixTrees {
Expand All @@ -64,6 +70,7 @@ extension Rope {
return sum
}

@inlinable
public var suffixSummary: Summary {
var sum = Summary.zero
if let item = _suffix { sum.add(item.summary) }
Expand All @@ -73,6 +80,7 @@ extension Rope {
return sum
}

@inlinable
var _lastPrefixItem: Rope._Item {
get {
assert(!isPrefixEmpty)
Expand All @@ -92,6 +100,7 @@ extension Rope {
}
}

@inlinable
var _firstSuffixItem: Rope._Item {
get {
assert(!isSuffixEmpty)
Expand All @@ -108,6 +117,7 @@ extension Rope {
}
}

@inlinable
public func forEachElementInPrefix(
from position: Int,
in metric: some RopeMetric<Element>,
Expand Down Expand Up @@ -155,6 +165,7 @@ extension Rope {
return true
}

@inlinable
public mutating func mutatingForEachSuffix<R>(
_ body: (inout Element) -> R?
) -> R? {
Expand All @@ -170,10 +181,12 @@ extension Rope {
return nil
}

@inlinable
public mutating func insertBeforeTip(_ item: __owned Element) {
_insertBeforeTip(Rope._Item(item))
}

@inlinable
mutating func _insertBeforeTip(_ item: __owned Rope._Item) {
guard !item.isEmpty else { return }
guard var prefix = self._prefix._take() else {
Expand All @@ -189,6 +202,7 @@ extension Rope {
self._prefix = item
}

@inlinable
mutating func _appendNow(_ item: __owned Rope._Item) {
assert(self._prefix == nil)
assert(!item.isUndersized)
Expand All @@ -202,11 +216,13 @@ extension Rope {
_invariantCheck()
}

@inlinable
public mutating func insertBeforeTip(_ rope: __owned Rope) {
guard rope._root != nil else { return }
_insertBeforeTip(rope.root)
}

@inlinable
mutating func _insertBeforeTip(_ node: __owned Rope._Node) {
defer { _invariantCheck() }
var node = node
Expand Down Expand Up @@ -249,6 +265,7 @@ extension Rope {
_appendNow(node)
}

@inlinable
mutating func _appendNow(_ rope: __owned Rope._Node) {
assert(self._prefix == nil && self._prefixLeaf == nil)
var new = rope
Expand Down Expand Up @@ -287,10 +304,12 @@ extension Rope {
_prefixTrees.append(Rope(root: new))
}

@inlinable
public mutating func insertAfterTip(_ item: __owned Element) {
_insertAfterTip(_Item(item))
}

@inlinable
mutating func _insertAfterTip(_ item: __owned _Item) {
guard !item.isEmpty else { return }
if var suffixItem = self._suffix._take() {
Expand All @@ -306,16 +325,19 @@ extension Rope {
self._suffix = item
}

@inlinable
public mutating func insertAfterTip(_ rope: __owned Rope) {
assert(_suffix == nil)
assert(_suffixTrees.isEmpty || rope._height <= _suffixTrees.last!._height)
_suffixTrees.append(rope)
}

@inlinable
mutating func _insertAfterTip(_ rope: __owned Rope._Node) {
insertAfterTip(Rope(root: rope))
}

@inlinable
mutating func _insertBeforeTip(slots: Range<Int>, in node: __owned Rope._Node) {
assert(slots.lowerBound >= 0 && slots.upperBound <= node.childCount)
let c = slots.count
Expand All @@ -334,6 +356,7 @@ extension Rope {
_insertBeforeTip(copy)
}

@inlinable
mutating func _insertAfterTip(slots: Range<Int>, in node: __owned Rope._Node) {
assert(slots.lowerBound >= 0 && slots.upperBound <= node.childCount)
let c = slots.count
Expand All @@ -352,6 +375,7 @@ extension Rope {
_insertAfterTip(copy)
}

@inlinable
public mutating func finalize() -> Rope {
// Integrate prefix & suffix chunks.
if let suffixItem = self._suffix._take() {
Expand Down Expand Up @@ -390,6 +414,7 @@ extension Rope {
return rope
}

@inlinable
public func _invariantCheck() {
#if COLLECTIONS_INTERNAL_CHECKS
var h = UInt8.max
Expand Down
11 changes: 8 additions & 3 deletions Sources/RopeModule/Rope/Basics/Rope+Debugging.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,22 @@ import _CollectionsUtilities
#endif

extension Rope._UnmanagedLeaf: CustomStringConvertible {
var description: String {
@usableFromInline
internal var description: String {
_addressString(for: _ref.toOpaque())
}
}

extension Rope {
@inlinable
public var _nodeCount: Int {
_root?.nodeCount ?? 0
}
}

extension Rope._Node {
var nodeCount: Int {
@inlinable
internal var nodeCount: Int {
guard !isLeaf else { return 1 }
return readInner { $0.children.reduce(into: 1) { $0 += $1.nodeCount } }
}
Expand All @@ -47,7 +50,8 @@ extension Rope {
}

extension Rope._Node: CustomStringConvertible {
var description: String {
@usableFromInline
internal var description: String {
"""
\(height > 0 ? "Inner@\(height)" : "Leaf")(\
at: \(_addressString(for: object)), \
Expand All @@ -58,6 +62,7 @@ extension Rope._Node: CustomStringConvertible {
}

extension Rope._Node {
@usableFromInline
internal func dump(
heightLimit: Int = .max,
firstPrefix: String = "",
Expand Down
11 changes: 9 additions & 2 deletions Sources/RopeModule/Rope/Basics/Rope+Invariants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
//===----------------------------------------------------------------------===//

extension Rope {
@inlinable @inline(__always)
public func _invariantCheck() {
#if COLLECTIONS_INTERNAL_CHECKS
_root?.invariantCheck(depth: 0, height: root.height, recursive: true)
Expand All @@ -18,8 +19,9 @@ extension Rope {
}

extension Rope._Node {
func invariantCheck(depth: UInt8, height: UInt8, recursive: Bool = true) {
#if COLLECTIONS_INTERNAL_CHECKS
@usableFromInline
internal func invariantCheck(depth: UInt8, height: UInt8, recursive: Bool = true) {
precondition(height == self.height, "Mismatching rope height")
if isLeaf {
precondition(self.childCount <= Summary.maxNodeSize, "Oversized leaf")
Expand Down Expand Up @@ -58,6 +60,11 @@ extension Rope._Node {
child.invariantCheck(depth: depth + 1, height: height - 1, recursive: true)
}
}
#endif
}
#else
@inlinable @inline(__always)
internal func invariantCheck(depth: UInt8, height: UInt8, recursive: Bool = true) {
// Do nothing.
}
#endif
}
Loading

0 comments on commit 454c84b

Please sign in to comment.