github.com/balzaczyy/golucene@v0.0.0-20151210033525-d0be9ee89713/core/util/packed/packedLongValues.go (about) 1 package packed 2 3 import ( 4 "github.com/balzaczyy/golucene/core/util" 5 "reflect" 6 ) 7 8 // util/packed/PackedLongValues.java 9 10 const DEFAULT_PAGE_SIZE = 1024 11 const MIN_PAGE_SIZE = 64 12 const MAX_PAGE_SIZE = 1 << 20 13 14 type PackedLongValues interface { 15 Size() int64 16 Iterator() func() (interface{}, bool) 17 } 18 19 type PackedLongValuesBuilder interface { 20 util.Accountable 21 Build() PackedLongValues 22 Size() int64 23 Add(int64) PackedLongValuesBuilder 24 } 25 26 func DeltaPackedBuilder(acceptableOverheadRatio float32) PackedLongValuesBuilder { 27 return NewDeltaPackedLongValuesBuilder(DEFAULT_PAGE_SIZE, acceptableOverheadRatio) 28 } 29 30 type PackedLongValuesImpl struct { 31 values []PackedIntsReader 32 pageShift, pageMask int 33 size int64 34 ramBytesUsed int64 35 } 36 37 func newPackedLongValues(pageShift, pageMask int, 38 values []PackedIntsReader, 39 size, ramBytesUsed int64) *PackedLongValuesImpl { 40 41 return &PackedLongValuesImpl{ 42 pageShift: pageShift, 43 pageMask: pageMask, 44 values: values, 45 size: size, 46 ramBytesUsed: ramBytesUsed, 47 } 48 } 49 50 func (p *PackedLongValuesImpl) Size() int64 { 51 return p.size 52 } 53 54 func (p *PackedLongValuesImpl) decodeBlock(block int, dest []int64) int { 55 vals := p.values[block] 56 size := vals.Size() 57 for k := 0; k < size; { 58 k += vals.getBulk(k, dest[k:size]) 59 } 60 return size 61 } 62 63 func (p *PackedLongValuesImpl) Iterator() func() (interface{}, bool) { 64 currentValues := make([]int64, p.pageMask+1) 65 vOff := 0 66 pOff := 0 67 currentCount := 0 68 fillBlock := func() { 69 if vOff == len(p.values) { 70 currentCount = 0 71 } else { 72 currentCount = p.decodeBlock(vOff, currentValues) 73 assert(currentCount > 0) 74 } 75 } 76 fillBlock() 77 return func() (v interface{}, ok bool) { 78 if pOff < currentCount { 79 v = currentValues[pOff] 80 if pOff++; pOff == currentCount { 81 vOff++ 82 pOff = 0 83 fillBlock() 84 } 85 } 86 return v, pOff < currentCount 87 } 88 } 89 90 const INITIAL_PAGE_COUNT = 16 91 92 type PackedLongValuesBuilderImpl struct { 93 pageShift, pageMask int 94 acceptableOverheadRatio float32 95 pending []int64 96 size int64 97 98 values []PackedIntsReader 99 ramBytesUsed int64 100 valuesOff int 101 pendingOff int 102 } 103 104 func newPackedLongValuesBuilder(pageSize int, 105 acceptableOverheadRatio float32) *PackedLongValuesBuilderImpl { 106 107 ans := &PackedLongValuesBuilderImpl{ 108 pageShift: checkBlockSize(pageSize, MIN_PAGE_SIZE, MAX_PAGE_SIZE), 109 pageMask: pageSize - 1, 110 acceptableOverheadRatio: acceptableOverheadRatio, 111 values: make([]PackedIntsReader, INITIAL_PAGE_COUNT), 112 pending: make([]int64, pageSize), 113 } 114 ans.ramBytesUsed = util.ShallowSizeOfInstance(reflect.TypeOf(&PackedLongValuesBuilderImpl{})) + 115 util.SizeOf(ans.pending) + util.ShallowSizeOf(ans.values) 116 return ans 117 } 118 119 /* 120 Build a PackedLongValues instance that contains values that have been 121 added to this builder. This operation is destructive. 122 */ 123 func (b *PackedLongValuesBuilderImpl) Build() PackedLongValues { 124 b.finish() 125 b.pending = nil 126 values := make([]PackedIntsReader, b.valuesOff) 127 copy(values, b.values[:b.valuesOff]) 128 ramBytesUsed := util.ShallowSizeOfInstance(reflect.TypeOf(&PackedLongValuesImpl{})) + 129 util.SizeOf(values) 130 return newPackedLongValues(b.pageShift, b.pageMask, values, b.size, ramBytesUsed) 131 } 132 133 func (b *PackedLongValuesBuilderImpl) RamBytesUsed() int64 { 134 return b.ramBytesUsed 135 } 136 137 /* Return the number of elements that have been added to this builder */ 138 func (b *PackedLongValuesBuilderImpl) Size() int64 { 139 return b.size 140 } 141 142 /* Add a new element to this builder. */ 143 func (b *PackedLongValuesBuilderImpl) Add(l int64) PackedLongValuesBuilder { 144 assert2(b.pending != nil, "Cannot be reused after build()") 145 if b.pendingOff == len(b.pending) { // check size 146 if b.valuesOff == len(b.values) { 147 newLength := util.Oversize(b.valuesOff+1, 8) 148 b.grow(newLength) 149 } 150 b.pack() 151 } 152 b.pending[b.pendingOff] = l 153 b.pendingOff++ 154 b.size++ 155 return b 156 } 157 158 func (b *PackedLongValuesBuilderImpl) finish() { 159 if b.pendingOff > 0 { 160 if len(b.values) == b.valuesOff { 161 b.grow(b.valuesOff + 1) 162 } 163 b.pack() 164 } 165 } 166 167 func (b *PackedLongValuesBuilderImpl) pack() { 168 b.packFrom(b.pending[:b.pendingOff], b.valuesOff, b.acceptableOverheadRatio) 169 b.ramBytesUsed += b.values[b.valuesOff].RamBytesUsed() 170 b.valuesOff++ 171 b.pendingOff = 0 // reset pending buffer 172 } 173 174 func (b *PackedLongValuesBuilderImpl) packFrom(values []int64, 175 block int, acceptableOverheadRatio float32) { 176 177 assert(len(values) > 0) 178 179 // compute max delta 180 minValue := values[0] 181 maxValue := values[0] 182 for _, v := range values[1:] { 183 if v < minValue { 184 minValue = v 185 } else if v > maxValue { 186 maxValue = v 187 } 188 } 189 190 // build a new packed reader 191 if minValue == 0 && maxValue == 0 { 192 b.values[block] = newNilReader(len(values)) 193 } else { 194 bitsRequired := 64 195 if minValue >= 0 { 196 bitsRequired = BitsRequired(maxValue) 197 } 198 mutable := MutableFor(len(values), bitsRequired, acceptableOverheadRatio) 199 for i := 0; i < len(values); i++ { 200 i += mutable.setBulk(i, values[i:]) 201 } 202 b.values[block] = mutable 203 } 204 } 205 206 func (b *PackedLongValuesBuilderImpl) grow(newBlockCount int) { 207 panic("niy") 208 } 209 210 // util/packed/DeltaPackedLongValues.java 211 212 type DeltaPackedLongValuesBuilderImpl struct { 213 *PackedLongValuesBuilderImpl 214 mins []int64 215 } 216 217 func NewDeltaPackedLongValuesBuilder(pageSize int, 218 acceptableOverheadRatio float32) *DeltaPackedLongValuesBuilderImpl { 219 220 super := newPackedLongValuesBuilder(pageSize, acceptableOverheadRatio) 221 ans := &DeltaPackedLongValuesBuilderImpl{ 222 PackedLongValuesBuilderImpl: super, 223 mins: make([]int64, len(super.values)), 224 } 225 ans.ramBytesUsed += util.ShallowSizeOfInstance(reflect.TypeOf(&DeltaPackedLongValuesBuilderImpl{})) + 226 util.SizeOf(ans.mins) 227 return ans 228 }