mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-25 18:40:19 -04:00
Process content info values in contiguous runs
This commit is contained in:
parent
62ef259edc
commit
e45e467b1a
3 changed files with 125 additions and 19 deletions
|
|
@ -1395,6 +1395,80 @@ static inline snapraid_info info_get(tommy_arrayblkof* array, block_off_t pos)
|
|||
return info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a run of info values.
|
||||
*
|
||||
* Grow the array once and process each internal block directly, avoiding the
|
||||
* per-position grow and lookup performed by info_set().
|
||||
*/
|
||||
static inline void info_set_run(tommy_arrayblkof* array, block_off_t pos, block_off_t count, snapraid_info info)
|
||||
{
|
||||
tommy_arrayblkof_grow(array, pos + count);
|
||||
|
||||
while (count) {
|
||||
block_off_t offset = pos % TOMMY_ARRAYBLKOF_SIZE;
|
||||
block_off_t run = TOMMY_ARRAYBLKOF_SIZE - offset;
|
||||
snapraid_info* data;
|
||||
block_off_t i;
|
||||
|
||||
if (run > count)
|
||||
run = count;
|
||||
|
||||
data = tommy_arrayblkof_ref(array, pos);
|
||||
for (i = 0; i < run; ++i)
|
||||
data[i] = info;
|
||||
|
||||
pos += run;
|
||||
count -= run;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value and length of an info run, up to count positions.
|
||||
*
|
||||
* Unallocated positions have the same zero value returned by info_get().
|
||||
* Process allocated storage a block at a time to avoid resolving every array
|
||||
* position independently.
|
||||
*/
|
||||
static inline block_off_t info_get_run(tommy_arrayblkof* array, block_off_t pos, block_off_t count, snapraid_info* info)
|
||||
{
|
||||
block_off_t size = tommy_arrayblkof_size(array);
|
||||
block_off_t total = 0;
|
||||
|
||||
if (pos >= size) {
|
||||
*info = 0;
|
||||
return count;
|
||||
}
|
||||
|
||||
memcpy(info, tommy_arrayblkof_ref(array, pos), sizeof(snapraid_info));
|
||||
|
||||
while (total < count && pos + total < size) {
|
||||
block_off_t current = pos + total;
|
||||
block_off_t offset = current % TOMMY_ARRAYBLKOF_SIZE;
|
||||
block_off_t run = TOMMY_ARRAYBLKOF_SIZE - offset;
|
||||
snapraid_info* data;
|
||||
block_off_t i;
|
||||
|
||||
if (run > count - total)
|
||||
run = count - total;
|
||||
if (run > size - current)
|
||||
run = size - current;
|
||||
|
||||
data = tommy_arrayblkof_ref(array, current);
|
||||
for (i = 0; i < run; ++i)
|
||||
if (data[i] != *info)
|
||||
return total + i;
|
||||
|
||||
total += run;
|
||||
}
|
||||
|
||||
/* info_get() returns zero for the whole unallocated tail */
|
||||
if (total < count && *info == 0)
|
||||
return count;
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* bucket */
|
||||
|
||||
|
|
|
|||
|
|
@ -600,6 +600,50 @@ bail:
|
|||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
static void test_info_run(void)
|
||||
{
|
||||
tommy_arrayblkof array;
|
||||
const block_off_t start = TOMMY_ARRAYBLKOF_SIZE - 2;
|
||||
const block_off_t count = TOMMY_ARRAYBLKOF_SIZE + 4;
|
||||
const snapraid_info first = 0x100;
|
||||
const snapraid_info second = 0x200;
|
||||
snapraid_info info;
|
||||
|
||||
tommy_arrayblkof_init(&array, sizeof(snapraid_info));
|
||||
|
||||
/* check an entirely unallocated zero run */
|
||||
if (info_get_run(&array, 0, count, &info) != count || info != 0)
|
||||
goto bail;
|
||||
|
||||
/* cross two internal array block boundaries */
|
||||
info_set_run(&array, start, count, first);
|
||||
if (info_get_run(&array, 0, start + count, &info) != start || info != 0)
|
||||
goto bail;
|
||||
if (info_get_run(&array, start, count + 1, &info) != count || info != first)
|
||||
goto bail;
|
||||
if (info_get_run(&array, start + count, count, &info) != count || info != 0)
|
||||
goto bail;
|
||||
|
||||
/* split the first run without changing the allocated size */
|
||||
info_set_run(&array, start + 100, 10, second);
|
||||
if (info_get_run(&array, start, count, &info) != 100 || info != first)
|
||||
goto bail;
|
||||
if (info_get_run(&array, start + 100, count, &info) != 10 || info != second)
|
||||
goto bail;
|
||||
if (info_get_run(&array, start + 110, count, &info) != count - 110 || info != first)
|
||||
goto bail;
|
||||
|
||||
tommy_arrayblkof_done(&array);
|
||||
return;
|
||||
|
||||
bail:
|
||||
/* LCOV_EXCL_START */
|
||||
tommy_arrayblkof_done(&array);
|
||||
log_fatal(EINTERNAL, "Failed info run test\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
struct {
|
||||
const char* pattern;
|
||||
const char* text;
|
||||
|
|
@ -2492,6 +2536,7 @@ void selftest(void)
|
|||
|
||||
/* tommyds data structures (hash tables, lists, search, sort) */
|
||||
test_tommy();
|
||||
test_info_run();
|
||||
|
||||
/* cauchy raid module self-test */
|
||||
raid_mode(RAID_MODE_CAUCHY_RAID);
|
||||
|
|
|
|||
|
|
@ -2772,14 +2772,9 @@ static void state_read_content(struct snapraid_state* state, const char* path, S
|
|||
|
||||
bucket_insert(&bucket_hash, t64 + v_oldest, v_count, justsynced);
|
||||
|
||||
while (v_count) {
|
||||
/* insert the info in the array */
|
||||
info_set(&state->infoarr, v_pos, info);
|
||||
|
||||
/* go to next block */
|
||||
++v_pos;
|
||||
--v_count;
|
||||
}
|
||||
/* insert the complete run in the info array */
|
||||
info_set_run(&state->infoarr, v_pos, v_count, info);
|
||||
v_pos += v_count;
|
||||
} else {
|
||||
while (v_count) {
|
||||
/* ensure that an info is present only for used positions */
|
||||
|
|
@ -4405,17 +4400,9 @@ static void* state_write_thread(void* arg)
|
|||
time_t t;
|
||||
unsigned flag;
|
||||
|
||||
info = info_get(&state->infoarr, begin);
|
||||
|
||||
/* find the end of run of blocks */
|
||||
end = begin + 1;
|
||||
while (end < blockmax
|
||||
&& info == info_get(&state->infoarr, end)
|
||||
) {
|
||||
++end;
|
||||
}
|
||||
|
||||
count = end - begin;
|
||||
/* find the complete run without resolving each array position */
|
||||
count = info_get_run(&state->infoarr, begin, blockmax - begin, &info);
|
||||
end = begin + count;
|
||||
sputb64(count, f);
|
||||
|
||||
/* if there is info */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue