mirror of
https://github.com/netsurf-browser/netsurf
synced 2024-11-28 09:13:08 +03:00
allocate small block using block use bitmaps to find free entries.
This commit is contained in:
parent
83fa13b315
commit
9eeae4dd49
@ -100,7 +100,6 @@
|
|||||||
/** length in bytes of a block files use map */
|
/** length in bytes of a block files use map */
|
||||||
#define BLOCK_USE_MAP_SIZE (1 << (BLOCK_ENTRY_COUNT - 3))
|
#define BLOCK_USE_MAP_SIZE (1 << (BLOCK_ENTRY_COUNT - 3))
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type used to store index values refering to store entries. Care
|
* The type used to store index values refering to store entries. Care
|
||||||
* must be taken with this type as it is used to build address to
|
* must be taken with this type as it is used to build address to
|
||||||
@ -204,6 +203,11 @@ struct block_file {
|
|||||||
uint8_t use_map[BLOCK_USE_MAP_SIZE];
|
uint8_t use_map[BLOCK_USE_MAP_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const unsigned int log2_block_size[] = {
|
||||||
|
BLOCK_DATA_SIZE,
|
||||||
|
BLOCK_META_SIZE
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parameters controlling the backing store.
|
* Parameters controlling the backing store.
|
||||||
*/
|
*/
|
||||||
@ -831,6 +835,36 @@ get_store_entry(struct store_state *state, nsurl *url, struct store_entry **bse)
|
|||||||
return NSERROR_OK;
|
return NSERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find next available small block.
|
||||||
|
*/
|
||||||
|
static block_index_t alloc_block(struct store_state *state, int elem_idx)
|
||||||
|
{
|
||||||
|
int bf;
|
||||||
|
int idx;
|
||||||
|
int bit;
|
||||||
|
uint8_t *map;
|
||||||
|
|
||||||
|
for (bf = 0; bf < BLOCK_FILE_COUNT; bf++) {
|
||||||
|
map = &state->blocks[elem_idx][bf].use_map[0];
|
||||||
|
|
||||||
|
for (idx = 0; idx < BLOCK_USE_MAP_SIZE; idx++) {
|
||||||
|
if (*(map + idx) != 0xff) {
|
||||||
|
/* located an unused block */
|
||||||
|
for (bit = 0; bit < 8;bit++) {
|
||||||
|
if (((*(map + idx)) & (1U << bit)) == 0) {
|
||||||
|
/* mark block as used */
|
||||||
|
*(map + idx) |= 1U << bit;
|
||||||
|
state->blocks_dirty = true;
|
||||||
|
return (((bf * BLOCK_USE_MAP_SIZE) + idx) * 8) + bit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a backing store entry in the entry table from a url.
|
* Set a backing store entry in the entry table from a url.
|
||||||
@ -931,6 +965,12 @@ set_store_entry(struct store_state *state,
|
|||||||
elem->size = datalen;
|
elem->size = datalen;
|
||||||
state->total_alloc += elem->size;
|
state->total_alloc += elem->size;
|
||||||
|
|
||||||
|
/* if the elemnt will fit in a small block attempt to allocate one */
|
||||||
|
if (elem->size <= (1U << log2_block_size[elem_idx])) {
|
||||||
|
elem->block = alloc_block(state, elem_idx);
|
||||||
|
LOG(("Using block %d", elem->block));
|
||||||
|
}
|
||||||
|
|
||||||
/* ensure control maintinance scheduled. */
|
/* ensure control maintinance scheduled. */
|
||||||
state->entries_dirty = true;
|
state->entries_dirty = true;
|
||||||
guit->browser->schedule(CONTROL_MAINT_TIME, control_maintinance, state);
|
guit->browser->schedule(CONTROL_MAINT_TIME, control_maintinance, state);
|
||||||
@ -1134,6 +1174,8 @@ read_blocks(struct store_state *state)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOG(("Initialising block use map from %s", fname));
|
||||||
|
|
||||||
fd = open(fname, O_RDWR);
|
fd = open(fname, O_RDWR);
|
||||||
free(fname);
|
free(fname);
|
||||||
if (fd != -1) {
|
if (fd != -1) {
|
||||||
@ -1153,6 +1195,7 @@ read_blocks(struct store_state *state)
|
|||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
LOG(("Initialising block use map to defaults"));
|
||||||
/* ensure block 0 (invalid sentinal) is skipped */
|
/* ensure block 0 (invalid sentinal) is skipped */
|
||||||
state->blocks[ENTRY_ELEM_DATA][0].use_map[0] = 1;
|
state->blocks[ENTRY_ELEM_DATA][0].use_map[0] = 1;
|
||||||
state->blocks[ENTRY_ELEM_META][0].use_map[0] = 1;
|
state->blocks[ENTRY_ELEM_META][0].use_map[0] = 1;
|
||||||
@ -1458,11 +1501,23 @@ initialise(const struct llcache_store_parameters *parameters)
|
|||||||
static nserror
|
static nserror
|
||||||
finalise(void)
|
finalise(void)
|
||||||
{
|
{
|
||||||
|
int bf; /* block file index */
|
||||||
|
|
||||||
if (storestate != NULL) {
|
if (storestate != NULL) {
|
||||||
guit->browser->schedule(-1, control_maintinance, storestate);
|
guit->browser->schedule(-1, control_maintinance, storestate);
|
||||||
write_entries(storestate);
|
write_entries(storestate);
|
||||||
write_blocks(storestate);
|
write_blocks(storestate);
|
||||||
|
|
||||||
|
/* ensure all block files are closed */
|
||||||
|
for (bf = 0; bf < BLOCK_FILE_COUNT; bf++) {
|
||||||
|
if (storestate->blocks[ENTRY_ELEM_DATA][bf].fd != -1) {
|
||||||
|
close(storestate->blocks[ENTRY_ELEM_DATA][bf].fd);
|
||||||
|
}
|
||||||
|
if (storestate->blocks[ENTRY_ELEM_META][bf].fd != -1) {
|
||||||
|
close(storestate->blocks[ENTRY_ELEM_META][bf].fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* avoid division by zero */
|
/* avoid division by zero */
|
||||||
if (storestate->miss_count == 0) {
|
if (storestate->miss_count == 0) {
|
||||||
storestate->miss_count = 1;
|
storestate->miss_count = 1;
|
||||||
@ -1494,7 +1549,7 @@ static nserror store_write_block(struct store_state *state,
|
|||||||
{
|
{
|
||||||
block_index_t bf = (bse->elem[elem_idx].block >> BLOCK_ENTRY_COUNT) &
|
block_index_t bf = (bse->elem[elem_idx].block >> BLOCK_ENTRY_COUNT) &
|
||||||
((1 << BLOCK_FILE_COUNT) - 1); /* block file block resides in */
|
((1 << BLOCK_FILE_COUNT) - 1); /* block file block resides in */
|
||||||
block_index_t bi = bse->elem[elem_idx].block & ((1 << BLOCK_ENTRY_COUNT) -1); /* block index in file */
|
block_index_t bi = bse->elem[elem_idx].block & ((1U << BLOCK_ENTRY_COUNT) -1); /* block index in file */
|
||||||
ssize_t wr;
|
ssize_t wr;
|
||||||
off_t offst;
|
off_t offst;
|
||||||
|
|
||||||
@ -1518,6 +1573,10 @@ static nserror store_write_block(struct store_state *state,
|
|||||||
bse->elem[elem_idx].size,
|
bse->elem[elem_idx].size,
|
||||||
offst);
|
offst);
|
||||||
|
|
||||||
|
LOG(("Wrote %d of %d bytes from %p at %x block %d",
|
||||||
|
wr, bse->elem[elem_idx].size, bse->elem[elem_idx].data,
|
||||||
|
offst, bse->elem[elem_idx].block));
|
||||||
|
|
||||||
if (wr != bse->elem[elem_idx].size) {
|
if (wr != bse->elem[elem_idx].size) {
|
||||||
return NSERROR_SAVE_FAILED;
|
return NSERROR_SAVE_FAILED;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user