vitess.io/vitess@v0.16.2/go/mysql/collations/internal/uca/collation.go (about) 1 /* 2 Copyright 2021 The Vitess Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package uca 18 19 import ( 20 "sync" 21 22 "vitess.io/vitess/go/mysql/collations/internal/charset" 23 ) 24 25 type Collation interface { 26 Charset() charset.Charset 27 Weights() (Weights, Layout) 28 WeightForSpace() uint16 29 WeightsEqual(left, right rune) bool 30 } 31 32 var _ Collation = (*Collation900)(nil) 33 34 type Collation900 struct { 35 table Weights 36 implicits func([]uint16, rune) 37 contract Contractor 38 param *parametricT 39 maxLevel int 40 iterpool *sync.Pool 41 } 42 43 func (c *Collation900) Charset() charset.Charset { 44 return charset.Charset_utf8mb4{} 45 } 46 47 func (c *Collation900) Weights() (Weights, Layout) { 48 return c.table, Layout_uca900{} 49 } 50 51 func (c *Collation900) Iterator(input []byte) WeightIterator { 52 iter := c.iterpool.Get().(WeightIterator) 53 iter.reset(input) 54 return iter 55 } 56 57 func (c *Collation900) WeightForSpace() uint16 { 58 ascii := *c.table[0] 59 return ascii[CodepointsPerPage+' '] 60 } 61 62 func (c *Collation900) WeightsEqual(left, right rune) bool { 63 if left == right { 64 return true 65 } 66 return equalWeights900(c.table, c.maxLevel, left, right) 67 } 68 69 func NewCollation(name string, weights Weights, weightPatches []Patch, reorder []Reorder, contract Contractor, upperCaseFirst bool, levels int) *Collation900 { 70 coll := &Collation900{ 71 table: ApplyTailoring(Layout_uca900{}, weights, weightPatches), 72 implicits: UnicodeImplicitWeights900, 73 contract: contract, 74 maxLevel: levels, 75 param: newParametricTailoring(reorder, upperCaseFirst), 76 iterpool: &sync.Pool{}, 77 } 78 79 switch { 80 case coll.param == nil && len(weightPatches) == 0 && coll.contract == nil: 81 coll.iterpool.New = func() any { 82 return &FastIterator900{iterator900: iterator900{Collation900: *coll}} 83 } 84 case name == "utf8mb4_ja_0900_as_cs_ks" || name == "utf8mb4_ja_0900_as_cs": 85 coll.iterpool.New = func() any { 86 return &jaIterator900{iterator900: iterator900{Collation900: *coll}} 87 } 88 case name == "utf8mb4_zh_0900_as_cs": 89 coll.implicits = unicodeImplicitChineseWeights 90 fallthrough 91 default: 92 coll.iterpool.New = func() any { 93 return &slowIterator900{iterator900: iterator900{Collation900: *coll}} 94 } 95 } 96 97 return coll 98 } 99 100 var _ Collation = (*CollationLegacy)(nil) 101 102 type CollationLegacy struct { 103 charset charset.Charset 104 table Weights 105 maxCodepoint rune 106 contract Contractor 107 iterpool *sync.Pool 108 } 109 110 func (c *CollationLegacy) Charset() charset.Charset { 111 return c.charset 112 } 113 114 func (c *CollationLegacy) Weights() (Weights, Layout) { 115 return c.table, Layout_uca_legacy{Max: c.maxCodepoint} 116 } 117 118 func (c *CollationLegacy) Iterator(input []byte) *WeightIteratorLegacy { 119 iter := c.iterpool.Get().(*WeightIteratorLegacy) 120 iter.reset(input) 121 return iter 122 } 123 124 func (c *CollationLegacy) WeightForSpace() uint16 { 125 ascii := *c.table[0] 126 stride := ascii[0] 127 return ascii[1+' '*stride] 128 } 129 130 func (c *CollationLegacy) WeightsEqual(left, right rune) bool { 131 if left == right { 132 return true 133 } 134 return equalWeightsLegacy(c.table, left, right) 135 } 136 137 func NewCollationLegacy(cs charset.Charset, weights Weights, weightPatches []Patch, contract Contractor, maxCodepoint rune) *CollationLegacy { 138 coll := &CollationLegacy{ 139 charset: cs, 140 table: ApplyTailoring(Layout_uca_legacy{}, weights, weightPatches), 141 maxCodepoint: maxCodepoint, 142 contract: contract, 143 iterpool: &sync.Pool{}, 144 } 145 146 coll.iterpool.New = func() any { 147 return &WeightIteratorLegacy{CollationLegacy: *coll} 148 } 149 150 return coll 151 }