@ -712,7 +712,7 @@ func (t *freezerTable) RetrieveItems(start, count, maxBytes uint64) ([][]byte, e
if ! t . noCompression {
if ! t . noCompression {
decompressedSize , _ = snappy . DecodedLen ( item )
decompressedSize , _ = snappy . DecodedLen ( item )
}
}
if i > 0 && uint64 ( outputSize + decompressedSize ) > maxBytes {
if i > 0 && maxBytes != 0 && uint64 ( outputSize + decompressedSize ) > maxBytes {
break
break
}
}
if ! t . noCompression {
if ! t . noCompression {
@ -730,8 +730,10 @@ func (t *freezerTable) RetrieveItems(start, count, maxBytes uint64) ([][]byte, e
}
}
// retrieveItems reads up to 'count' items from the table. It reads at least
// retrieveItems reads up to 'count' items from the table. It reads at least
// one item, but otherwise avoids reading more than maxBytes bytes.
// one item, but otherwise avoids reading more than maxBytes bytes. Freezer
// It returns the (potentially compressed) data, and the sizes.
// will ignore the size limitation and continuously allocate memory to store
// data if maxBytes is 0. It returns the (potentially compressed) data, and
// the sizes.
func ( t * freezerTable ) retrieveItems ( start , count , maxBytes uint64 ) ( [ ] byte , [ ] int , error ) {
func ( t * freezerTable ) retrieveItems ( start , count , maxBytes uint64 ) ( [ ] byte , [ ] int , error ) {
t . lock . RLock ( )
t . lock . RLock ( )
defer t . lock . RUnlock ( )
defer t . lock . RUnlock ( )
@ -752,25 +754,22 @@ func (t *freezerTable) retrieveItems(start, count, maxBytes uint64) ([]byte, []i
if start + count > items {
if start + count > items {
count = items - start
count = items - start
}
}
var (
var output [ ] byte // Buffer to read data into
output = make ( [ ] byte , maxBytes ) // Buffer to read data into
if maxBytes != 0 {
outputSize int // Used size of that buffer
output = make ( [ ] byte , 0 , maxBytes )
)
} else {
output = make ( [ ] byte , 0 , 1024 ) // initial buffer cap
}
// readData is a helper method to read a single data item from disk.
// readData is a helper method to read a single data item from disk.
readData := func ( fileId , start uint32 , length int ) error {
readData := func ( fileId , start uint32 , length int ) error {
// In case a small limit is used, and the elements are large, may need to
output = grow ( output , length )
// realloc the read-buffer when reading the first (and only) item.
if len ( output ) < length {
output = make ( [ ] byte , length )
}
dataFile , exist := t . files [ fileId ]
dataFile , exist := t . files [ fileId ]
if ! exist {
if ! exist {
return fmt . Errorf ( "missing data file %d" , fileId )
return fmt . Errorf ( "missing data file %d" , fileId )
}
}
if _ , err := dataFile . ReadAt ( output [ outputSize : outputSize + length ] , int64 ( start ) ) ; err != nil {
if _ , err := dataFile . ReadAt ( output [ len ( output ) - length : ] , int64 ( start ) ) ; err != nil {
return err
return err
}
}
outputSize += length
return nil
return nil
}
}
// Read all the indexes in one go
// Read all the indexes in one go
@ -801,7 +800,7 @@ func (t *freezerTable) retrieveItems(start, count, maxBytes uint64) ([]byte, []i
}
}
readStart = 0
readStart = 0
}
}
if i > 0 && uint64 ( totalSize + size ) > maxBytes {
if i > 0 && uint64 ( totalSize + size ) > maxBytes && maxBytes != 0 {
// About to break out due to byte limit being exceeded. We don't
// About to break out due to byte limit being exceeded. We don't
// read this last item, but we need to do the deferred reads now.
// read this last item, but we need to do the deferred reads now.
if unreadSize > 0 {
if unreadSize > 0 {
@ -815,7 +814,7 @@ func (t *freezerTable) retrieveItems(start, count, maxBytes uint64) ([]byte, []i
unreadSize += size
unreadSize += size
totalSize += size
totalSize += size
sizes = append ( sizes , size )
sizes = append ( sizes , size )
if i == len ( indices ) - 2 || uint64 ( totalSize ) > maxBytes {
if i == len ( indices ) - 2 || ( uint64 ( totalSize ) > maxBytes && maxBytes != 0 ) {
// Last item, need to do the read now
// Last item, need to do the read now
if err := readData ( secondIndex . filenum , readStart , unreadSize ) ; err != nil {
if err := readData ( secondIndex . filenum , readStart , unreadSize ) ; err != nil {
return nil , nil , err
return nil , nil , err
@ -826,7 +825,7 @@ func (t *freezerTable) retrieveItems(start, count, maxBytes uint64) ([]byte, []i
// Update metrics.
// Update metrics.
t . readMeter . Mark ( int64 ( totalSize ) )
t . readMeter . Mark ( int64 ( totalSize ) )
return output [ : outputSize ] , sizes , nil
return output , sizes , nil
}
}
// has returns an indicator whether the specified number data is still accessible
// has returns an indicator whether the specified number data is still accessible