github.com/balzaczyy/golucene@v0.0.0-20151210033525-d0be9ee89713/core/store/buffer.go (about) 1 package store 2 3 import ( 4 "errors" 5 "fmt" 6 ) 7 8 type SeekReader interface { 9 seekInternal(pos int64) error 10 readInternal(buf []byte) error 11 Length() int64 12 } 13 14 /* Minimum buffer size allowed */ 15 const MIN_BUFFER_SIZE = 8 16 17 /* Base implementation class for buffered IndexInput. */ 18 type BufferedIndexInput struct { 19 *IndexInputImpl 20 spi SeekReader 21 bufferSize int 22 buffer []byte 23 bufferStart int64 24 bufferLength int 25 bufferPosition int 26 } 27 28 func newBufferedIndexInput(spi SeekReader, desc string, context IOContext) *BufferedIndexInput { 29 return newBufferedIndexInputBySize(spi, desc, bufferSize(context)) 30 } 31 32 func newBufferedIndexInputBySize(spi SeekReader, desc string, bufferSize int) *BufferedIndexInput { 33 checkBufferSize(bufferSize) 34 ans := &BufferedIndexInput{spi: spi, bufferSize: bufferSize} 35 ans.IndexInputImpl = NewIndexInputImpl(desc, ans) 36 return ans 37 } 38 39 func (in *BufferedIndexInput) newBuffer(newBuffer []byte) { 40 // Subclasses can do something here 41 in.buffer = newBuffer 42 } 43 44 func (in *BufferedIndexInput) ReadByte() (b byte, err error) { 45 if in.bufferPosition >= in.bufferLength { 46 err = in.refill() 47 if err != nil { 48 return 0, err 49 } 50 } 51 b = in.buffer[in.bufferPosition] 52 in.bufferPosition++ 53 return 54 } 55 56 func checkBufferSize(bufferSize int) { 57 assert2(bufferSize >= MIN_BUFFER_SIZE, 58 "bufferSize must be at least MIN_BUFFER_SIZE (got %v)", 59 bufferSize) 60 } 61 62 func (in *BufferedIndexInput) ReadBytes(buf []byte) error { 63 return in.ReadBytesBuffered(buf, true) 64 } 65 66 func (in *BufferedIndexInput) ReadBytesBuffered(buf []byte, useBuffer bool) error { 67 available := in.bufferLength - in.bufferPosition 68 if length := len(buf); length <= available { 69 // the buffer contains enough data to satisfy this request 70 if length > 0 { // to allow b to be null if len is 0... 71 copy(buf, in.buffer[in.bufferPosition:in.bufferPosition+length]) 72 } 73 in.bufferPosition += length 74 } else { 75 // the buffer does not have enough data. First serve all we've got. 76 if available > 0 { 77 copy(buf, in.buffer[in.bufferPosition:in.bufferPosition+available]) 78 buf = buf[available:] 79 in.bufferPosition += available 80 } 81 // and now, read the remaining 'len' bytes: 82 if length := len(buf); useBuffer && length < in.bufferSize { 83 // If the amount left to read is small enough, and 84 // we are allowed to use our buffer, do it in the usual 85 // buffered way: fill the buffer and copy from it: 86 if err := in.refill(); err != nil { 87 return err 88 } 89 if in.bufferLength < length { 90 // Throw an exception when refill() could not read len bytes: 91 copy(buf, in.buffer[0:in.bufferLength]) 92 return errors.New(fmt.Sprintf("read past EOF: %v", in)) 93 } else { 94 copy(buf, in.buffer[0:length]) 95 in.bufferPosition += length 96 } 97 } else { 98 // The amount left to read is larger than the buffer 99 // or we've been asked to not use our buffer - 100 // there's no performance reason not to read it all 101 // at once. Note that unlike the previous code of 102 // this function, there is no need to do a seek 103 // here, because there's no need to reread what we 104 // had in the buffer. 105 length := len(buf) 106 after := in.bufferStart + int64(in.bufferPosition) + int64(length) 107 if after > in.spi.Length() { 108 return errors.New(fmt.Sprintf("read past EOF: %v", in)) 109 } 110 if err := in.spi.readInternal(buf); err != nil { 111 return err 112 } 113 in.bufferStart = after 114 in.bufferPosition = 0 115 in.bufferLength = 0 // trigger refill() on read 116 } 117 } 118 return nil 119 } 120 121 func (in *BufferedIndexInput) ReadShort() (n int16, err error) { 122 if 2 <= in.bufferLength-in.bufferPosition { 123 in.bufferPosition += 2 124 return (int16(in.buffer[in.bufferPosition-2]) << 8) | int16(in.buffer[in.bufferPosition-1]), nil 125 } 126 return in.DataInputImpl.ReadShort() 127 } 128 129 func (in *BufferedIndexInput) ReadInt() (n int32, err error) { 130 if 4 <= in.bufferLength-in.bufferPosition { 131 // log.Print("Reading int from buffer...") 132 in.bufferPosition += 4 133 return (int32(in.buffer[in.bufferPosition-4]) << 24) | (int32(in.buffer[in.bufferPosition-3]) << 16) | 134 (int32(in.buffer[in.bufferPosition-2]) << 8) | int32(in.buffer[in.bufferPosition-1]), nil 135 } 136 return in.DataInputImpl.ReadInt() 137 } 138 139 func (in *BufferedIndexInput) ReadLong() (n int64, err error) { 140 if 8 <= in.bufferLength-in.bufferPosition { 141 in.bufferPosition += 4 142 i1 := (int64(in.buffer[in.bufferPosition-4]) << 24) | (int64(in.buffer[in.bufferPosition-3]) << 16) | 143 (int64(in.buffer[in.bufferPosition-2]) << 8) | int64(in.buffer[in.bufferPosition-1]) 144 in.bufferPosition += 4 145 i2 := (int64(in.buffer[in.bufferPosition-4]) << 24) | (int64(in.buffer[in.bufferPosition-3]) << 16) | 146 (int64(in.buffer[in.bufferPosition-2]) << 8) | int64(in.buffer[in.bufferPosition-1]) 147 return (i1 << 32) | i2, nil 148 } 149 return in.DataInputImpl.ReadLong() 150 } 151 152 func (in *BufferedIndexInput) ReadVInt() (n int32, err error) { 153 if 5 <= in.bufferLength-in.bufferPosition { 154 b := in.buffer[in.bufferPosition] 155 in.bufferPosition++ 156 if b < 128 { 157 return int32(b), nil 158 } 159 n := int32(b) & 0x7F 160 b = in.buffer[in.bufferPosition] 161 in.bufferPosition++ 162 n |= (int32(b) & 0x7F) << 7 163 if b < 128 { 164 return n, nil 165 } 166 b = in.buffer[in.bufferPosition] 167 in.bufferPosition++ 168 n |= (int32(b) & 0x7F) << 14 169 if b < 128 { 170 return n, nil 171 } 172 b = in.buffer[in.bufferPosition] 173 in.bufferPosition++ 174 n |= (int32(b) & 0x7F) << 21 175 if b < 128 { 176 return n, nil 177 } 178 b = in.buffer[in.bufferPosition] 179 in.bufferPosition++ 180 // Warning: the next ands use 0x0F / 0xF0 - beware copy/paste errors: 181 n |= (int32(b) & 0x0F) << 28 182 if (b & 0xF0) == 0 { 183 return n, nil 184 } 185 return 0, errors.New("Invalid vInt detected (too many bits)") 186 } 187 return in.DataInputImpl.ReadVInt() 188 } 189 190 func (in *BufferedIndexInput) ReadVLong() (n int64, err error) { 191 if 9 <= in.bufferLength-in.bufferPosition { 192 b := in.buffer[in.bufferPosition] 193 in.bufferPosition++ 194 if b < 128 { 195 return int64(b), nil 196 } 197 n := int64(b & 0x7F) 198 b = in.buffer[in.bufferPosition] 199 in.bufferPosition++ 200 n |= (int64(b&0x7F) << 7) 201 if b < 128 { 202 return n, nil 203 } 204 b = in.buffer[in.bufferPosition] 205 in.bufferPosition++ 206 n |= (int64(b&0x7F) << 14) 207 if b < 128 { 208 return n, nil 209 } 210 b = in.buffer[in.bufferPosition] 211 in.bufferPosition++ 212 n |= (int64(b&0x7F) << 21) 213 if b < 128 { 214 return n, nil 215 } 216 b = in.buffer[in.bufferPosition] 217 in.bufferPosition++ 218 n |= (int64(b&0x7F) << 28) 219 if b < 128 { 220 return n, nil 221 } 222 b = in.buffer[in.bufferPosition] 223 in.bufferPosition++ 224 n |= (int64(b&0x7F) << 35) 225 if b < 128 { 226 return n, nil 227 } 228 b = in.buffer[in.bufferPosition] 229 in.bufferPosition++ 230 n |= (int64(b&0x7F) << 42) 231 if b < 128 { 232 return n, nil 233 } 234 b = in.buffer[in.bufferPosition] 235 in.bufferPosition++ 236 n |= (int64(b&0x7F) << 49) 237 if b < 128 { 238 return n, nil 239 } 240 b = in.buffer[in.bufferPosition] 241 in.bufferPosition++ 242 n |= (int64(b&0x7F) << 56) 243 if b < 128 { 244 return n, nil 245 } 246 return 0, errors.New("Invalid vLong detected (negative values disallowed)") 247 } 248 return in.DataInputImpl.ReadVLong() 249 } 250 251 // use panic/recover to handle error 252 func (in *BufferedIndexInput) refill() error { 253 start := in.bufferStart + int64(in.bufferPosition) 254 end := start + int64(in.bufferSize) 255 if n := in.spi.Length(); end > n { // don't read past EOF 256 end = n 257 } 258 newLength := int(end - start) 259 if newLength <= 0 { 260 return errors.New(fmt.Sprintf("read past EOF: %v", in)) 261 } 262 263 if in.buffer == nil { 264 in.newBuffer(make([]byte, in.bufferSize)) // allocate buffer lazily 265 in.spi.seekInternal(int64(in.bufferStart)) 266 } 267 in.spi.readInternal(in.buffer[0:newLength]) 268 in.bufferLength = newLength 269 in.bufferStart = start 270 in.bufferPosition = 0 271 return nil 272 } 273 274 func (in *BufferedIndexInput) FilePointer() int64 { 275 return in.bufferStart + int64(in.bufferPosition) 276 } 277 278 func (in *BufferedIndexInput) Seek(pos int64) error { 279 if pos >= in.bufferStart && pos < in.bufferStart+int64(in.bufferLength) { 280 in.bufferPosition = int(pos - in.bufferStart) // seek within buffer 281 return nil 282 } else { 283 in.bufferStart = pos 284 in.bufferPosition = 0 285 in.bufferLength = 0 // trigger refill() on read() 286 return in.spi.seekInternal(pos) 287 } 288 } 289 290 func (in *BufferedIndexInput) Clone() *BufferedIndexInput { 291 ans := &BufferedIndexInput{ 292 bufferSize: in.bufferSize, 293 buffer: nil, 294 bufferStart: in.FilePointer(), 295 bufferLength: 0, 296 bufferPosition: 0, 297 } 298 ans.IndexInputImpl = NewIndexInputImpl(in.desc, ans) 299 return ans 300 } 301 302 func (in *BufferedIndexInput) Slice(desc string, offset, length int64) (IndexInput, error) { 303 panic("not implemented yet") 304 } 305 306 /* The default buffer size in bytes. */ 307 const DEFAULT_BUFFER_SIZE = 16384