Skip to content

Commit 8b076ee

Browse files
committed
adt-tower W3.1: .Small ring-column coverage probe
Add a compile+run probe proving a Memory.Small<64>-leaf ring column typechecks and behaves through the [DS-029]-generalized ops — construction (form-2), enqueue past the inline budget (form-2, exercising the inline→heap spill), and drain (form-1 popFront + consuming .drain + static seam ops). This is the exact column W3.2's Queue<E>.Small<n> / deque .Small doors will consume. Adds swift-memory-small-primitives as a test-only dependency (Memory.Small is the growable leaf; mirror already configured). 104 tests/29 suites green (baseline 101/28 + 3 probe tests).
1 parent 9f4a2fc commit 8b076ee

2 files changed

Lines changed: 89 additions & 0 deletions

File tree

Package.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ let package = Package(
3333
.package(url: "https://github.com/swift-primitives/swift-sequence-primitives.git", branch: "main"),
3434
.package(url: "https://github.com/swift-primitives/swift-iterator-primitives.git", branch: "main"),
3535
.package(url: "https://github.com/swift-primitives/swift-memory-heap-primitives.git", branch: "main"),
36+
// W3.1 .Small compile-probe dependency (test-only): the Memory.Small growable leaf.
37+
.package(url: "https://github.com/swift-primitives/swift-memory-small-primitives.git", branch: "main"),
3638
],
3739
targets: [
3840

@@ -149,6 +151,7 @@ let package = Package(
149151
.product(name: "Buffer Primitives Test Support", package: "swift-buffer-primitives"),
150152
.product(name: "Storage Contiguous Primitives", package: "swift-storage-primitives"),
151153
.product(name: "Memory Heap Primitives", package: "swift-memory-heap-primitives"),
154+
.product(name: "Memory Small Primitives", package: "swift-memory-small-primitives"),
152155
.product(name: "Memory Allocator Primitive", package: "swift-memory-allocation-primitives"),
153156
.product(name: "Storage Protocol Primitives", package: "swift-storage-primitives"),
154157
]
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import Buffer_Ring_Primitives
2+
import Memory_Allocator_Primitive
3+
import Memory_Small_Primitives
4+
import Storage_Contiguous_Primitives
5+
import Testing
6+
7+
// MARK: - W3.1 `.Small` compile-coverage probe
8+
//
9+
// Verifies a `Memory.Small<n>`-leaf ring column typechecks AND runs through the
10+
// [DS-029]-generalized ops: construction (FORM-2), enqueue past the inline budget
11+
// (FORM-2 — grows via `S.create`, re-running the inline→heap spill decision), and
12+
// drain (FORM-1 — `popFront` / the consuming `.drain` over the ledgered seam).
13+
//
14+
// This is the exact column W3.2's `Queue<E>.Small<n>` / `Queue<E>.DoubleEnded.Small<n>`
15+
// front doors will consume: the door is a constrained alias; this probe proves the
16+
// generalized ops resolve and behave on the `Memory.Small` growable leaf. Memory.Small
17+
// is `Memory.Growable`, so form-2 applies; a `Memory.Inline` leaf would (correctly)
18+
// not satisfy the growth-op fence.
19+
20+
@Suite("Buffer.Ring .Small coverage")
21+
struct RingSmallCoverageTests {
22+
// `Memory.Small`'s n is a BYTE budget: 64 bytes ≈ 8 `Int`s inline before spilling.
23+
typealias SmallColumn = Storage<Memory.Allocator<Memory.Small<64>>>.Contiguous<Int>
24+
}
25+
26+
extension RingSmallCoverageTests {
27+
28+
@Test
29+
func `construct + enqueue (form-2, inline→heap spill) + drain via popFront (form-1)`() {
30+
// FORM-2 construction on the growable Small leaf.
31+
var ring = Buffer<SmallColumn>.Ring(minimumCapacity: 4)
32+
33+
// FORM-2 enqueue: push 16 `Int`s (128 bytes) past the 64-byte inline budget,
34+
// forcing at least one inline→heap spill during growth.
35+
for value in 1 ... 16 {
36+
ring.pushBack(value)
37+
}
38+
#expect(ring.count == 16)
39+
40+
// FORM-1 drain via popFront over the ledgered seam — FIFO order preserved
41+
// across the spill boundary.
42+
var expected = 1
43+
while ring.count > .zero {
44+
let element = ring.popFront()
45+
#expect(element == expected)
46+
expected += 1
47+
}
48+
#expect(expected == 17)
49+
}
50+
51+
@Test
52+
func `consuming .drain (form-1) over Memory.Small<64>`() {
53+
var ring = Buffer<SmallColumn>.Ring(minimumCapacity: 2)
54+
ring.pushBack(100)
55+
ring.pushBack(200)
56+
ring.pushBack(300)
57+
#expect(ring.count == 3)
58+
59+
// FORM-1 consuming drain — the generic `Sequence.Drain` surface the door reuses.
60+
var seen: [Int] = []
61+
ring.drain { seen.append($0) }
62+
#expect(seen == [100, 200, 300])
63+
#expect(ring.count == .zero)
64+
}
65+
66+
@Test
67+
func `static seam ops (form-1) over a Memory.Small<64> substrate`() {
68+
let capacity: Index<Int>.Count = 8
69+
var header = Buffer<SmallColumn>.Ring.Header(capacity: capacity)
70+
var storage = SmallColumn.create(minimumCapacity: capacity)
71+
72+
// FORM-1 static element ops resolve on the Small substrate (same seam as heap).
73+
Buffer<SmallColumn>.Ring.pushBack(1, header: &header, storage: &storage)
74+
Buffer<SmallColumn>.Ring.pushBack(2, header: &header, storage: &storage)
75+
#expect(header.count == 2)
76+
77+
let first = Buffer<SmallColumn>.Ring.popFront(header: &header, storage: &storage)
78+
#expect(first == 1)
79+
80+
Buffer<SmallColumn>.Ring.deinitializeAll(header: &header, storage: &storage)
81+
let headerIsEmpty = header.isEmpty
82+
#expect(headerIsEmpty)
83+
84+
storage.initialization = .empty
85+
}
86+
}

0 commit comments

Comments
 (0)