ce = uint32(weights[0]<<maxSecondaryCompactBits + weights[1])
ce |= isPrimary
} else {
- d := weights[1] - defaultSecondary
+ d := weights[1] - defaultSecondary + 4
if d >= 1<<maxSecondaryDiffBits || d < 0 {
return 0, fmt.Errorf("makeCE: secondary weight diff out of bounds: %x < 0 || %x > %x", d, d, 1<<maxSecondaryDiffBits)
}
// nextWeight computes the first possible collation weights following elems
// for the given level.
func nextWeight(level collate.Level, elems [][]int) [][]int {
- nce := make([][]int, len(elems))
- copy(nce, elems)
-
- if level != collate.Identity {
- nce[0] = make([]int, len(elems[0]))
- copy(nce[0], elems[0])
- nce[0][level]++
- if level < collate.Secondary {
- nce[0][collate.Secondary] = defaultSecondary
+ if level == collate.Identity {
+ next := make([][]int, len(elems))
+ copy(next, elems)
+ return next
+ }
+ next := [][]int{make([]int, len(elems[0]))}
+ copy(next[0], elems[0])
+ next[0][level]++
+ if level < collate.Secondary {
+ next[0][collate.Secondary] = defaultSecondary
+ }
+ if level < collate.Tertiary {
+ next[0][collate.Tertiary] = defaultTertiary
+ }
+ // Filter entries that cannot influence ordering.
+ for _, ce := range elems[1:] {
+ skip := true
+ for i := collate.Primary; i < level; i++ {
+ skip = skip && ce[i] == 0
}
- if level < collate.Tertiary {
- nce[0][collate.Tertiary] = defaultTertiary
+ if !skip {
+ next = append(next, ce)
}
}
- return nce
+ return next
}
func nextVal(elems [][]int, i int, level collate.Level) (index, value int) {
var ceTests = []ceTest{
{normalCE, []int{0, 0, 0}, 0x80000000},
{normalCE, []int{0, 0x28, 3}, 0x80002803},
- {normalCE, []int{100, defaultSecondary, 3}, 0x0000C803},
+ {normalCE, []int{100, defaultSecondary, 3}, 0x0000C883},
// non-ignorable primary with non-default secondary
{normalCE, []int{100, 0x28, defaultTertiary}, 0x40006428},
- {normalCE, []int{100, defaultSecondary + 8, 3}, 0x0000C903},
+ {normalCE, []int{100, defaultSecondary + 8, 3}, 0x0000C983},
{normalCE, []int{100, 0, 3}, 0xFFFF}, // non-ignorable primary with non-supported secondary
{normalCE, []int{100, 1, 3}, 0xFFFF},
{normalCE, []int{1 << maxPrimaryBits, defaultSecondary, 0}, 0xFFFF},
},
}
-var extra = []int{200, 32, 8, 0}
+var extra = [][]int{{200, 32, 8, 0}, {0, 32, 8, 0}, {0, 0, 8, 0}, {0, 0, 0, 0}}
func TestNextWeight(t *testing.T) {
for i, tt := range nextWeightTests {
- test := func(tt weightsTest, a, gold [][]int) {
+ test := func(l collate.Level, tt weightsTest, a, gold [][]int) {
res := nextWeight(tt.level, a)
if !equalCEArrays(gold, res) {
- t.Errorf("%d: expected weights %d; found %d", i, tt.b, res)
+ t.Errorf("%d:%d: expected weights %d; found %d", i, l, gold, res)
+ }
+ }
+ test(-1, tt, tt.a, tt.b)
+ for l := collate.Primary; l <= collate.Tertiary; l++ {
+ if tt.level <= l {
+ test(l, tt, append(tt.a, extra[l]), tt.b)
+ } else {
+ test(l, tt, append(tt.a, extra[l]), append(tt.b, extra[l]))
}
}
- test(tt, tt.a, tt.b)
- test(tt, append(tt.a, extra), append(tt.b, extra))
}
}
0,
},
{
- [][]int{{100, 20, 5, 0}, extra},
+ [][]int{{100, 20, 5, 0}, extra[0]},
[][]int{{100, 20, 5, 1}},
collate.Primary,
1,
}
}
test(tt, tt.a, tt.b)
- test(tt, append(tt.a, extra), append(tt.b, extra))
+ test(tt, append(tt.a, extra[0]), append(tt.b, extra[0]))
}
}