github.com/balzaczyy/golucene@v0.0.0-20151210033525-d0be9ee89713/core/util/packed/paged.go (about) 1 package packed 2 3 // packed/AbstractPagedMutable.java 4 5 const MIN_BLOCK_SIZE = 1 << 6 6 const MAX_BLOCK_SIZE = 1 << 30 7 8 type abstractPagedMutableSPI interface { 9 newMutable(int, int) Mutable 10 } 11 12 type abstractPagedMutable struct { 13 spi abstractPagedMutableSPI 14 size int64 15 pageShift uint 16 pageMask int 17 subMutables []Mutable 18 bitsPerValue int 19 } 20 21 func newAbstractPagedMutable(spi abstractPagedMutableSPI, 22 bitsPerValue int, size int64, pageSize int) *abstractPagedMutable { 23 numPages := numBlocks(size, pageSize) 24 return &abstractPagedMutable{ 25 spi: spi, 26 bitsPerValue: bitsPerValue, 27 size: size, 28 pageShift: uint(checkBlockSize(pageSize, MIN_BLOCK_SIZE, MAX_BLOCK_SIZE)), 29 pageMask: pageSize - 1, 30 subMutables: make([]Mutable, numPages), 31 } 32 } 33 34 func (m *abstractPagedMutable) fillPages() { 35 numPages := numBlocks(m.size, m.pageSize()) 36 for i := 0; i < numPages; i++ { 37 // do not allocate for more entries than necessary on the last page 38 var valueCount int 39 if i == numPages-1 { 40 valueCount = m.lastPageSize(m.size) 41 } else { 42 valueCount = m.pageSize() 43 } 44 m.subMutables[i] = m.spi.newMutable(valueCount, m.bitsPerValue) 45 } 46 } 47 48 func (m *abstractPagedMutable) lastPageSize(size int64) int { 49 if sz := m.indexInPage(size); sz != 0 { 50 return sz 51 } 52 return m.pageSize() 53 } 54 55 func (m *abstractPagedMutable) pageSize() int { 56 return m.pageMask + 1 57 } 58 59 func (m *abstractPagedMutable) Size() int64 { 60 return m.size 61 } 62 63 func (m *abstractPagedMutable) pageIndex(index int64) int { 64 return int(uint64(index) >> m.pageShift) 65 } 66 67 func (m *abstractPagedMutable) indexInPage(index int64) int { 68 return int(index & int64(m.pageMask)) 69 } 70 71 func (m *abstractPagedMutable) Get(index int64) int64 { 72 assert(index >= 0 && index < m.size) 73 pageIndex := m.pageIndex(index) 74 indexInPage := m.indexInPage(index) 75 return m.subMutables[pageIndex].Get(indexInPage) 76 } 77 78 /* set value at index. */ 79 func (m *abstractPagedMutable) Set(index, value int64) { 80 assert(index >= 0 && index < m.size) 81 pageIndex := m.pageIndex(index) 82 indexInPage := m.indexInPage(index) 83 m.subMutables[pageIndex].Set(indexInPage, value) 84 } 85 86 // packed/PagedGrowableWriter.java 87 88 /* 89 A PagedGrowableWriter. This class slices data into fixed-size blocks 90 which have independent numbers of bits per value and grow on-demand. 91 92 You should use this class instead of the AbstractAppendingLongBuffer 93 related ones only when you need random write-access. Otherwise this 94 class will likely be slower and less memory-efficient. 95 */ 96 type PagedGrowableWriter struct { 97 *abstractPagedMutable 98 acceptableOverheadRatio float32 99 } 100 101 /* Create a new PagedGrowableWriter instance. */ 102 func NewPagedGrowableWriter(size int64, pageSize, startBitsPerValue int, 103 acceptableOverheadRatio float32) *PagedGrowableWriter { 104 return newPagedGrowableWriter(size, pageSize, startBitsPerValue, acceptableOverheadRatio, true) 105 } 106 107 func newPagedGrowableWriter(size int64, pageSize, startBitsPerValue int, 108 acceptableOverheadRatio float32, fillPages bool) *PagedGrowableWriter { 109 ans := &PagedGrowableWriter{acceptableOverheadRatio: acceptableOverheadRatio} 110 ans.abstractPagedMutable = newAbstractPagedMutable(ans, startBitsPerValue, size, pageSize) 111 if fillPages { 112 ans.fillPages() 113 } 114 return ans 115 } 116 117 func (w *PagedGrowableWriter) newMutable(valueCount, bitsPerValue int) Mutable { 118 return NewGrowableWriter(bitsPerValue, valueCount, w.acceptableOverheadRatio) 119 }