github.com/Schaudge/grailbase@v0.0.0-20240223061707-44c758a471c0/recordio/estimate.go (about) 1 package recordio 2 3 import ( 4 "encoding/binary" 5 6 "github.com/Schaudge/grailbase/recordio/internal" 7 ) 8 9 // RequiredSpaceUpperBound returns an upper bound on the space required to 10 // store n items of itemSizes for a specified record size. 11 func RequiredSpaceUpperBound(itemSizes []int64, recordSize int64) int64 { 12 13 // Max number of chunks required per record. 14 // reqChunksPerRecord is Ceil(recordSize / internal.MaxChunkPayloadSize) 15 reqChunksPerRecord := recordSize / internal.MaxChunkPayloadSize 16 if (recordSize % internal.MaxChunkPayloadSize) != 0 { 17 reqChunksPerRecord++ 18 } 19 20 // Max payload = UpperBound(header) + payload. 21 // 1 varint for # items, n for the size of each of n items. 22 // Using binary.MaxVarintLen64 since we want an upper bound. 23 hdrSizeUBound := (len(itemSizes) + 1) * binary.MaxVarintLen64 24 maxPayload := int64(hdrSizeUBound) 25 for _, s := range itemSizes { 26 maxPayload += s 27 } 28 29 // Max number of records required for payload. 30 // reqRecordsForPayload is Ceil(maxPayload / recordSize) 31 reqRecordsForPayload := maxPayload / recordSize 32 if (maxPayload % recordSize) != 0 { 33 reqRecordsForPayload++ 34 } 35 36 // Max number of chunks required = chunks for payload + 2 chunks for header and trailer. 37 reqChunksForPayload := (reqChunksPerRecord * reqRecordsForPayload) + int64(2) 38 39 // Upper bound on the space required. 40 return reqChunksForPayload * internal.ChunkSize 41 }