mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 19:01:57 -04:00
Avoid to recompute the block status multiple times
Store it in a bit vector and reuse the result.
This commit is contained in:
parent
f0a5268d32
commit
2a5b5499c4
7 changed files with 59 additions and 31 deletions
|
|
@ -869,6 +869,7 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
|
|||
unsigned l;
|
||||
char esc_buffer[ESC_MAX];
|
||||
char esc_buffer_alt[ESC_MAX];
|
||||
bit_vect_t* block_enabled;
|
||||
|
||||
handle = handle_mapping(state, &diskmax);
|
||||
|
||||
|
|
@ -894,9 +895,11 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
|
|||
|
||||
/* first count the number of blocks to process */
|
||||
countmax = 0;
|
||||
block_enabled = calloc_nofail(1, bit_vect_size(blockmax)); /* preinitialize to 0 */
|
||||
for (i = blockstart; i < blockmax; ++i) {
|
||||
if (!block_is_enabled(state, i, handle, diskmax))
|
||||
continue;
|
||||
bit_vect_set(block_enabled, i);
|
||||
++countmax;
|
||||
}
|
||||
|
||||
|
|
@ -918,7 +921,7 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna
|
|||
snapraid_info info;
|
||||
int rehash;
|
||||
|
||||
if (!block_is_enabled(state, i, handle, diskmax)) {
|
||||
if (!bit_vect_test(block_enabled, i)) {
|
||||
/* post process the files */
|
||||
ret = file_post(state, fix, i, handle, diskmax);
|
||||
if (ret == -1) {
|
||||
|
|
@ -1916,6 +1919,7 @@ bail:
|
|||
|
||||
free(failed);
|
||||
free(failed_map);
|
||||
free(block_enabled);
|
||||
free(handle);
|
||||
free(buffer_alloc);
|
||||
free(buffer);
|
||||
|
|
|
|||
|
|
@ -28,17 +28,6 @@
|
|||
/****************************************************************************/
|
||||
/* dry */
|
||||
|
||||
/**
|
||||
* Check if we have to process the specified block index ::i.
|
||||
*/
|
||||
static int block_is_enabled(void* void_plan, block_off_t i)
|
||||
{
|
||||
(void)void_plan;
|
||||
(void)i;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void dry_data_reader(struct snapraid_worker* worker, struct snapraid_task* task)
|
||||
{
|
||||
struct snapraid_io* io = worker->io;
|
||||
|
|
@ -208,7 +197,7 @@ static int state_dry_process(struct snapraid_state* state, struct snapraid_parit
|
|||
countpos = 0;
|
||||
|
||||
/* start all the worker threads */
|
||||
io_start(&io, blockstart, blockmax, &block_is_enabled, 0);
|
||||
io_start(&io, blockstart, blockmax, 0);
|
||||
|
||||
state_progress_begin(state, blockstart, blockmax, countmax);
|
||||
while (1) {
|
||||
|
|
|
|||
18
cmdline/io.c
18
cmdline/io.c
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
void (*io_start)(struct snapraid_io* io,
|
||||
block_off_t blockstart, block_off_t blockmax,
|
||||
int (*block_is_enabled)(void* arg, block_off_t), void* blockarg) = 0;
|
||||
bit_vect_t* block_enabled) = 0;
|
||||
void (*io_stop)(struct snapraid_io* io) = 0;
|
||||
block_off_t (*io_read_next)(struct snapraid_io* io, void*** buffer) = 0;
|
||||
struct snapraid_task* (*io_data_read)(struct snapraid_io* io, unsigned* diskcur, unsigned* waiting_map, unsigned* waiting_mac) = 0;
|
||||
|
|
@ -40,8 +40,10 @@ static block_off_t io_position_next(struct snapraid_io* io)
|
|||
block_off_t blockcur;
|
||||
|
||||
/* get the next position */
|
||||
while (io->block_next < io->block_max && !io->block_is_enabled(io->block_arg, io->block_next))
|
||||
++io->block_next;
|
||||
if (io->block_enabled) {
|
||||
while (io->block_next < io->block_max && !bit_vect_test(io->block_enabled, io->block_next))
|
||||
++io->block_next;
|
||||
}
|
||||
|
||||
blockcur = io->block_next;
|
||||
|
||||
|
|
@ -257,12 +259,11 @@ static void io_parity_write_mono(struct snapraid_io* io, unsigned* pos, unsigned
|
|||
|
||||
static void io_start_mono(struct snapraid_io* io,
|
||||
block_off_t blockstart, block_off_t blockmax,
|
||||
int (*block_is_enabled)(void* arg, block_off_t), void* blockarg)
|
||||
bit_vect_t* block_enabled)
|
||||
{
|
||||
io->block_start = blockstart;
|
||||
io->block_max = blockmax;
|
||||
io->block_is_enabled = block_is_enabled;
|
||||
io->block_arg = blockarg;
|
||||
io->block_enabled = block_enabled;
|
||||
io->block_next = blockstart;
|
||||
}
|
||||
|
||||
|
|
@ -767,7 +768,7 @@ static void* io_writer_thread(void* arg)
|
|||
|
||||
static void io_start_thread(struct snapraid_io* io,
|
||||
block_off_t blockstart, block_off_t blockmax,
|
||||
int (*block_is_enabled)(void* arg, block_off_t), void* blockarg)
|
||||
bit_vect_t* block_enabled)
|
||||
{
|
||||
unsigned i;
|
||||
tommy_node* j;
|
||||
|
|
@ -780,8 +781,7 @@ static void io_start_thread(struct snapraid_io* io,
|
|||
|
||||
io->block_start = blockstart;
|
||||
io->block_max = blockmax;
|
||||
io->block_is_enabled = block_is_enabled;
|
||||
io->block_arg = blockarg;
|
||||
io->block_enabled = block_enabled;
|
||||
io->block_next = blockstart;
|
||||
|
||||
io->done = 0;
|
||||
|
|
|
|||
|
|
@ -217,8 +217,7 @@ struct snapraid_io {
|
|||
block_off_t block_start;
|
||||
block_off_t block_max;
|
||||
block_off_t block_next;
|
||||
int (*block_is_enabled)(void* arg, block_off_t);
|
||||
void* block_arg;
|
||||
bit_vect_t* block_enabled;
|
||||
|
||||
/**
|
||||
* Buffers for data.
|
||||
|
|
@ -315,7 +314,7 @@ void io_done(struct snapraid_io* io);
|
|||
*/
|
||||
extern void (*io_start)(struct snapraid_io* io,
|
||||
block_off_t blockstart, block_off_t blockmax,
|
||||
int (*block_is_enabled)(void* arg, block_off_t), void* blockarg);
|
||||
bit_vect_t* block_enabled);
|
||||
|
||||
/**
|
||||
* Stop all the worker threads.
|
||||
|
|
|
|||
|
|
@ -50,9 +50,8 @@ struct snapraid_plan {
|
|||
/**
|
||||
* Check if we have to process the specified block index ::i.
|
||||
*/
|
||||
static int block_is_enabled(void* void_plan, block_off_t i)
|
||||
static int block_is_enabled(struct snapraid_plan* plan, block_off_t i)
|
||||
{
|
||||
struct snapraid_plan* plan = void_plan;
|
||||
time_t blocktime;
|
||||
snapraid_info info;
|
||||
|
||||
|
|
@ -268,6 +267,7 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par
|
|||
unsigned* waiting_map;
|
||||
unsigned waiting_mac;
|
||||
char esc_buffer[ESC_MAX];
|
||||
bit_vect_t* block_enabled;
|
||||
|
||||
/* maps the disks to handles */
|
||||
handle = handle_mapping(state, &diskmax);
|
||||
|
|
@ -294,9 +294,11 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par
|
|||
/* first count the number of blocks to process */
|
||||
countmax = 0;
|
||||
plan->countlast = 0;
|
||||
block_enabled = calloc_nofail(1, bit_vect_size(blockmax)); /* preinitialize to 0 */
|
||||
for (blockcur = blockstart; blockcur < blockmax; ++blockcur) {
|
||||
if (!block_is_enabled(plan, blockcur))
|
||||
continue;
|
||||
bit_vect_set(block_enabled, blockcur);
|
||||
++countmax;
|
||||
}
|
||||
|
||||
|
|
@ -317,7 +319,7 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par
|
|||
msg_progress("Scrubbing...\n");
|
||||
|
||||
/* start all the worker threads */
|
||||
io_start(&io, blockstart, blockmax, &block_is_enabled, plan);
|
||||
io_start(&io, blockstart, blockmax, block_enabled);
|
||||
|
||||
state_progress_begin(state, blockstart, blockmax, countmax);
|
||||
while (1) {
|
||||
|
|
@ -704,6 +706,7 @@ bail:
|
|||
free(rehandle_alloc);
|
||||
free(waiting_map);
|
||||
io_done(&io);
|
||||
free(block_enabled);
|
||||
|
||||
if (state->opt.expect_recoverable) {
|
||||
if (error + silent_error + io_error == 0)
|
||||
|
|
|
|||
|
|
@ -440,9 +440,8 @@ struct snapraid_rehash {
|
|||
/**
|
||||
* Check if we have to process the specified block index ::i.
|
||||
*/
|
||||
static int block_is_enabled(void* void_plan, block_off_t i)
|
||||
static int block_is_enabled(struct snapraid_plan* plan, block_off_t i)
|
||||
{
|
||||
struct snapraid_plan* plan = void_plan;
|
||||
unsigned j;
|
||||
int one_invalid;
|
||||
int one_valid;
|
||||
|
|
@ -693,6 +692,7 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
|
|||
unsigned* waiting_map;
|
||||
unsigned waiting_mac;
|
||||
char esc_buffer[ESC_MAX];
|
||||
bit_vect_t* block_enabled;
|
||||
|
||||
/* the sync process assumes that all the hashes are correct */
|
||||
/* including the ones from CHG and DELETED blocks */
|
||||
|
|
@ -739,9 +739,11 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
|
|||
plan.handle_max = diskmax;
|
||||
plan.handle_map = handle;
|
||||
plan.force_full = state->opt.force_full;
|
||||
block_enabled = calloc_nofail(1, bit_vect_size(blockmax)); /* preinitialize to 0 */
|
||||
for (blockcur = blockstart; blockcur < blockmax; ++blockcur) {
|
||||
if (!block_is_enabled(&plan, blockcur))
|
||||
continue;
|
||||
bit_vect_set(block_enabled, blockcur);
|
||||
++countmax;
|
||||
}
|
||||
|
||||
|
|
@ -761,7 +763,7 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
|
|||
msg_progress("Syncing...\n");
|
||||
|
||||
/* start all the worker threads */
|
||||
io_start(&io, blockstart, blockmax, &block_is_enabled, &plan);
|
||||
io_start(&io, blockstart, blockmax, block_enabled);
|
||||
|
||||
if (!state_progress_begin(state, blockstart, blockmax, countmax))
|
||||
goto end;
|
||||
|
|
@ -1417,6 +1419,7 @@ bail:
|
|||
free(failed_map);
|
||||
free(waiting_map);
|
||||
io_done(&io);
|
||||
free(block_enabled);
|
||||
|
||||
if (state->opt.expect_recoverable) {
|
||||
if (error + silent_error + io_error == 0)
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#ifndef __UTIL_H
|
||||
#define __UTIL_H
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* memory */
|
||||
|
||||
|
|
@ -221,5 +222,34 @@ int lock_lock(const char* file);
|
|||
*/
|
||||
int lock_unlock(int f);
|
||||
|
||||
/****************************************************************************/
|
||||
/* bitvect */
|
||||
|
||||
typedef unsigned char bit_vect_t;
|
||||
#define BIT_VECT_SIZE (sizeof(bit_vect_t) * 8)
|
||||
|
||||
static inline size_t bit_vect_size(size_t max)
|
||||
{
|
||||
return (max + BIT_VECT_SIZE - 1) / BIT_VECT_SIZE;
|
||||
}
|
||||
|
||||
static inline void bit_vect_set(bit_vect_t* bit_vect, size_t off)
|
||||
{
|
||||
bit_vect_t mask = 1 << (off % BIT_VECT_SIZE);
|
||||
bit_vect[off / BIT_VECT_SIZE] |= mask;
|
||||
}
|
||||
|
||||
static inline void bit_vect_clear(bit_vect_t* bit_vect, size_t off)
|
||||
{
|
||||
bit_vect_t mask = 1 << (off % BIT_VECT_SIZE);
|
||||
bit_vect[off / BIT_VECT_SIZE] &= ~mask;
|
||||
}
|
||||
|
||||
static inline int bit_vect_test(bit_vect_t* bit_vect, size_t off)
|
||||
{
|
||||
bit_vect_t mask = 1 << (off % BIT_VECT_SIZE);
|
||||
return (bit_vect[off / BIT_VECT_SIZE] & mask) != 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue