Skip to content

Commit

Permalink
Merge pull request katef#472 from katef/sv/add_fsm_vacuum
Browse files Browse the repository at this point in the history
Add fsm_vacuum, which reduces the state array when over-allocated.
  • Loading branch information
katef authored May 30, 2024
2 parents 201637d + 6147860 commit 1732de7
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 1 deletion.
8 changes: 8 additions & 0 deletions include/fsm/fsm.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
* be atomic.
*/

#include <stdbool.h>

struct fsm;
struct fsm_options;
struct path; /* XXX */
Expand Down Expand Up @@ -493,5 +495,11 @@ 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 true if the vacuuming attempt succeeded (including
* deciding not to do anything), false if realloc failed. */
bool
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
5 changes: 4 additions & 1 deletion src/libfsm/fsm.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
#include "capture.h"
#include "endids.h"

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

void
free_contents(struct fsm *fsm)
{
Expand Down Expand Up @@ -57,7 +60,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
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
6 changes: 6 additions & 0 deletions src/libfsm/minimise.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,12 @@ fsm_minimise(struct fsm *fsm)

fsm_move(fsm, dst);

/* The FSM state count should be settled now, so if the state
* allocation is unnecessarily large move to a smaller one. */
if (!fsm_vacuum(fsm)) { /* realloc failure */
r = 0;
}

cleanup:
if (mapping != NULL) {
f_free(fsm->opt->alloc, mapping);
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"

bool
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 true;
}

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

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

return true;
}

0 comments on commit 1732de7

Please sign in to comment.