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:
parent
75447dc43c
commit
c5de0c21c9
|
|
@ -6,7 +6,8 @@
|
||||||
|
|
||||||
struct plot constantplot = {
|
struct plot constantplot = {
|
||||||
"Constant values", Spice_Build_Date, "constants",
|
"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;
|
struct plot *plot_cur = &constantplot;
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
|
||||||
#include "dimens.h"
|
#include "dimens.h"
|
||||||
#include "../misc/misc_time.h"
|
#include "../misc/misc_time.h"
|
||||||
#include "vectors.h"
|
#include "vectors.h"
|
||||||
|
#include "ngspice/dstring.h"
|
||||||
#include "plotting/plotting.h"
|
#include "plotting/plotting.h"
|
||||||
|
|
||||||
#ifdef XSPICE
|
#ifdef XSPICE
|
||||||
|
|
@ -28,13 +29,46 @@ struct dvec *EVTfindvec(char *node);
|
||||||
#endif
|
#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
|
/* 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. */
|
* v_link2 is set, because otherwise we will get screwed up. */
|
||||||
static struct dvec *
|
static struct dvec *
|
||||||
findvec(char *word, struct plot *pl)
|
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;
|
struct dvec *d, *newv = NULL, *end = NULL, *v;
|
||||||
char buf[BSIZE_SP];
|
|
||||||
|
|
||||||
if (pl == NULL)
|
if (pl == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
@ -115,15 +149,37 @@ findvec(char *word, struct plot *pl)
|
||||||
return (newv);
|
return (newv);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (d = pl->pl_dvecs; d; d = d->v_next)
|
if (!pl->pl_lookup_valid)
|
||||||
if (cieq(word, d->v_name) && (d->v_flags & VF_PERMANENT))
|
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;
|
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
|
#ifdef XSPICE
|
||||||
/* gtri - begin - Add processing for getting event-driven vector */
|
/* gtri - begin - Add processing for getting event-driven vector */
|
||||||
|
|
||||||
|
|
@ -728,6 +784,7 @@ vec_new(struct dvec *d)
|
||||||
if (plot_cur == NULL) {
|
if (plot_cur == NULL) {
|
||||||
fprintf(cp_err, "vec_new: Internal Error: no cur plot\n");
|
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))
|
if ((d->v_flags & VF_PERMANENT) && (plot_cur->pl_scale == NULL))
|
||||||
plot_cur->pl_scale = d;
|
plot_cur->pl_scale = d;
|
||||||
if (!d->v_plot)
|
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. */
|
/* Now we have to take this dvec out of the plot list. */
|
||||||
if (pl != NULL) {
|
if (pl != NULL) {
|
||||||
|
pl->pl_lookup_valid = FALSE;
|
||||||
if (pl->pl_dvecs == v) {
|
if (pl->pl_dvecs == v) {
|
||||||
pl->pl_dvecs = v->v_next;
|
pl->pl_dvecs = v->v_next;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#include "ngspice/wordlist.h"
|
#include "ngspice/wordlist.h"
|
||||||
#include "ngspice/bool.h"
|
#include "ngspice/bool.h"
|
||||||
#include "ngspice/dvec.h"
|
#include "ngspice/dvec.h"
|
||||||
|
#include "ngspice/hash.h"
|
||||||
|
|
||||||
struct ccom;
|
struct ccom;
|
||||||
|
|
||||||
|
|
@ -17,10 +18,12 @@ struct plot {
|
||||||
struct dvec *pl_dvecs; /* The data vectors in this plot. */
|
struct dvec *pl_dvecs; /* The data vectors in this plot. */
|
||||||
struct dvec *pl_scale; /* The "scale" for the rest of the vectors. */
|
struct dvec *pl_scale; /* The "scale" for the rest of the vectors. */
|
||||||
struct plot *pl_next; /* List of plots. */
|
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. */
|
wordlist *pl_commands; /* Commands to execute for this plot. */
|
||||||
struct variable *pl_env; /* The 'environment' for this plot. */
|
struct variable *pl_env; /* The 'environment' for this plot. */
|
||||||
struct ccom *pl_ccom; /* The ccom struct 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_written; /* Some or all of the vecs have been saved. */
|
||||||
|
bool pl_lookup_valid; /* vector lookup table valid */
|
||||||
int pl_ndims; /* Number of dimensions */
|
int pl_ndims; /* Number of dimensions */
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue