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 }