Skip to content

Commit f1722e9

Browse files
committed
slices: simplify rotate code
The rotate-by-reverse code in fact does only 2 writes per entry, so it is fine and simpler. Change-Id: I5feea9698b5575f1f0ae9069cc1d074643529262 Reviewed-on: https://go-review.googlesource.com/c/go/+/562321 Reviewed-by: Ian Lance Taylor <[email protected]> Reviewed-by: Michael Knyszek <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent f27a57f commit f1722e9

File tree

1 file changed

+5
-49
lines changed

1 file changed

+5
-49
lines changed

src/slices/slices.go

Lines changed: 5 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -408,65 +408,21 @@ func Clip[S ~[]E, E any](s S) S {
408408
return s[:len(s):len(s)]
409409
}
410410

411-
// Rotation algorithm explanation:
412-
//
413-
// rotate left by 2
414-
// start with
415-
// 0123456789
416-
// split up like this
417-
// 01 234567 89
418-
// swap first 2 and last 2
419-
// 89 234567 01
420-
// join first parts
421-
// 89234567 01
422-
// recursively rotate first left part by 2
423-
// 23456789 01
424-
// join at the end
425-
// 2345678901
426-
//
427-
// rotate left by 8
428-
// start with
429-
// 0123456789
430-
// split up like this
431-
// 01 234567 89
432-
// swap first 2 and last 2
433-
// 89 234567 01
434-
// join last parts
435-
// 89 23456701
436-
// recursively rotate second part left by 6
437-
// 89 01234567
438-
// join at the end
439-
// 8901234567
440-
441411
// TODO: There are other rotate algorithms.
442-
// This algorithm has the desirable property that it moves each element exactly twice.
443-
// The triple-reverse algorithm is simpler and more cache friendly, but takes more writes.
412+
// This algorithm has the desirable property that it moves each element at most twice.
444413
// The follow-cycles algorithm can be 1-write but it is not very cache friendly.
445414

446-
// rotateLeft rotates b left by n spaces.
415+
// rotateLeft rotates s left by r spaces.
447416
// s_final[i] = s_orig[i+r], wrapping around.
448417
func rotateLeft[E any](s []E, r int) {
449-
for r != 0 && r != len(s) {
450-
if r*2 <= len(s) {
451-
swap(s[:r], s[len(s)-r:])
452-
s = s[:len(s)-r]
453-
} else {
454-
swap(s[:len(s)-r], s[r:])
455-
s, r = s[len(s)-r:], r*2-len(s)
456-
}
457-
}
418+
Reverse(s[:r])
419+
Reverse(s[r:])
420+
Reverse(s)
458421
}
459422
func rotateRight[E any](s []E, r int) {
460423
rotateLeft(s, len(s)-r)
461424
}
462425

463-
// swap swaps the contents of x and y. x and y must be equal length and disjoint.
464-
func swap[E any](x, y []E) {
465-
for i := 0; i < len(x); i++ {
466-
x[i], y[i] = y[i], x[i]
467-
}
468-
}
469-
470426
// overlaps reports whether the memory ranges a[0:len(a)] and b[0:len(b)] overlap.
471427
func overlaps[E any](a, b []E) bool {
472428
if len(a) == 0 || len(b) == 0 {

0 commit comments

Comments
 (0)