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  }