Skip to content

Commit

Permalink
Add fsm_vacuum, which reduces the state array when over-allocated.
Browse files Browse the repository at this point in the history
  • Loading branch information
silentbicycle committed May 29, 2024
1 parent 073305b commit 94ffdcc
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 1 deletion.
9 changes: 9 additions & 0 deletions include/fsm/fsm.h
Original file line number Diff line number Diff line change
Expand Up @@ -493,5 +493,14 @@ int fsm_fgetc(void *opaque); /* expects opaque to be FILE * */
int
fsm_shuffle(struct fsm *fsm, unsigned seed);

/* Attempt to reclaim memory if an FSM has significantly reduced its
* state count. Returns 1 if */
enum fsm_vacuum_res {
FSM_VACUUM_NO_CHANGE,
FSM_VACUUM_REDUCED_MEMORY,
FSM_VACUUM_ERROC_REALLOC = -1,
}
fsm_vacuum(struct fsm *fsm);

#endif

1 change: 1 addition & 0 deletions src/libfsm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ SRC += src/libfsm/trim.c
SRC += src/libfsm/example.c
SRC += src/libfsm/getc.c
SRC += src/libfsm/shuffle.c
SRC += src/libfsm/vacuum.c
SRC += src/libfsm/vm.c

# graph things
Expand Down
2 changes: 1 addition & 1 deletion src/libfsm/fsm.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ fsm_new(const struct fsm_options *opt)
return NULL;
}

new->statealloc = 128; /* guess */
new->statealloc = FSM_DEFAULT_STATEALLOC;
new->statecount = 0;
new->endcount = 0;
new->capture_info = NULL;
Expand Down
3 changes: 3 additions & 0 deletions src/libfsm/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ struct state_array;

#define FSM_CAPTURE_MAX INT_MAX

/* guess for default state allocation */
#define FSM_DEFAULT_STATEALLOC 128

struct fsm_edge {
fsm_state_t state; /* destination */
unsigned char symbol;
Expand Down
1 change: 1 addition & 0 deletions src/libfsm/libfsm.syms
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ fsm_addstate
fsm_addstate_bulk
fsm_removestate
fsm_shuffle
fsm_vacuum

fsm_addedge_any
fsm_addedge_epsilon
Expand Down
40 changes: 40 additions & 0 deletions src/libfsm/vacuum.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright 2024 Scott Vokes
*
* See LICENCE for the full copyright terms.
*/

#include <stdlib.h>
#include <fsm/fsm.h>
#include <fsm/alloc.h>

#include <assert.h>

#include "internal.h"

enum fsm_vacuum_res
fsm_vacuum(struct fsm *fsm)
{
assert(fsm != NULL);
assert(fsm->statecount <= fsm->statealloc);
size_t nceil = fsm->statealloc;

while ((fsm->statecount < nceil/2) && nceil > 1) {
nceil /= 2;
}

if (nceil == fsm->statealloc) {
return FSM_VACUUM_NO_CHANGE;
}

struct fsm_state *nstates = f_realloc(fsm->opt->alloc,
fsm->states, nceil * sizeof(nstates[0]));
if (nstates == NULL) {
return FSM_VACUUM_ERROC_REALLOC;
}

fsm->states = nstates;
fsm->statealloc = nceil;

return FSM_VACUUM_REDUCED_MEMORY;
}

0 comments on commit 94ffdcc

Please sign in to comment.