MCPcopy Index your code
hub / github.com/CovenantSQL/CovenantSQL / write

Function write

cmd/cql-fuse/block.go:228–347  ·  view source on GitHub ↗

write commits data to the blocks starting at 'offset' Amount of data to write must be non-zero. If offset is greated than 'originalSize', the file is grown first. We always write all or nothing.

(e sqlExecutor, inodeID, originalSize, offset uint64, data []byte)

Source from the content-addressed store, hash-verified

226// If offset is greated than 'originalSize', the file is grown first.
227// We always write all or nothing.
228func write(e sqlExecutor, inodeID, originalSize, offset uint64, data []byte) error {
229 if offset > originalSize {
230 diff := offset - originalSize
231 if diff > BlockSize*2 {
232 // we need to grow the file by at least two blocks. Use growing method
233 // which only sends empty blocks once.
234 if err := grow(e, inodeID, originalSize, offset); err != nil {
235 return err
236 }
237 originalSize = offset
238 } else if diff > 0 {
239 // don't grow the file first, just change what we need to write.
240 data = append(make([]byte, diff, diff), data...)
241 offset = originalSize
242 }
243 }
244
245 // Now we know that offset is <= originalSize.
246 writeRange := newBlockRange(offset, uint64(len(data)))
247 writeFrom := writeRange.start
248
249 if writeRange.startOffset > 0 {
250 // We're partially overwriting a block (this includes appending
251 // to the last block): fetch it, grow it, and update it.
252 // TODO(marc): this would be more efficient if we had RPAD for bytes.
253 blockData, err := getBlockData(e, inodeID, writeRange.start)
254 if err != nil {
255 return err
256 }
257 blockData = append(blockData[:writeRange.startOffset], data[:writeRange.startLength]...)
258 data = data[writeRange.startLength:]
259 if err := updateBlockData(e, inodeID, writeRange.start, blockData); err != nil {
260 return err
261 }
262 // We don't need to insert this block.
263 writeFrom++
264 }
265
266 writeTo := writeRange.last
267 if writeRange.lastLength == 0 {
268 // Last block is empty, don't update/insert it.
269 writeTo--
270 }
271 if writeTo < writeFrom {
272 return nil
273 }
274
275 // Figure out last existing block. Needed to tell the difference
276 // between insert and update.
277 lastBlock := int(originalSize / BlockSize)
278 if originalSize%BlockSize == 0 {
279 // Empty blocks do not exist (size=0 -> lastblock=-1).
280 lastBlock--
281 }
282
283 // Process updates first.
284 for i := writeFrom; i <= writeTo; i++ {
285 if i > lastBlock {

Callers 3

BenchmarkStorageFunction · 0.85
WriteMethod · 0.85
TestReadWriteBlocksFunction · 0.85

Calls 6

growFunction · 0.85
newBlockRangeFunction · 0.85
getBlockDataFunction · 0.85
updateBlockDataFunction · 0.85
minFunction · 0.85
ExecMethod · 0.65

Tested by 2

BenchmarkStorageFunction · 0.68
TestReadWriteBlocksFunction · 0.68