github.com/balzaczyy/golucene@v0.0.0-20151210033525-d0be9ee89713/core/util/packed/bulkop.go (about) 1 package packed 2 3 import () 4 5 // util/packed/BulkOperationPacked.java 6 7 // Non-specialized BulkOperation for Packed format 8 type BulkOperationPacked struct { 9 *BulkOperationImpl 10 bitsPerValue int 11 longBlockCount int 12 longValueCount int 13 byteBlockCount int 14 byteValueCount int 15 mask int64 16 intMask int 17 } 18 19 func newBulkOperationPacked(bitsPerValue uint32) *BulkOperationPacked { 20 self := &BulkOperationPacked{} 21 self.bitsPerValue = int(bitsPerValue) 22 assert(bitsPerValue > 0 && bitsPerValue <= 64) 23 blocks := uint32(bitsPerValue) 24 for (blocks & 1) == 0 { 25 blocks = (blocks >> 1) 26 } 27 self.longBlockCount = int(blocks) 28 self.longValueCount = 64 * self.longBlockCount / int(bitsPerValue) 29 byteBlockCount := 8 * self.longBlockCount 30 byteValueCount := self.longValueCount 31 for (byteBlockCount&1) == 0 && (byteValueCount&1) == 0 { 32 byteBlockCount = (byteBlockCount >> 1) 33 byteValueCount = (byteValueCount >> 1) 34 } 35 self.byteBlockCount = byteBlockCount 36 self.byteValueCount = byteValueCount 37 if bitsPerValue == 64 { 38 self.mask = ^int64(0) 39 } else { 40 self.mask = (int64(1) << bitsPerValue) - 1 41 } 42 self.intMask = int(self.mask) 43 assert(self.longValueCount*int(bitsPerValue) == 64*self.longBlockCount) 44 self.BulkOperationImpl = newBulkOperationImpl(self) 45 return self 46 } 47 48 func (p *BulkOperationPacked) LongBlockCount() int { 49 return p.longBlockCount 50 } 51 52 func (p *BulkOperationPacked) LongValueCount() int { 53 return p.longValueCount 54 } 55 56 func (p *BulkOperationPacked) ByteBlockCount() int { 57 return p.byteBlockCount 58 } 59 60 func (p *BulkOperationPacked) ByteValueCount() int { 61 return p.byteValueCount 62 } 63 64 func (p *BulkOperationPacked) decodeLongToLong(blocks, values []int64, iterations int) { 65 blocksOff, valuesOff := 0, 0 66 bitsLeft := 64 67 for i := 0; i < p.longValueCount*iterations; i++ { 68 bitsLeft -= p.bitsPerValue 69 if bitsLeft < 0 { 70 values[valuesOff] = 71 ((blocks[blocksOff] & ((int64(1) << uint(p.bitsPerValue+bitsLeft)) - 1)) << uint(-bitsLeft)) | 72 int64(uint64(blocks[blocksOff+1])>>uint(64+bitsLeft)) 73 valuesOff++ 74 blocksOff++ 75 bitsLeft += 64 76 } else { 77 values[valuesOff] = int64(uint64(blocks[blocksOff])>>uint(bitsLeft)) & p.mask 78 valuesOff++ 79 } 80 } 81 } 82 83 func (p *BulkOperationPacked) decodeByteToLong(blocks []byte, values []int64, iterations int) { 84 panic("niy") 85 } 86 87 func (p *BulkOperationPacked) encodeLongToLong(values, blocks []int64, iterations int) { 88 var nextBlock int64 = 0 89 var bitsLeft int = 64 90 valuesOffset, blocksOffset := 0, 0 91 for i, limit := 0, p.longValueCount*iterations; i < limit; i++ { 92 bitsLeft -= p.bitsPerValue 93 switch { 94 case bitsLeft > 0: 95 nextBlock |= (values[valuesOffset] << uint(bitsLeft)) 96 valuesOffset++ 97 case bitsLeft == 0: 98 nextBlock |= values[valuesOffset] 99 valuesOffset++ 100 blocks[blocksOffset] = nextBlock 101 blocksOffset++ 102 nextBlock = 0 103 bitsLeft = 64 104 default: // bitsLeft < 0 105 nextBlock |= int64(uint64(values[valuesOffset]) >> uint(-bitsLeft)) 106 blocks[blocksOffset] = nextBlock 107 blocksOffset++ 108 nextBlock = (values[valuesOffset] & ((1 << uint(-bitsLeft)) - 1) << uint(64+bitsLeft)) 109 valuesOffset++ 110 bitsLeft += 64 111 } 112 } 113 } 114 115 func (p *BulkOperationPacked) encodeLongToByte(values []int64, blocks []byte, iterations int) { 116 var nextBlock int = 0 117 var bitsLeft int = 8 118 valuesOffset, blocksOffset := 0, 0 119 for i, limit := 0, p.byteValueCount*iterations; i < limit; i++ { 120 v := values[valuesOffset] 121 valuesOffset++ 122 assert(UnsignedBitsRequired(v) <= p.bitsPerValue) 123 if p.bitsPerValue < bitsLeft { // just buffer 124 nextBlock |= int(v << uint(bitsLeft-p.bitsPerValue)) 125 bitsLeft -= p.bitsPerValue 126 } else { // flush as many blocks as possible 127 bits := uint(p.bitsPerValue - bitsLeft) 128 blocks[blocksOffset] = byte(nextBlock | int(uint64(v)>>bits)) 129 blocksOffset++ 130 for bits >= 8 { 131 bits -= 8 132 blocks[blocksOffset] = byte(uint64(v) >> bits) 133 blocksOffset++ 134 } 135 // then buffer 136 bitsLeft = int(8 - bits) 137 nextBlock = int((v & ((1 << bits) - 1)) << uint(bitsLeft)) 138 } 139 } 140 assert(bitsLeft == 8) 141 } 142 143 func (p *BulkOperationPacked) EncodeIntToByte(values []int, blocks []byte, iterations int) { 144 valuesOff, blocksOff := 0, 0 145 nextBlock, bitsLeft := 0, 8 146 for i := 0; i < p.byteValueCount*iterations; i++ { 147 v := values[valuesOff] 148 valuesOff++ 149 assert(BitsRequired(int64(v)) <= p.bitsPerValue) 150 if p.bitsPerValue < bitsLeft { 151 // just buffer 152 nextBlock |= (v << uint(bitsLeft-p.bitsPerValue)) 153 bitsLeft -= p.bitsPerValue 154 } else { 155 // flush as many blocks as possible 156 bits := p.bitsPerValue - bitsLeft 157 blocks[blocksOff] = byte(nextBlock | int(uint(v)>>uint(bits))) 158 blocksOff++ 159 for bits >= 8 { 160 bits -= 8 161 blocks[blocksOff] = byte(uint(v) >> uint(bits)) 162 blocksOff++ 163 } 164 // then buffer 165 bitsLeft = 8 - bits 166 nextBlock = (v & ((1 << uint(bits)) - 1)) << uint(bitsLeft) 167 } 168 } 169 assert(bitsLeft == 8) 170 } 171 172 // util/packed/BulkOperationPackedSingleBlock.java 173 174 // Non-specialized BulkOperation for PACKED_SINGLE_BLOCK format 175 type BulkOperationPackedSingleBlock struct { 176 *BulkOperationImpl 177 bitsPerValue int 178 valueCount int 179 mask int64 180 } 181 182 const BLOCK_COUNT = 1 183 184 func newBulkOperationPackedSingleBlock(bitsPerValue uint32) BulkOperation { 185 // log.Printf("Initializing BulkOperationPackedSingleBlock(%v)", bitsPerValue) 186 self := &BulkOperationPackedSingleBlock{ 187 bitsPerValue: int(bitsPerValue), 188 valueCount: 64 / int(bitsPerValue), 189 mask: (int64(1) << bitsPerValue) - 1, 190 } 191 self.BulkOperationImpl = newBulkOperationImpl(self) 192 return self 193 } 194 195 func (p *BulkOperationPackedSingleBlock) LongBlockCount() int { 196 return BLOCK_COUNT 197 } 198 199 func (p *BulkOperationPackedSingleBlock) ByteBlockCount() int { 200 return BLOCK_COUNT * 8 201 } 202 203 func (p *BulkOperationPackedSingleBlock) LongValueCount() int { 204 return p.valueCount 205 } 206 207 func (p *BulkOperationPackedSingleBlock) ByteValueCount() int { 208 return p.valueCount 209 } 210 211 func (p *BulkOperationPackedSingleBlock) decodeLongs(block int64, values []int64) int { 212 off := 0 213 values[off] = block & p.mask 214 off++ 215 for j := 1; j < p.valueCount; j++ { 216 block = int64(uint64(block) >> uint(p.bitsPerValue)) 217 values[off] = block & p.mask 218 off++ 219 } 220 return off 221 } 222 223 func (p *BulkOperationPackedSingleBlock) encodeLongs(values []int64) int64 { 224 off := 0 225 block := values[off] 226 off++ 227 for j := 1; j < p.valueCount; j++ { 228 block |= (values[off] << uint(j*p.bitsPerValue)) 229 off++ 230 } 231 return block 232 } 233 234 func (p *BulkOperationPackedSingleBlock) encodeInts(values []int) int64 { 235 off := 0 236 block := int64(values[off]) 237 off++ 238 for j := 1; j < p.valueCount; j++ { 239 block |= int64(values[off]) << uint(j*p.bitsPerValue) 240 off++ 241 } 242 return block 243 } 244 245 func (p *BulkOperationPackedSingleBlock) decodeLongToLong(blocks, values []int64, iterations int) { 246 blocksOffset, valuesOffset := 0, 0 247 for i := 0; i < iterations; i++ { 248 block := blocks[blocksOffset] 249 blocksOffset++ 250 valuesOffset = p.decodeLongs(block, values[valuesOffset:]) 251 } 252 } 253 254 func (p *BulkOperationPackedSingleBlock) decodeByteToLong(blocks []byte, 255 values []int64, iterations int) { 256 panic("niy") 257 } 258 259 func (p *BulkOperationPackedSingleBlock) encodeLongToLong(values, 260 blocks []int64, iterations int) { 261 valuesOffset, blocksOffset := 0, 0 262 for i, limit := 0, iterations; i < limit; i++ { 263 blocks[blocksOffset] = p.encodeLongs(values[valuesOffset:]) 264 blocksOffset++ 265 valuesOffset += p.valueCount 266 } 267 } 268 269 func (p *BulkOperationPackedSingleBlock) encodeLongToByte(values []int64, 270 blocks []byte, iterations int) { 271 272 valuesOffset, blocksOffset := 0, 0 273 for i := 0; i < iterations; i++ { 274 block := p.encodeLongs(values[valuesOffset:]) 275 valuesOffset += p.valueCount 276 blocksOffset += p.writeLong(block, blocks[blocksOffset:]) 277 } 278 } 279 280 func (p *BulkOperationPackedSingleBlock) EncodeIntToByte(values []int, 281 blocks []byte, iterations int) { 282 283 valuesOffset, blocksOffset := 0, 0 284 for i := 0; i < iterations; i++ { 285 block := p.encodeInts(values[valuesOffset:]) 286 valuesOffset += p.valueCount 287 blocksOffset += p.writeLong(block, blocks[blocksOffset:]) 288 } 289 }