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  }