MCPcopy Create free account
hub / github.com/git/git / table_iter_seek_linear

Function table_iter_seek_linear

reftable/table.c:270–354  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

268}
269
270static int table_iter_seek_linear(struct table_iter *ti,
271 struct reftable_record *want)
272{
273 struct reftable_buf want_key = REFTABLE_BUF_INIT;
274 struct reftable_buf got_key = REFTABLE_BUF_INIT;
275 struct reftable_record rec;
276 int err;
277
278 err = reftable_record_init(&rec, reftable_record_type(want));
279 if (err < 0)
280 goto done;
281
282 err = reftable_record_key(want, &want_key);
283 if (err < 0)
284 goto done;
285
286 /*
287 * First we need to locate the block that must contain our record. To
288 * do so we scan through blocks linearly until we find the first block
289 * whose first key is bigger than our wanted key. Once we have found
290 * that block we know that the key must be contained in the preceding
291 * block.
292 *
293 * This algorithm is somewhat unfortunate because it means that we
294 * always have to seek one block too far and then back up. But as we
295 * can only decode the _first_ key of a block but not its _last_ key we
296 * have no other way to do this.
297 */
298 while (1) {
299 struct table_iter next = *ti;
300
301 /*
302 * We must be careful to not modify underlying data of `ti`
303 * because we may find that `next` does not contain our desired
304 * block, but that `ti` does. In that case, we would discard
305 * `next` and continue with `ti`.
306 *
307 * This also means that we cannot reuse allocated memory for
308 * `next` here. While it would be great if we could, it should
309 * in practice not be too bad given that we should only ever
310 * end up doing linear seeks with at most three blocks. As soon
311 * as we have more than three blocks we would have an index, so
312 * we would not do a linear search there anymore.
313 */
314 memset(&next.block.block_data, 0, sizeof(next.block.block_data));
315 next.block.zstream = NULL;
316 next.block.uncompressed_data = NULL;
317 next.block.uncompressed_cap = 0;
318
319 err = table_iter_next_block(&next);
320 if (err < 0)
321 goto done;
322 if (err > 0)
323 break;
324
325 err = reftable_block_first_key(&next.block, &got_key);
326 if (err < 0)
327 goto done;

Callers 2

table_iter_seek_indexedFunction · 0.85
table_iter_seekFunction · 0.85

Calls 11

reftable_record_initFunction · 0.85
reftable_record_typeFunction · 0.85
reftable_record_keyFunction · 0.85
table_iter_next_blockFunction · 0.85
reftable_block_first_keyFunction · 0.85
reftable_buf_cmpFunction · 0.85
table_iter_block_doneFunction · 0.85
block_iter_initFunction · 0.85
block_iter_seek_keyFunction · 0.85
reftable_record_releaseFunction · 0.85
reftable_buf_releaseFunction · 0.85

Tested by

no test coverage detected