github.com/egonelbre/exp@v0.0.0-20240430123955-ed1d3aa93911/sorts/rdxsort/uint64.go (about) 1 package rdxsort 2 3 func Uint64(arr, buf []uint64) { 4 if int64(len(arr)) >= int64(1<<32) { 5 panic("slice too large") 6 } 7 if len(arr) != len(buf) { 8 panic("len(arr) != len(buf)") 9 } 10 11 var count [8][256]uint32 12 for _, v := range arr { 13 count[0][byte(v>>(0*8))]++ 14 count[1][byte(v>>(1*8))]++ 15 count[2][byte(v>>(2*8))]++ 16 count[3][byte(v>>(3*8))]++ 17 count[4][byte(v>>(4*8))]++ 18 count[5][byte(v>>(5*8))]++ 19 count[6][byte(v>>(6*8))]++ 20 count[7][byte(v>>(7*8))]++ 21 } 22 23 var offset [8][256]uint32 24 for k := 1; k < 256; k++ { 25 offset[0][k] = offset[0][k-1] + count[0][k-1] 26 offset[1][k] = offset[1][k-1] + count[1][k-1] 27 offset[2][k] = offset[2][k-1] + count[2][k-1] 28 offset[3][k] = offset[3][k-1] + count[3][k-1] 29 offset[4][k] = offset[4][k-1] + count[4][k-1] 30 offset[5][k] = offset[5][k-1] + count[5][k-1] 31 offset[6][k] = offset[6][k-1] + count[6][k-1] 32 offset[7][k] = offset[7][k-1] + count[7][k-1] 33 } 34 35 var nonZero [8]byte 36 for k := range nonZero { 37 nz := byte(0) 38 for _, v := range count[k] { 39 if v != 0 { 40 nz++ 41 } 42 } 43 nonZero[k] = nz 44 } 45 46 swaps := 0 47 src, dst := arr, buf 48 for k := uint8(0); k < 8; k++ { 49 if nonZero[k] == 1 { 50 continue 51 } 52 swaps++ 53 54 off := &offset[k] 55 56 p := k * 8 57 for _, v := range src { 58 key := uint8(v >> p) 59 dst[off[key]] = v 60 off[key]++ 61 } 62 63 dst, src = src, dst 64 } 65 66 if swaps&1 == 1 { 67 copy(arr, src) 68 } 69 } 70 71 func Uint32(arr, buf []uint32) { 72 if int64(len(arr)) >= int64(1<<32) { 73 panic("slice too large") 74 } 75 if len(arr) != len(buf) { 76 panic("len(arr) != len(buf)") 77 } 78 79 var count [4][256]uint32 80 for _, v := range arr { 81 count[0][byte(v>>(0*8))]++ 82 count[1][byte(v>>(1*8))]++ 83 count[2][byte(v>>(2*8))]++ 84 count[3][byte(v>>(3*8))]++ 85 } 86 87 var offset [4][256]uint32 88 for k := 1; k < 256; k++ { 89 offset[0][k] = offset[0][k-1] + count[0][k-1] 90 offset[1][k] = offset[1][k-1] + count[1][k-1] 91 offset[2][k] = offset[2][k-1] + count[2][k-1] 92 offset[3][k] = offset[3][k-1] + count[3][k-1] 93 } 94 95 var nonZero [4]byte 96 for k := range nonZero { 97 nz := byte(0) 98 for _, v := range count[k] { 99 if v != 0 { 100 nz++ 101 } 102 } 103 nonZero[k] = nz 104 } 105 106 swaps := 0 107 src, dst := arr, buf 108 for k := uint8(0); k < 4; k++ { 109 if nonZero[k] == 1 { 110 continue 111 } 112 swaps++ 113 114 off := &offset[k] 115 p := k * 8 116 for _, v := range src { 117 key := uint8(v >> p) 118 dst[off[key]] = v 119 off[key]++ 120 } 121 122 dst, src = src, dst 123 } 124 125 if swaps&1 == 1 { 126 copy(arr, src) 127 } 128 }