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

Function grow

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

grow resizes the data to a larger length. Requirement: to > from. If the file ended in a partial block, we fetch it, grow it, and write it back.

(e sqlExecutor, inodeID, from, to uint64)

Source from the content-addressed store, hash-verified

121// If the file ended in a partial block, we fetch it, grow it,
122// and write it back.
123func grow(e sqlExecutor, inodeID, from, to uint64) error {
124 addRange := newBlockRange(from, to-from)
125 insertFrom := addRange.start
126
127 if addRange.startOffset > 0 {
128 // We need to extend the original 'last block'.
129 // Fetch it, grow it, and update it.
130 // TODO(marc): this would be more efficient if we had RPAD for bytes.
131 data, err := getBlockData(e, inodeID, addRange.start)
132 if err != nil {
133 return err
134 }
135 data = append(data, make([]byte, addRange.startLength, addRange.startLength)...)
136 if err := updateBlockData(e, inodeID, addRange.start, data); err != nil {
137 return err
138 }
139 // We don't need to insert this block.
140 insertFrom++
141 }
142
143 insertTo := addRange.last
144 if insertTo < insertFrom {
145 return nil
146 }
147
148 // Build the sql statement and blocks to insert.
149 // We don't share this functionality with 'write' because we can repeat empty blocks.
150 // This would be shorter if we weren't trying to be efficient.
151 // TODO(marc): this would also be better if we supported sparse files.
152 paramStrings := []string{}
153 params := []interface{}{}
154 count := 1 // placeholder count starts at 1.
155 if insertFrom != insertTo {
156 // We have full blocks. Only send a full block once.
157 for i := insertFrom; i < insertTo; i++ {
158 params = append(params, make([]byte, BlockSize, BlockSize))
159 }
160 count++
161 }
162
163 // Go over all blocks that are certainly full.
164 for i := insertFrom; i < insertTo; i++ {
165 paramStrings = append(paramStrings, fmt.Sprintf("(%d, %d, ?)", inodeID, i))
166 }
167
168 // Check the last block.
169 if addRange.lastLength > 0 {
170 // Not empty, write it. It can't be a full block, because we
171 // would have an empty block right after.
172 params = append(params, make([]byte, addRange.lastLength, addRange.lastLength))
173 paramStrings = append(paramStrings, fmt.Sprintf("(%d, %d, ?)",
174 inodeID, addRange.last))
175 count++
176 }
177
178 if len(paramStrings) == 0 {
179 // We had only one block, and it was empty. Nothing do to.
180 return nil

Callers 3

tryGrowFunction · 0.85
writeFunction · 0.85
resizeBlocksFunction · 0.85

Calls 4

newBlockRangeFunction · 0.85
getBlockDataFunction · 0.85
updateBlockDataFunction · 0.85
ExecMethod · 0.65

Tested by 1

tryGrowFunction · 0.68