forked from AuroraMiddleware/gtk
cssselector: Rework how we handle the bloom filter
Instead of foreaching through all the previous selectors every time we bloom-filter, just bloom-filter the current element and return a special value if that filter fails (FALSE). If that happens, don't try filter-matching more nodes in the caller as we know it's an abort.
This commit is contained in:
parent
c6158f1684
commit
5e3cbff8d2
@ -1883,49 +1883,6 @@ gtk_css_selector_tree_get_change (const GtkCssSelectorTree *tree,
|
|||||||
return change;
|
return change;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
gtk_css_selector_tree_match_bloom (const GtkCssSelectorTree *tree,
|
|
||||||
const GtkCountingBloomFilter *filter,
|
|
||||||
gboolean skipping)
|
|
||||||
{
|
|
||||||
const GtkCssSelectorTree *prev;
|
|
||||||
|
|
||||||
switch (tree->selector.class->category)
|
|
||||||
{
|
|
||||||
case GTK_CSS_SELECTOR_CATEGORY_SIMPLE:
|
|
||||||
break;
|
|
||||||
case GTK_CSS_SELECTOR_CATEGORY_SIMPLE_RADICAL:
|
|
||||||
if (skipping)
|
|
||||||
break;
|
|
||||||
if (!gtk_counting_bloom_filter_may_contain (filter,
|
|
||||||
gtk_css_selector_hash_one (&tree->selector)))
|
|
||||||
return FALSE;
|
|
||||||
break;
|
|
||||||
case GTK_CSS_SELECTOR_CATEGORY_PARENT:
|
|
||||||
skipping = FALSE;
|
|
||||||
break;
|
|
||||||
case GTK_CSS_SELECTOR_CATEGORY_SIBLING:
|
|
||||||
skipping = TRUE;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
g_assert_not_reached ();
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gtk_css_selector_tree_get_matches (tree))
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
for (prev = gtk_css_selector_tree_get_previous (tree);
|
|
||||||
prev != NULL;
|
|
||||||
prev = gtk_css_selector_tree_get_sibling (prev))
|
|
||||||
{
|
|
||||||
if (gtk_css_selector_tree_match_bloom (prev, filter, skipping))
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_css_selector_tree_found_match (const GtkCssSelectorTree *tree,
|
gtk_css_selector_tree_found_match (const GtkCssSelectorTree *tree,
|
||||||
GPtrArray **results)
|
GPtrArray **results)
|
||||||
@ -1944,27 +1901,27 @@ gtk_css_selector_tree_found_match (const GtkCssSelectorTree *tree,
|
|||||||
g_ptr_array_insert_sorted (*results, matches[i]);
|
g_ptr_array_insert_sorted (*results, matches[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static gboolean
|
||||||
gtk_css_selector_tree_match (const GtkCssSelectorTree *tree,
|
gtk_css_selector_tree_match (const GtkCssSelectorTree *tree,
|
||||||
const GtkCountingBloomFilter *filter,
|
const GtkCountingBloomFilter *filter,
|
||||||
|
gboolean match_filter,
|
||||||
GtkCssNode *node,
|
GtkCssNode *node,
|
||||||
GPtrArray **results)
|
GPtrArray **results)
|
||||||
{
|
{
|
||||||
const GtkCssSelectorTree *prev;
|
const GtkCssSelectorTree *prev;
|
||||||
GtkCssNode *child;
|
GtkCssNode *child;
|
||||||
|
|
||||||
|
if (match_filter && tree->selector.class->category == GTK_CSS_SELECTOR_CATEGORY_SIMPLE_RADICAL &&
|
||||||
|
!gtk_counting_bloom_filter_may_contain (filter, gtk_css_selector_hash_one (&tree->selector)))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
if (!gtk_css_selector_match_one (&tree->selector, node))
|
if (!gtk_css_selector_match_one (&tree->selector, node))
|
||||||
return;
|
return TRUE;
|
||||||
|
|
||||||
gtk_css_selector_tree_found_match (tree, results);
|
gtk_css_selector_tree_found_match (tree, results);
|
||||||
|
|
||||||
if (filter && !gtk_css_selector_is_simple (&tree->selector))
|
if (filter && !gtk_css_selector_is_simple (&tree->selector))
|
||||||
{
|
match_filter = tree->selector.class->category == GTK_CSS_SELECTOR_CATEGORY_PARENT;
|
||||||
/* We can pass both TRUE or FALSE for skipping here, because the
|
|
||||||
* function will immediately update it. */
|
|
||||||
if (!gtk_css_selector_tree_match_bloom (tree, filter, FALSE))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (prev = gtk_css_selector_tree_get_previous (tree);
|
for (prev = gtk_css_selector_tree_get_previous (tree);
|
||||||
prev != NULL;
|
prev != NULL;
|
||||||
@ -1974,11 +1931,12 @@ gtk_css_selector_tree_match (const GtkCssSelectorTree *tree,
|
|||||||
child;
|
child;
|
||||||
child = gtk_css_selector_iterator (&tree->selector, node, child))
|
child = gtk_css_selector_iterator (&tree->selector, node, child))
|
||||||
{
|
{
|
||||||
gtk_css_selector_tree_match (prev, filter, child, results);
|
if (!gtk_css_selector_tree_match (prev, filter, match_filter, child, results))
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
GPtrArray *
|
GPtrArray *
|
||||||
@ -1986,12 +1944,14 @@ _gtk_css_selector_tree_match_all (const GtkCssSelectorTree *tree,
|
|||||||
const GtkCountingBloomFilter *filter,
|
const GtkCountingBloomFilter *filter,
|
||||||
GtkCssNode *node)
|
GtkCssNode *node)
|
||||||
{
|
{
|
||||||
|
const GtkCssSelectorTree *iter;
|
||||||
GPtrArray *results = NULL;
|
GPtrArray *results = NULL;
|
||||||
|
|
||||||
for (; tree != NULL;
|
for (iter = tree;
|
||||||
tree = gtk_css_selector_tree_get_sibling (tree))
|
iter != NULL;
|
||||||
|
iter = gtk_css_selector_tree_get_sibling (iter))
|
||||||
{
|
{
|
||||||
gtk_css_selector_tree_match (tree, filter, node, &results);
|
gtk_css_selector_tree_match (iter, filter, FALSE, node, &results);
|
||||||
}
|
}
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
@ -2020,7 +1980,7 @@ gtk_css_selector_tree_get_change_all (const GtkCssSelectorTree *tree,
|
|||||||
|
|
||||||
#ifdef PRINT_TREE
|
#ifdef PRINT_TREE
|
||||||
static void
|
static void
|
||||||
_gtk_css_selector_tree_print (const GtkCssSelectorTree *tree, GString *str, char *prefix)
|
_gtk_css_selector_tree_print (const GtkCssSelectorTree *tree, GString *str, const char *prefix)
|
||||||
{
|
{
|
||||||
gboolean first = TRUE;
|
gboolean first = TRUE;
|
||||||
int len, i;
|
int len, i;
|
||||||
|
Loading…
Reference in New Issue
Block a user