Skip to content

Commit 45dcbbd

Browse files
[Chunked] Code review adjustments
1 parent 05df988 commit 45dcbbd

File tree

1 file changed

+47
-44
lines changed

1 file changed

+47
-44
lines changed

Sources/Algorithms/Chunked.swift

Lines changed: 47 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ public struct ChunkedByCount<Base: Collection> {
271271
internal let chunkCount: Int
272272

273273
@usableFromInline
274-
internal var computedStartIndex: Index
274+
internal var computedStartEnd: Base.Index
275275

276276
/// Creates a view instance that presents the elements of `base`
277277
/// in `SubSequence` chunks of the given count.
@@ -284,13 +284,10 @@ public struct ChunkedByCount<Base: Collection> {
284284

285285
// Compute the start index upfront in order to make
286286
// start index a O(1) lookup.
287-
let baseEnd = _base.index(
287+
self.computedStartEnd = _base.index(
288288
_base.startIndex, offsetBy: _chunkCount,
289289
limitedBy: _base.endIndex
290290
) ?? _base.endIndex
291-
292-
self.computedStartIndex =
293-
Index(_baseRange: _base.startIndex..<baseEnd)
294291
}
295292
}
296293

@@ -307,7 +304,9 @@ extension ChunkedByCount: Collection {
307304

308305
/// - Complexity: O(1)
309306
@inlinable
310-
public var startIndex: Index { computedStartIndex }
307+
public var startIndex: Index {
308+
Index(_baseRange: base.startIndex..<computedStartEnd)
309+
}
311310
@inlinable
312311
public var endIndex: Index {
313312
Index(_baseRange: base.endIndex..<base.endIndex)
@@ -331,6 +330,12 @@ extension ChunkedByCount: Collection {
331330
}
332331

333332
extension ChunkedByCount.Index: Comparable {
333+
@inlinable
334+
public static func == (lhs: ChunkedByCount.Index,
335+
rhs: ChunkedByCount.Index) -> Bool {
336+
lhs.baseRange.lowerBound == rhs.baseRange.lowerBound
337+
}
338+
334339
@inlinable
335340
public static func < (lhs: ChunkedByCount.Index,
336341
rhs: ChunkedByCount.Index) -> Bool {
@@ -359,6 +364,25 @@ where Base: RandomAccessCollection {
359364
) ?? base.startIndex
360365
return Index(_baseRange: baseIdx..<i.baseRange.lowerBound)
361366
}
367+
}
368+
369+
extension ChunkedByCount {
370+
@inlinable
371+
public func distance(from start: Index, to end: Index) -> Int {
372+
let distance =
373+
base.distance(from: start.baseRange.lowerBound,
374+
to: end.baseRange.lowerBound)
375+
let (quotient, remainder) =
376+
distance.quotientAndRemainder(dividingBy: chunkCount)
377+
return quotient + remainder.signum()
378+
}
379+
380+
@inlinable
381+
public var count: Int {
382+
let (quotient, remainder) =
383+
base.count.quotientAndRemainder(dividingBy: chunkCount)
384+
return quotient + remainder.signum()
385+
}
362386

363387
@inlinable
364388
public func index(
@@ -391,72 +415,51 @@ where Base: RandomAccessCollection {
391415

392416
@usableFromInline
393417
internal func offsetForward(_ i: Index, offsetBy distance: Int) -> Index {
418+
assert(distance > 0)
394419
return makeOffsetIndex(
395-
from: i, baseBound: base.endIndex, distance: distance
420+
from: i, baseBound: base.endIndex, baseDistance: distance * chunkCount
396421
)
397422
}
398423

399424
@usableFromInline
400425
internal func offsetBackward(_ i: Index, offsetBy distance: Int) -> Index {
401-
var idx = i
402-
var distance = distance
403-
// If we know that the last chunk is the only one that can possible
404-
// have a variadic count. So in order to simplify and avoid another
405-
// calculation of offsets(that is already done at `index(before:)`)
406-
// we just move one position already so the index can be calculated
407-
// since all remaining chunks have the same size.
426+
assert(distance < 0)
408427
if i.baseRange.lowerBound == base.endIndex {
409-
formIndex(before: &idx)
410-
distance += 1
411-
// If the offset was simply one, we are done.
412-
guard distance != 0 else {
413-
return idx
428+
let remainder = base.count%chunkCount
429+
// We have to take it into account when calculating offsets.
430+
if remainder != 0 {
431+
// Distance "minus" one(at this point distance is negative) because we
432+
// need to adjust for the last position that have a variadic(remainder)
433+
// number of elements.
434+
let baseDistance = ((distance + 1) * chunkCount) - remainder
435+
return makeOffsetIndex(
436+
from: i, baseBound: base.startIndex, baseDistance: baseDistance
437+
)
414438
}
415439
}
416-
417440
return makeOffsetIndex(
418-
from: idx, baseBound: base.startIndex, distance: distance
441+
from: i, baseBound: base.startIndex, baseDistance: distance * chunkCount
419442
)
420443
}
421444

422445
// Helper to compute index(offsetBy:) index.
423446
@inline(__always)
424447
private func makeOffsetIndex(
425-
from i: Index, baseBound: Base.Index, distance: Int
448+
from i: Index, baseBound: Base.Index, baseDistance: Int
426449
) -> Index {
427450
let baseStartIdx = base.index(
428-
i.baseRange.lowerBound, offsetBy: distance * chunkCount,
451+
i.baseRange.lowerBound, offsetBy: baseDistance,
429452
limitedBy: baseBound
430453
) ?? baseBound
431454

432455
let baseEndIdx = base.index(
433-
i.baseRange.lowerBound, offsetBy: (distance + 1) * chunkCount,
434-
limitedBy: base.endIndex
456+
baseStartIdx, offsetBy: chunkCount, limitedBy: base.endIndex
435457
) ?? base.endIndex
436458

437459
return Index(_baseRange: baseStartIdx..<baseEndIdx)
438460
}
439461
}
440462

441-
extension ChunkedByCount {
442-
@inlinable
443-
public func distance(from start: Index, to end: Index) -> Int {
444-
let distance =
445-
base.distance(from: start.baseRange.lowerBound,
446-
to: end.baseRange.lowerBound)
447-
let (quotient, remainder) =
448-
distance.quotientAndRemainder(dividingBy: chunkCount)
449-
return quotient + remainder.signum()
450-
}
451-
452-
@inlinable
453-
public var count: Int {
454-
let (quotient, remainder) =
455-
base.count.quotientAndRemainder(dividingBy: chunkCount)
456-
return quotient + remainder.signum()
457-
}
458-
}
459-
460463
extension Collection {
461464
/// Returns a `ChunkedCollection<Self>` view presenting the elements
462465
/// in chunks with count of the given count parameter.

0 commit comments

Comments
 (0)