findvec(), use hash tables for the vector search

patch originally provided by Bill Swartz, 2010
reduces vector search time from O(n) to O(1)
This commit is contained in:
h_vogt 2012-12-09 13:08:43 +01:00 committed by rlar
parent 75447dc43c
commit c5de0c21c9
3 changed files with 71 additions and 9 deletions

View File

@ -6,7 +6,8 @@
struct plot constantplot = {
"Constant values", Spice_Build_Date, "constants",
"const", NULL, NULL, NULL, NULL, NULL, NULL, TRUE, 0
"const", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
TRUE, FALSE, 0
};
struct plot *plot_cur = &constantplot;

View File

@ -19,6 +19,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "dimens.h"
#include "../misc/misc_time.h"
#include "vectors.h"
#include "ngspice/dstring.h"
#include "plotting/plotting.h"
#ifdef XSPICE
@ -28,13 +29,46 @@ struct dvec *EVTfindvec(char *node);
#endif
static void
vec_rebuild_lookup_table(struct plot *pl)
{
int cnt; /* count entries */
struct dvec *d; /* dynamic vector */
NGHASHPTR lookup_p; /* lookup table for speed */
SPICE_DSTRING dbuf; /* dynamic buffer */
char *lower_name; /* lower case name */
if (pl->pl_lookup_table) {
nghash_empty(pl->pl_lookup_table, NULL, NULL);
} else {
cnt = 0;
for (d = pl->pl_dvecs; d; d = d->v_next)
cnt++;
pl->pl_lookup_table = nghash_init(cnt);
/* allow multiple entries */
nghash_unique(pl->pl_lookup_table, FALSE);
}
lookup_p = pl->pl_lookup_table;
spice_dstring_init(&dbuf);
for (d = pl->pl_dvecs; d; d = d->v_next) {
spice_dstring_reinit(&dbuf);
lower_name = spice_dstring_append_lower(&dbuf, d->v_name, -1);
nghash_insert(lookup_p, lower_name, d);
}
spice_dstring_free(&dbuf);
pl->pl_lookup_valid = TRUE;
}
/* Find a named vector in a plot. We are careful to copy the vector if
* v_link2 is set, because otherwise we will get screwed up. */
static struct dvec *
findvec(char *word, struct plot *pl)
{
SPICE_DSTRING dbuf; /* dynamic buffer */
char *lower_name; /* lower case name */
char *node_name;
struct dvec *d, *newv = NULL, *end = NULL, *v;
char buf[BSIZE_SP];
if (pl == NULL)
return (NULL);
@ -115,15 +149,37 @@ findvec(char *word, struct plot *pl)
return (newv);
}
for (d = pl->pl_dvecs; d; d = d->v_next)
if (cieq(word, d->v_name) && (d->v_flags & VF_PERMANENT))
if (!pl->pl_lookup_valid)
vec_rebuild_lookup_table(pl);
spice_dstring_init(&dbuf);
lower_name = spice_dstring_append_lower(&dbuf, word, -1);
for (d = nghash_find(pl->pl_lookup_table, lower_name);
d;
d = nghash_find_again(pl->pl_lookup_table, lower_name))
{
if (d->v_flags & VF_PERMANENT)
break;
if (!d) {
(void) sprintf(buf, "v(%s)", word);
for (d = pl->pl_dvecs; d; d = d->v_next)
if (cieq(buf, d->v_name) && (d->v_flags & VF_PERMANENT))
break;
}
if (!d) {
spice_dstring_reinit(&dbuf);
spice_dstring_append(&dbuf, "v(", -1);
spice_dstring_append_lower(&dbuf, word, -1);
node_name = spice_dstring_append_char(&dbuf, ')');
for (d = nghash_find(pl->pl_lookup_table, node_name);
d;
d = nghash_find_again(pl->pl_lookup_table, node_name))
{
if (d->v_flags & VF_PERMANENT)
break;
}
}
spice_dstring_free(&dbuf);
#ifdef XSPICE
/* gtri - begin - Add processing for getting event-driven vector */
@ -728,6 +784,7 @@ vec_new(struct dvec *d)
if (plot_cur == NULL) {
fprintf(cp_err, "vec_new: Internal Error: no cur plot\n");
}
plot_cur->pl_lookup_valid = FALSE;
if ((d->v_flags & VF_PERMANENT) && (plot_cur->pl_scale == NULL))
plot_cur->pl_scale = d;
if (!d->v_plot)
@ -791,6 +848,7 @@ vec_free_x(struct dvec *v)
/* Now we have to take this dvec out of the plot list. */
if (pl != NULL) {
pl->pl_lookup_valid = FALSE;
if (pl->pl_dvecs == v) {
pl->pl_dvecs = v->v_next;
} else {

View File

@ -4,6 +4,7 @@
#include "ngspice/wordlist.h"
#include "ngspice/bool.h"
#include "ngspice/dvec.h"
#include "ngspice/hash.h"
struct ccom;
@ -17,10 +18,12 @@ struct plot {
struct dvec *pl_dvecs; /* The data vectors in this plot. */
struct dvec *pl_scale; /* The "scale" for the rest of the vectors. */
struct plot *pl_next; /* List of plots. */
NGHASHPTR pl_lookup_table; /* for quick lookup of vectors */
wordlist *pl_commands; /* Commands to execute for this plot. */
struct variable *pl_env; /* The 'environment' for this plot. */
struct ccom *pl_ccom; /* The ccom struct for this plot. */
bool pl_written; /* Some or all of the vecs have been saved. */
bool pl_lookup_valid; /* vector lookup table valid */
int pl_ndims; /* Number of dimensions */
} ;