github.com/balzaczyy/golucene@v0.0.0-20151210033525-d0be9ee89713/core/util/packed/packed64SingleBlock.go (about) 1 package packed 2 3 import ( 4 "fmt" 5 "github.com/balzaczyy/golucene/core/util" 6 ) 7 8 func is64Supported(bitsPerValue int) bool { 9 // Lucene use binary-search which is unnecessary 10 assert(bitsPerValue > 0 && bitsPerValue <= 64) 11 return bitsPerValue <= len(packedSingleBlockBulkOps) && 12 packedSingleBlockBulkOps[bitsPerValue-1] != nil 13 } 14 15 func requiredCapacity(valueCount, valuesPerBlock int32) int32 { 16 fit := (valueCount % valuesPerBlock) != 0 17 ans := valueCount / valuesPerBlock 18 if fit { 19 ans++ 20 } 21 return ans 22 } 23 24 type Packed64SingleBlock struct { 25 *MutableImpl 26 get func(int) int64 27 set func(int, int64) 28 blocks []int64 29 } 30 31 func newPacked64SingleBlock(valueCount int32, bitsPerValue uint32) *Packed64SingleBlock { 32 // assert isSupported(bitsPerValue) 33 valuesPerBlock := int32(64 / bitsPerValue) 34 ans := &Packed64SingleBlock{blocks: make([]int64, requiredCapacity(valueCount, valuesPerBlock))} 35 ans.MutableImpl = newMutableImpl(ans, int(valueCount), int(bitsPerValue)) 36 return ans 37 } 38 39 func (p *Packed64SingleBlock) Clear() { 40 for i, _ := range p.blocks { 41 p.blocks[i] = 0 42 } 43 } 44 45 func (p *Packed64SingleBlock) RamBytesUsed() int64 { 46 return util.AlignObjectSize( 47 util.NUM_BYTES_OBJECT_HEADER + 48 2*util.NUM_BYTES_INT + 49 util.NUM_BYTES_OBJECT_REF + 50 util.SizeOf(p.blocks)) 51 } 52 53 func (p *Packed64SingleBlock) Get(index int) int64 { 54 return p.get(index) 55 } 56 57 func (p *Packed64SingleBlock) Set(index int, value int64) { 58 p.set(index, value) 59 } 60 61 func (p *Packed64SingleBlock) getBulk(index int, arr []int64) int { 62 off, length := 0, len(arr) 63 assert2(length > 0, "len must be > 0 (got %v)", length) 64 assert(index >= 0 && index < p.valueCount) 65 if p.valueCount-index < length { 66 length = p.valueCount - index 67 } 68 69 originalIndex := index 70 71 // go to the next block boundry 72 valuesPerBlock := 64 / p.bitsPerValue 73 offsetInBlock := index % valuesPerBlock 74 if offsetInBlock != 0 { 75 for i := offsetInBlock; i < valuesPerBlock && length > 0; i++ { 76 arr[off] = p.Get(index) 77 off++ 78 index++ 79 length-- 80 } 81 if length == 0 { 82 return index - originalIndex 83 } 84 } 85 86 // bulk get 87 assert(index%valuesPerBlock == 0) 88 op := newBulkOperation(PackedFormat(PACKED_SINGLE_BLOCK), uint32(p.bitsPerValue)) 89 assert(op.LongBlockCount() == 1) 90 assert(op.LongValueCount() == valuesPerBlock) 91 blockIndex := index / valuesPerBlock 92 nBlocks := (index+length)/valuesPerBlock - blockIndex 93 op.decodeLongToLong(p.blocks[blockIndex:], arr[off:], nBlocks) 94 diff := nBlocks * valuesPerBlock 95 index += diff 96 length -= diff 97 98 if index > originalIndex { 99 // stay at the block boundry 100 return index - originalIndex 101 } 102 // no progress so far => already at a block boundry but no full block to set 103 assert(index == originalIndex) 104 return p.MutableImpl.getBulk(index, arr[off:off+length]) 105 } 106 107 func (p *Packed64SingleBlock) setBulk(index int, arr []int64) int { 108 off, length := 0, len(arr) 109 assert2(length > 0, "len must be > 0 (got %v)", length) 110 assert(index >= 0 && index < p.valueCount) 111 if p.valueCount-index < length { 112 length = p.valueCount - index 113 } 114 115 originalIndex := index 116 117 // go to the next block boundry 118 valuesPerBlock := 64 / p.bitsPerValue 119 offsetInBlock := index % valuesPerBlock 120 if offsetInBlock != 0 { 121 for i := offsetInBlock; i < valuesPerBlock && length > 0; i++ { 122 p.Set(index, arr[off]) 123 index++ 124 off++ 125 length-- 126 } 127 if length == 0 { 128 return index - originalIndex 129 } 130 } 131 132 // bulk set 133 assert(index%valuesPerBlock == 0) 134 op := newBulkOperation(PackedFormat(PACKED_SINGLE_BLOCK), uint32(p.bitsPerValue)) 135 assert(op.LongBlockCount() == 1) 136 assert(op.LongValueCount() == valuesPerBlock) 137 blockIndex := index / valuesPerBlock 138 nBlocks := (index+length)/valuesPerBlock - blockIndex 139 op.encodeLongToLong(arr[off:], p.blocks[blockIndex:], nBlocks) 140 diff := nBlocks * valuesPerBlock 141 index += diff 142 length -= diff 143 144 if index > originalIndex { 145 // stay at the block boundry 146 return index - originalIndex 147 } 148 // no progress so far => already at a block boundry but no full block to set 149 assert(index == originalIndex) 150 return p.MutableImpl.setBulk(index, arr[off:off+length]) 151 } 152 153 func (p *Packed64SingleBlock) fill(from, to int, val int64) { 154 panic("niy") 155 } 156 157 func (p *Packed64SingleBlock) Format() PackedFormat { 158 return PackedFormat(PACKED_SINGLE_BLOCK) 159 } 160 161 func (p *Packed64SingleBlock) String() string { 162 return fmt.Sprintf("Packed64SingleBlock(bitsPerValue=%v, size=%v, elements.length=%v)", 163 p.bitsPerValue, p.Size(), len(p.blocks)) 164 } 165 166 func newPacked64SingleBlockFromInput(in DataInput, valueCount int32, bitsPerValue uint32) (reader PackedIntsReader, err error) { 167 ans := newPacked64SingleBlockBy(valueCount, bitsPerValue) 168 for i, _ := range ans.blocks { 169 if ans.blocks[i], err = in.ReadLong(); err != nil { 170 break 171 } 172 } 173 return ans, err 174 } 175 176 func newPacked64SingleBlockBy(valueCount int32, bitsPerValue uint32) *Packed64SingleBlock { 177 switch bitsPerValue { 178 case 1: 179 return newPacked64SingleBlock1(valueCount) 180 case 2: 181 return newPacked64SingleBlock2(valueCount) 182 case 3: 183 return newPacked64SingleBlock3(valueCount) 184 case 4: 185 return newPacked64SingleBlock4(valueCount) 186 case 5: 187 return newPacked64SingleBlock5(valueCount) 188 case 6: 189 return newPacked64SingleBlock6(valueCount) 190 case 7: 191 return newPacked64SingleBlock7(valueCount) 192 case 8: 193 return newPacked64SingleBlock8(valueCount) 194 case 9: 195 return newPacked64SingleBlock9(valueCount) 196 case 10: 197 return newPacked64SingleBlock10(valueCount) 198 case 12: 199 return newPacked64SingleBlock12(valueCount) 200 case 16: 201 return newPacked64SingleBlock16(valueCount) 202 case 21: 203 return newPacked64SingleBlock21(valueCount) 204 case 32: 205 return newPacked64SingleBlock32(valueCount) 206 default: 207 panic(fmt.Sprintf("Unsuppoted number of bits per value: %v", bitsPerValue)) 208 } 209 } 210 211 func newPacked64SingleBlock1(valueCount int32) *Packed64SingleBlock { 212 ans := newPacked64SingleBlock(valueCount, 1) 213 ans.get = func(index int) int64 { 214 o := uint32(index) >> 6 215 b := index & 63 216 shift := uint32(b << 0) 217 return int64(uint64(ans.blocks[o])>>shift) & 1 218 } 219 ans.set = func(index int, value int64) { 220 o := uint32(index) >> 6 221 b := uint32(index & 63) 222 shift := b << 0 223 ans.blocks[o] = (ans.blocks[o] & ^(int64(1) << shift)) | (value << shift) 224 } 225 return ans 226 } 227 228 func newPacked64SingleBlock2(valueCount int32) *Packed64SingleBlock { 229 ans := newPacked64SingleBlock(valueCount, 2) 230 ans.get = func(index int) int64 { 231 o := uint32(index) >> 5 232 b := index & 31 233 shift := uint32(b << 1) 234 return int64(uint64(ans.blocks[o])>>shift) & 3 235 } 236 ans.set = func(index int, value int64) { 237 o := uint32(index) >> 5 238 b := index & 31 239 shift := uint32(b << 1) 240 ans.blocks[o] = (ans.blocks[o] & ^(int64(3) << shift)) | (value << shift) 241 } 242 return ans 243 } 244 245 func newPacked64SingleBlock3(valueCount int32) *Packed64SingleBlock { 246 ans := newPacked64SingleBlock(valueCount, 3) 247 ans.get = func(index int) int64 { 248 o := index / 21 249 b := index % 21 250 shift := uint32(b * 3) 251 return int64(uint64(ans.blocks[o])>>shift) & 7 252 } 253 ans.set = func(index int, value int64) { 254 o := index / 21 255 b := index % 21 256 shift := uint32(b * 3) 257 ans.blocks[o] = (ans.blocks[o] & ^(int64(7) << shift)) | (value << shift) 258 } 259 return ans 260 } 261 262 func newPacked64SingleBlock4(valueCount int32) *Packed64SingleBlock { 263 ans := newPacked64SingleBlock(valueCount, 4) 264 ans.get = func(index int) int64 { 265 o := uint32(index) >> 4 266 b := index & 15 267 shift := uint32(b << 2) 268 return int64(uint64(ans.blocks[o])>>shift) & 15 269 } 270 ans.set = func(index int, value int64) { 271 o := uint32(index) >> 4 272 b := index & 15 273 shift := uint32(b << 2) 274 ans.blocks[o] = (ans.blocks[o] & ^(int64(15) << shift)) | (value << shift) 275 } 276 return ans 277 } 278 279 func newPacked64SingleBlock5(valueCount int32) *Packed64SingleBlock { 280 ans := newPacked64SingleBlock(valueCount, 5) 281 ans.get = func(index int) int64 { 282 o := index / 12 283 b := index % 12 284 shift := uint32(b * 5) 285 return int64(uint64(ans.blocks[o])>>shift) & 31 286 } 287 ans.set = func(index int, value int64) { 288 o := index / 12 289 b := index % 12 290 shift := uint32(b * 5) 291 ans.blocks[o] = (ans.blocks[o] & ^(int64(31) << shift)) | (value << shift) 292 } 293 return ans 294 } 295 296 func newPacked64SingleBlock6(valueCount int32) *Packed64SingleBlock { 297 ans := newPacked64SingleBlock(valueCount, 6) 298 ans.get = func(index int) int64 { 299 o := index / 10 300 b := index % 10 301 shift := uint32(b * 6) 302 return int64(uint64(ans.blocks[o])>>shift) & 63 303 } 304 ans.set = func(index int, value int64) { 305 o := index / 10 306 b := index % 10 307 shift := uint32(b * 6) 308 ans.blocks[o] = (ans.blocks[o] & ^(int64(63) << shift)) | (value << shift) 309 } 310 return ans 311 } 312 313 func newPacked64SingleBlock7(valueCount int32) *Packed64SingleBlock { 314 ans := newPacked64SingleBlock(valueCount, 7) 315 ans.get = func(index int) int64 { 316 o := index / 9 317 b := index % 9 318 shift := uint32(b * 7) 319 return int64(uint64(ans.blocks[o])>>shift) & 127 320 } 321 ans.set = func(index int, value int64) { 322 o := index / 9 323 b := index % 9 324 shift := uint32(b * 7) 325 ans.blocks[o] = (ans.blocks[o] & ^(int64(127) << shift)) | (value << shift) 326 } 327 return ans 328 } 329 330 func newPacked64SingleBlock8(valueCount int32) *Packed64SingleBlock { 331 ans := newPacked64SingleBlock(valueCount, 8) 332 ans.get = func(index int) int64 { 333 o := uint32(index) >> 3 334 b := index & 7 335 shift := uint32(b << 3) 336 return int64(uint64(ans.blocks[o])>>shift) & 255 337 } 338 ans.set = func(index int, value int64) { 339 o := uint32(index) >> 3 340 b := index & 7 341 shift := uint32(b << 3) 342 ans.blocks[o] = (ans.blocks[o] & ^(int64(255) << shift)) | (value << shift) 343 } 344 return ans 345 } 346 347 func newPacked64SingleBlock9(valueCount int32) *Packed64SingleBlock { 348 ans := newPacked64SingleBlock(valueCount, 9) 349 ans.get = func(index int) int64 { 350 o := index / 7 351 b := index % 7 352 shift := uint32(b * 9) 353 return int64(uint64(ans.blocks[o])>>shift) & 511 354 } 355 ans.set = func(index int, value int64) { 356 o := index / 7 357 b := index % 7 358 shift := uint32(b * 9) 359 ans.blocks[o] = (ans.blocks[o] & ^(int64(511) << shift)) | (value << shift) 360 } 361 return ans 362 } 363 364 func newPacked64SingleBlock10(valueCount int32) *Packed64SingleBlock { 365 ans := newPacked64SingleBlock(valueCount, 10) 366 ans.get = func(index int) int64 { 367 o := index / 6 368 b := index % 6 369 shift := uint32(b * 10) 370 return int64(uint64(ans.blocks[o])>>shift) & 1023 371 } 372 ans.set = func(index int, value int64) { 373 o := index / 6 374 b := index % 6 375 shift := uint32(b * 10) 376 ans.blocks[o] = (ans.blocks[o] & ^(int64(1023) << shift)) | (value << shift) 377 } 378 return ans 379 } 380 func newPacked64SingleBlock12(valueCount int32) *Packed64SingleBlock { 381 ans := newPacked64SingleBlock(valueCount, 12) 382 ans.get = func(index int) int64 { 383 o := index / 5 384 b := index % 5 385 shift := uint32(b * 12) 386 return int64(uint64(ans.blocks[o])>>shift) & 4095 387 } 388 ans.set = func(index int, value int64) { 389 o := index / 5 390 b := index % 5 391 shift := uint32(b * 12) 392 ans.blocks[o] = (ans.blocks[o] & ^(int64(4095) << shift)) | (value << shift) 393 } 394 return ans 395 } 396 397 func newPacked64SingleBlock16(valueCount int32) *Packed64SingleBlock { 398 ans := newPacked64SingleBlock(valueCount, 16) 399 ans.get = func(index int) int64 { 400 o := uint32(index) >> 2 401 b := index & 3 402 shift := uint32(b << 4) 403 return int64(uint64(ans.blocks[o])>>shift) & 65535 404 } 405 ans.set = func(index int, value int64) { 406 o := uint32(index) >> 2 407 b := index & 3 408 shift := uint32(b << 4) 409 ans.blocks[o] = (ans.blocks[o] & ^(int64(65335) << shift)) | (value << shift) 410 } 411 return ans 412 } 413 414 func newPacked64SingleBlock21(valueCount int32) *Packed64SingleBlock { 415 ans := newPacked64SingleBlock(valueCount, 21) 416 ans.get = func(index int) int64 { 417 o := index / 3 418 b := index % 3 419 shift := uint32(b * 21) 420 return int64(uint64(ans.blocks[o])>>shift) & 2097151 421 } 422 ans.set = func(index int, value int64) { 423 o := index / 3 424 b := index % 3 425 shift := uint32(b * 21) 426 ans.blocks[o] = (ans.blocks[o] & ^(int64(2097151) << shift)) | (value << shift) 427 } 428 return ans 429 } 430 431 func newPacked64SingleBlock32(valueCount int32) *Packed64SingleBlock { 432 ans := newPacked64SingleBlock(valueCount, 32) 433 ans.get = func(index int) int64 { 434 o := uint32(index) >> 1 435 b := index & 1 436 shift := uint32(b << 5) 437 return int64(uint64(ans.blocks[o])>>shift) & 4294967295 438 } 439 ans.set = func(index int, value int64) { 440 o := uint32(index) >> 1 441 b := index & 1 442 shift := uint32(b << 5) 443 ans.blocks[o] = (ans.blocks[o] & ^(int64(4294967295) << shift)) | (value << shift) 444 } 445 return ans 446 }