github.com/balzaczyy/golucene@v0.0.0-20151210033525-d0be9ee89713/core/util/intBlockPool.go (about)

     1  package util
     2  
     3  // util/IntBlockPool.java
     4  
     5  const INT_BLOCK_SHIFT = 13
     6  const INT_BLOCK_SIZE = 1 << INT_BLOCK_SHIFT
     7  const INT_BLOCK_MASK = INT_BLOCK_SIZE - 1
     8  
     9  /* A pool for int blocks similar to ByteBlockPool */
    10  type IntBlockPool struct {
    11  	Buffers    [][]int
    12  	bufferUpto int
    13  	IntUpto    int
    14  	Buffer     []int
    15  	IntOffset  int
    16  	allocator  IntAllocator
    17  }
    18  
    19  func NewIntBlockPool(allocator IntAllocator) *IntBlockPool {
    20  	return &IntBlockPool{
    21  		Buffers:    make([][]int, 10),
    22  		bufferUpto: -1,
    23  		IntUpto:    INT_BLOCK_SIZE,
    24  		IntOffset:  -INT_BLOCK_SIZE,
    25  		allocator:  allocator,
    26  	}
    27  }
    28  
    29  /* Expert: Resets the pool to its initial state reusing the first buffer. */
    30  func (pool *IntBlockPool) Reset(zeroFillBuffers, reuseFirst bool) {
    31  	if pool.bufferUpto != -1 {
    32  		// We allocated at least one buffer
    33  		if zeroFillBuffers {
    34  			panic("not implemented yet")
    35  		}
    36  
    37  		if pool.bufferUpto > 0 || !reuseFirst {
    38  			offset := 0
    39  			if reuseFirst {
    40  				offset = 1
    41  			}
    42  			// Recycle all but the first buffer
    43  			pool.allocator.Recycle(pool.Buffers[offset : 1+pool.bufferUpto])
    44  			for i := offset; i <= pool.bufferUpto; i++ {
    45  				pool.Buffers[i] = nil
    46  			}
    47  		}
    48  		if reuseFirst {
    49  			panic("not implemented yet")
    50  		} else {
    51  			pool.bufferUpto = -1
    52  			pool.IntUpto = INT_BLOCK_SIZE
    53  			pool.IntOffset = -INT_BLOCK_SIZE
    54  			pool.Buffer = nil
    55  		}
    56  	}
    57  }
    58  
    59  /*
    60  Advances the pool to its next buffer. This mthod should be called
    61  once after the constructor to initialize the pool. In contrast to the
    62  constructor a IntBlockPool.reset() call will advance the pool to its
    63  first buffer immediately.
    64  */
    65  func (p *IntBlockPool) NextBuffer() {
    66  	if 1+p.bufferUpto == len(p.Buffers) {
    67  		newBuffers := make([][]int, len(p.Buffers)+len(p.Buffers)/2)
    68  		copy(newBuffers, p.Buffers)
    69  		p.Buffers = newBuffers
    70  	}
    71  	p.Buffer = p.allocator.allocate()
    72  	p.Buffers[1+p.bufferUpto] = p.Buffer
    73  	p.bufferUpto++
    74  
    75  	p.IntUpto = 0
    76  	p.IntOffset += INT_BLOCK_SIZE
    77  }
    78  
    79  type IntAllocator interface {
    80  	Recycle(blocks [][]int)
    81  	allocate() []int
    82  }
    83  
    84  type IntAllocatorImpl struct {
    85  	blockSize int
    86  }
    87  
    88  func NewIntAllocator(blockSize int) *IntAllocatorImpl {
    89  	return &IntAllocatorImpl{blockSize}
    90  }
    91  
    92  func (a *IntAllocatorImpl) allocate() []int {
    93  	return make([]int, a.blockSize)
    94  }