* fix bug #95954 -- cache backend query compiles. Add a hash table

to map book -> backend compile and fill it in when the terms are
	  recompiled.


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@7332 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Derek Atkins 2002-10-17 16:49:41 +00:00
parent bd4c60d1c2
commit 05b4cb1192
2 changed files with 60 additions and 15 deletions

View File

@ -11,6 +11,10 @@
(i.e. a real container with no value in the container). (i.e. a real container with no value in the container).
* fix part of bug #96032 -- use (gnc:owner-is-valid) to detect owner * fix part of bug #96032 -- use (gnc:owner-is-valid) to detect owner
existence. existence.
* fix bug #95954 -- cache backend query compiles. Add a hash table
to map book -> backend compile and fill it in when the terms are
recompiled.
2002-10-16 Joshua Sled <jsled@asynchronous.org> 2002-10-16 Joshua Sled <jsled@asynchronous.org>

View File

@ -75,6 +75,9 @@ struct querynew_s {
/* list of books that will be participating in the query */ /* list of books that will be participating in the query */
GList * books; GList * books;
/* a map of book to backend-compiled queries */
GHashTable* be_compiled;
/* cache the results so we don't have to run the whole search /* cache the results so we don't have to run the whole search
* again until it's really necessary */ * again until it's really necessary */
int changed; int changed;
@ -93,6 +96,7 @@ static void query_init (QueryNew *q, QueryNewTerm *initial_term)
{ {
GList * or = NULL; GList * or = NULL;
GList *and = NULL; GList *and = NULL;
GHashTable *ht;
if (initial_term) { if (initial_term) {
or = g_list_alloc (); or = g_list_alloc ();
@ -115,7 +119,9 @@ static void query_init (QueryNew *q, QueryNewTerm *initial_term)
g_slist_free (q->secondary_sort.param_fcns); g_slist_free (q->secondary_sort.param_fcns);
g_slist_free (q->tertiary_sort.param_fcns); g_slist_free (q->tertiary_sort.param_fcns);
ht = q->be_compiled;
memset (q, 0, sizeof (*q)); memset (q, 0, sizeof (*q));
q->be_compiled = ht;
q->terms = or; q->terms = or;
q->changed = 1; q->changed = 1;
@ -429,7 +435,7 @@ static void compile_sort (QueryNewSort_t sort, GNCIdType obj)
static void compile_terms (QueryNew *q) static void compile_terms (QueryNew *q)
{ {
GList *or_ptr, *and_ptr; GList *or_ptr, *and_ptr, *node;
/* Find the specific functions for this Query. Note that the /* Find the specific functions for this Query. Note that the
* Query's search_for should now be set to the new type. * Query's search_for should now be set to the new type.
@ -463,6 +469,18 @@ static void compile_terms (QueryNew *q)
compile_sort (&(q->tertiary_sort), q->search_for); compile_sort (&(q->tertiary_sort), q->search_for);
q->defaultSort = gncQueryObjectDefaultSort (q->search_for); q->defaultSort = gncQueryObjectDefaultSort (q->search_for);
/* Now compile the backend instances */
for (node = q->books; node; node = node->next) {
GNCBook *book = node->data;
Backend *be = book->backend;
if (be && be->compile_query) {
gpointer result = (be->compile_query)(be, q);
if (result)
g_hash_table_insert (q->be_compiled, book, result);
}
}
} }
static void check_item_cb (gpointer object, gpointer user_data) static void check_item_cb (gpointer object, gpointer user_data)
@ -513,6 +531,24 @@ static GList * merge_books (GList *l1, GList *l2)
return res; return res;
} }
static gboolean
query_free_compiled (gpointer key, gpointer value, gpointer not_used)
{
GNCBook* book = key;
Backend* be = book->backend;
if (be && be->free_query)
(be->free_query)(be, value);
return TRUE;
}
/* clear out any cached query_compilations */
static void query_clear_compiles (QueryNew *q)
{
g_hash_table_foreach_remove (q->be_compiled, query_free_compiled, NULL);
}
/********************************************************************/ /********************************************************************/
/* PUBLISHED API FUNCTIONS */ /* PUBLISHED API FUNCTIONS */
@ -583,8 +619,10 @@ GList * gncQueryRun (QueryNew *q)
/* XXX: Prioritize the query terms? */ /* XXX: Prioritize the query terms? */
/* prepare the Query for processing */ /* prepare the Query for processing */
if (q->changed) if (q->changed) {
query_clear_compiles (q);
compile_terms (q); compile_terms (q);
}
/* Now run the query over all the objects and save the results */ /* Now run the query over all the objects and save the results */
{ {
@ -598,21 +636,12 @@ GList * gncQueryRun (QueryNew *q)
GNCBook *book = node->data; GNCBook *book = node->data;
Backend *be = book->backend; Backend *be = book->backend;
/* query the backend */ /* run the query in the backend */
if (be) { if (be) {
gpointer compiled_query = NULL; gpointer compiled_query = g_hash_table_lookup (q->be_compiled, book);
/* XXX: The compiled query should be cached as part of if (compiled_query && be->run_query)
* the compile_terms
*/
if (be->compile_query && be->run_query) {
compiled_query = (be->compile_query) (be, q);
(be->run_query) (be, compiled_query); (be->run_query) (be, compiled_query);
}
if (compiled_query && be->free_query)
(be->free_query) (be, compiled_query);
} }
/* and then iterate over all the objects */ /* and then iterate over all the objects */
@ -699,6 +728,7 @@ void gncQueryClear (QueryNew *query)
QueryNew * gncQueryCreate (void) QueryNew * gncQueryCreate (void)
{ {
QueryNew *qp = g_new0 (QueryNew, 1); QueryNew *qp = g_new0 (QueryNew, 1);
qp->be_compiled = g_hash_table_new (g_direct_hash, g_direct_equal);
query_init (qp, NULL); query_init (qp, NULL);
return qp; return qp;
} }
@ -763,18 +793,24 @@ void gncQueryDestroy (QueryNew *q)
{ {
if (!q) return; if (!q) return;
free_members (q); free_members (q);
query_clear_compiles (q);
g_hash_table_destroy (q->be_compiled);
g_free (q); g_free (q);
} }
QueryNew * gncQueryCopy (QueryNew *q) QueryNew * gncQueryCopy (QueryNew *q)
{ {
QueryNew *copy; QueryNew *copy;
GHashTable *ht;
if (!q) return NULL; if (!q) return NULL;
copy = gncQueryCreate (); copy = gncQueryCreate ();
ht = copy->be_compiled;
free_members (copy); free_members (copy);
memcpy (copy, q, sizeof (QueryNew)); memcpy (copy, q, sizeof (QueryNew));
copy->be_compiled = ht;
copy->terms = copy_or_terms (q->terms); copy->terms = copy_or_terms (q->terms);
copy->books = g_list_copy (q->books); copy->books = g_list_copy (q->books);
copy->results = g_list_copy (q->results); copy->results = g_list_copy (q->results);
@ -783,6 +819,8 @@ QueryNew * gncQueryCopy (QueryNew *q)
copy_sort (&(copy->secondary_sort), &(q->secondary_sort)); copy_sort (&(copy->secondary_sort), &(q->secondary_sort));
copy_sort (&(copy->tertiary_sort), &(q->tertiary_sort)); copy_sort (&(copy->tertiary_sort), &(q->tertiary_sort));
copy->changed = 1;
return copy; return copy;
} }
@ -1046,7 +1084,10 @@ void gncQuerySetBook (QueryNew *q, GNCBook *book)
{ {
if (!q || !book) return; if (!q || !book) return;
q->books = g_list_prepend (q->books, book); /* Make sure this book is only in the list once */
if (g_list_index (q->books, book) == -1)
q->books = g_list_prepend (q->books, book);
gncQueryAddGUIDMatch (q, g_slist_prepend (g_slist_prepend (NULL, gncQueryAddGUIDMatch (q, g_slist_prepend (g_slist_prepend (NULL,
QUERY_PARAM_GUID), QUERY_PARAM_GUID),
QUERY_PARAM_BOOK), QUERY_PARAM_BOOK),