mirror of
https://github.com/urbit/ares.git
synced 2024-11-23 00:25:49 +03:00
pma: persistent file growth highpg tracking attempted fix
spent a while debugging this, but there are still issues on restoration. We cannot simply call _flist_new and _flist_record_alloc on persistent state restoration since _flist_new won't properly set the highpg. If restoring, we should derive the high flist page (alloced or not) from state->file_size_p. I think I way overcomplicated this
This commit is contained in:
parent
6a08d08c0f
commit
aaa6f5e2ff
@ -243,8 +243,9 @@ int main(int argc, char *argv[])
|
|||||||
allocs[i].hi = allocs[i].lo + pages;
|
allocs[i].hi = allocs[i].lo + pages;
|
||||||
alloc_sizp += pages;
|
alloc_sizp += pages;
|
||||||
/* validate size changes to mlist and flist */
|
/* validate size changes to mlist and flist */
|
||||||
assert(_flist_sizep(state3->flist)
|
/* ;;: no longer a valid comparison since the flist may have grown */
|
||||||
== (flist_sizp - alloc_sizp));
|
/* assert(_flist_sizep(state3->flist) */
|
||||||
|
/* == (flist_sizp - alloc_sizp)); */
|
||||||
assert(_mlist_sizep(state3->mlist)
|
assert(_mlist_sizep(state3->mlist)
|
||||||
== (mlist_sizp - alloc_sizp));
|
== (mlist_sizp - alloc_sizp));
|
||||||
N = _bt_numkeys(root);
|
N = _bt_numkeys(root);
|
||||||
|
@ -331,7 +331,11 @@ struct BT_state {
|
|||||||
BYTE *map;
|
BYTE *map;
|
||||||
BT_meta *meta_pages[2]; /* double buffered */
|
BT_meta *meta_pages[2]; /* double buffered */
|
||||||
pgno_t file_size_p; /* the size of the pma file in pages */
|
pgno_t file_size_p; /* the size of the pma file in pages */
|
||||||
pgno_t flist_highpg; /* highest page in the flist */
|
/* ;;: todo: this may be unnecessary. But it's tricky to derive the lo pgno to
|
||||||
|
insert into the flist when extending the file. Probably possible though
|
||||||
|
by accounting for both file_size_p and the size of all allocated node
|
||||||
|
partitions. */
|
||||||
|
pgno_t flist_highpg; /* highest page alloced or not (exclusive) */
|
||||||
unsigned int which; /* which double-buffered db are we using? */
|
unsigned int which; /* which double-buffered db are we using? */
|
||||||
BT_nlistnode *nlist; /* node freelist */
|
BT_nlistnode *nlist; /* node freelist */
|
||||||
BT_mlistnode *mlist; /* memory freelist */
|
BT_mlistnode *mlist; /* memory freelist */
|
||||||
@ -537,6 +541,9 @@ _flist_record_alloc(BT_state *state, pgno_t lo, pgno_t hi)
|
|||||||
free(*head);
|
free(*head);
|
||||||
*head = next;
|
*head = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* update the highpg if necessary */
|
||||||
|
state->flist_highpg = MAX(state->flist_highpg, hi);
|
||||||
}
|
}
|
||||||
|
|
||||||
static BT_page *
|
static BT_page *
|
||||||
@ -1578,11 +1585,15 @@ _mlist_new(BT_state *state)
|
|||||||
return BT_SUCC;
|
return BT_SUCC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ;;: todo: we could remove the hifreepg param if we can derive the highest
|
||||||
|
page (alloced or not) in the persistent file. */
|
||||||
static void
|
static void
|
||||||
_flist_grow(BT_state *state, size_t pages)
|
_flist_grow(BT_state *state, size_t pages, pgno_t hifreepg)
|
||||||
/* grows the backing file by PMA_GROW_SIZE_p and appends this freespace to the
|
/* grows the backing file by PMA_GROW_SIZE_p and appends this freespace to the
|
||||||
flist */
|
flist */
|
||||||
{
|
{
|
||||||
|
pgno_t flist_highpg = MAX(hifreepg, state->flist_highpg);
|
||||||
|
|
||||||
/* grow the backing file by at least PMA_GROW_SIZE_p */
|
/* grow the backing file by at least PMA_GROW_SIZE_p */
|
||||||
pages = MAX(pages, PMA_GROW_SIZE_p);
|
pages = MAX(pages, PMA_GROW_SIZE_p);
|
||||||
off_t bytes = P2BYTES(pages);
|
off_t bytes = P2BYTES(pages);
|
||||||
@ -1594,8 +1605,8 @@ _flist_grow(BT_state *state, size_t pages)
|
|||||||
|
|
||||||
/* and add this space to the flist */
|
/* and add this space to the flist */
|
||||||
_flist_insert(&state->flist,
|
_flist_insert(&state->flist,
|
||||||
state->flist_highpg,
|
flist_highpg,
|
||||||
state->flist_highpg + pages);
|
flist_highpg + pages);
|
||||||
|
|
||||||
state->flist_highpg += pages;
|
state->flist_highpg += pages;
|
||||||
}
|
}
|
||||||
@ -2404,11 +2415,13 @@ _bt_falloc(BT_state *state, size_t pages)
|
|||||||
contiguous space for pages */
|
contiguous space for pages */
|
||||||
start:
|
start:
|
||||||
BT_flistnode **n = &state->flist;
|
BT_flistnode **n = &state->flist;
|
||||||
|
pgno_t hifreepg = 0;
|
||||||
pgno_t ret = 0;
|
pgno_t ret = 0;
|
||||||
|
|
||||||
/* first fit */
|
/* first fit */
|
||||||
for (; *n; n = &(*n)->next) {
|
for (; *n; n = &(*n)->next) {
|
||||||
size_t sz_p = (*n)->hi - (*n)->lo;
|
size_t sz_p = (*n)->hi - (*n)->lo;
|
||||||
|
hifreepg = (*n)->hi;
|
||||||
|
|
||||||
if (sz_p >= pages) {
|
if (sz_p >= pages) {
|
||||||
ret = (*n)->lo;
|
ret = (*n)->lo;
|
||||||
@ -2422,7 +2435,7 @@ _bt_falloc(BT_state *state, size_t pages)
|
|||||||
/* flist out of mem, grow it */
|
/* flist out of mem, grow it */
|
||||||
DPRINTF("flist out of mem, growing current size (pages): 0x%" PRIX32 " to: 0x%" PRIX32,
|
DPRINTF("flist out of mem, growing current size (pages): 0x%" PRIX32 " to: 0x%" PRIX32,
|
||||||
state->file_size_p, state->file_size_p + PMA_GROW_SIZE_p);
|
state->file_size_p, state->file_size_p + PMA_GROW_SIZE_p);
|
||||||
_flist_grow(state, pages);
|
_flist_grow(state, pages, hifreepg);
|
||||||
/* restart the find procedure */
|
/* restart the find procedure */
|
||||||
/* TODO: obv a minor optimization can be made here */
|
/* TODO: obv a minor optimization can be made here */
|
||||||
goto start;
|
goto start;
|
||||||
|
Loading…
Reference in New Issue
Block a user