[gtksourceview/wip/search] search: remove region_not_scanned and adapt doc
- From: Sébastien Wilmet <swilmet src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtksourceview/wip/search] search: remove region_not_scanned and adapt doc
- Date: Sun, 23 Jun 2013 10:55:51 +0000 (UTC)
commit 51d236516f5a14668ba99b850e1e63e1f2a407d9
Author: Sébastien Wilmet <swilmet gnome org>
Date: Sun Jun 23 12:54:39 2013 +0200
search: remove region_not_scanned and adapt doc
And rename region_to_scan -> scan_region.
gtksourceview/gtksourcesearch.c | 130 ++++++++++++++++-----------------------
1 files changed, 53 insertions(+), 77 deletions(-)
---
diff --git a/gtksourceview/gtksourcesearch.c b/gtksourceview/gtksourcesearch.c
index 0aa963d..6700e11 100644
--- a/gtksourceview/gtksourcesearch.c
+++ b/gtksourceview/gtksourcesearch.c
@@ -52,12 +52,24 @@
*
* Why highlighting the non-visible matches? What we want is to (1) highlight
* the visible matches and (2) count the number of occurrences. The code would
- * indeed be simpler if these two tasks are clearly separated (in two different
+ * indeed be simpler if these two tasks were clearly separated (in two different
* idle callbacks, with different regions to scan). With this simpler solution,
* we would always use forward_search() and backward_search() to navigate
* through the occurrences. But we can do better than that!
- * forward_to_tag_toggle() and backward_to_tag_toggle() are far more efficient.
- * We must just pay attention to contiguous matches.
+ * forward_to_tag_toggle() and backward_to_tag_toggle() are far more efficient:
+ * once the buffer has been scanned, going to the previous or the next
+ * occurrence is done in O(1). We must just pay attention to contiguous matches.
+ *
+ * While the user is typing the text in the search entry, the buffer is scanned
+ * to count the number of occurrences. And when the user wants to do an
+ * operation (go to the next occurrence for example), chances are that the
+ * buffer has already been scanned entirely, so almost all the operations will
+ * be really fast.
+ *
+ * Extreme example:
+ * <occurrence> [1 GB of text] <next-occurrence>
+ * Once the buffer is scanned, switching between the occurrences will be almost
+ * instantaneous.
*
* So how to count the number of occurrences then? Remember that the buffer
* contents can be modified during the scan, and that we keep the old
@@ -69,27 +81,17 @@
* state changes, even if old matches are still there. Because it is not
* possible to count the old matches to decrement occurrences_count (and storing
* the previous search text would not be sufficient, because even older matches
- * can still be there). To update correctly occurrences_count, there are two
- * maintained regions:
+ * can still be there). To increment and decrement occurrences_count, there is
+ * the scan_region, the region to scan. If an occurrence is contained in
+ * scan_region, it means that it has not already been scanned, so
+ * occurrences_count doesn't take into account this occurrence. On the other
+ * hand, if we find an occurrence outside scan_region, the occurrence is
+ * normally correctly highlighted, and occurrences_count take it into account.
*
- * - The region_not_scanned, which contain the region not already scanned since
- * the last search state update. region_not_scanned can potentially contain
- * old matches. When we highlight the matches in this region, we first remove
- * all the found_tag's, without decrementing occurrences_count, and then we
- * search the new matches and increment occurrences_count.
- *
- * - The region_to_scan, which can contain subregions already scanned (and thus
- * removed from region_not_scanned). If a modification occurs in a buffer
- * region not present in region_not_scanned, the modified region will be
- * present only in region_to_scan. Such a region can not contain old matches.
- * Before the modification occurs, we remove the (good) matches, and we
- * decrement occurrences_count. After the modification, the idle callback will
- * highlight the matches and will increment occurrences_count.
- *
- * Example where forward_to_tag_toggle() is really nice:
- * <occurrence> [1 GB of text] <next-occurrence>
- * Once the buffer has been scanned once, switching between the occurrences is
- * almost instantaneous (O(1) complexity).
+ * So when we highlight or when we remove the highlight of an occurrence (on
+ * text insertion, deletion, when scanning, etc.), we increment or decrement
+ * occurrences_count depending on whether the occurrence was already taken into
+ * account by occurrences_count.
*
* If the code seems too complicated and contains strange bugs, you have two
* choices:
@@ -120,13 +122,8 @@ struct _GtkSourceSearchPrivate
gint text_nb_lines;
GtkTextSearchFlags flags;
- /* The region not already scanned since the last search state update. */
- GtkTextRegion *region_not_scanned;
-
- /* The region to scan and highlight. If NULL, the scan is finished. It
- * can contains regions already scanned, but must be rescanned.
- */
- GtkTextRegion *region_to_scan;
+ /* The region to scan and highlight. If NULL, the scan is finished. */
+ GtkTextRegion *scan_region;
/* The region to scan and highlight in priority. I.e. the visible part
* of the buffer on the screen.
@@ -281,16 +278,10 @@ get_first_subregion (GtkTextRegion *region,
static void
clear_search (GtkSourceSearch *search)
{
- if (search->priv->region_not_scanned != NULL)
- {
- gtk_text_region_destroy (search->priv->region_not_scanned, TRUE);
- search->priv->region_not_scanned = NULL;
- }
-
- if (search->priv->region_to_scan != NULL)
+ if (search->priv->scan_region != NULL)
{
- gtk_text_region_destroy (search->priv->region_to_scan, TRUE);
- search->priv->region_to_scan = NULL;
+ gtk_text_region_destroy (search->priv->scan_region, TRUE);
+ search->priv->scan_region = NULL;
}
if (search->priv->high_priority_region != NULL)
@@ -345,7 +336,7 @@ adjust_subregion (GtkSourceSearch *search,
if (gtk_text_iter_has_tag (start, search->priv->found_tag))
{
- if (is_text_region_empty (search->priv->region_to_scan))
+ if (is_text_region_empty (search->priv->scan_region))
{
/* 'start' is in a correct match, we can skip it. */
@@ -370,7 +361,7 @@ adjust_subregion (GtkSourceSearch *search,
gtk_text_iter_forward_to_tag_toggle (&tag_end, search->priv->found_tag);
}
- region = gtk_text_region_intersect (search->priv->region_to_scan,
+ region = gtk_text_region_intersect (search->priv->scan_region,
&tag_start,
&tag_end);
@@ -401,7 +392,7 @@ adjust_subregion (GtkSourceSearch *search,
if (gtk_text_iter_has_tag (end, search->priv->found_tag))
{
- if (is_text_region_empty (search->priv->region_to_scan))
+ if (is_text_region_empty (search->priv->scan_region))
{
/* 'end' is in a correct match, we can skip it. */
@@ -426,7 +417,7 @@ adjust_subregion (GtkSourceSearch *search,
gtk_text_iter_forward_to_tag_toggle (&tag_end, search->priv->found_tag);
}
- region = gtk_text_region_intersect (search->priv->region_to_scan,
+ region = gtk_text_region_intersect (search->priv->scan_region,
&tag_start,
&tag_end);
@@ -504,7 +495,7 @@ remove_occurrences_in_range (GtkSourceSearch *search,
&match_end,
end))
{
- if (search->priv->region_to_scan == NULL)
+ if (search->priv->scan_region == NULL)
{
/* The occurrence has already been scanned, and thus
* occurrence_count take it into account. */
@@ -512,7 +503,7 @@ remove_occurrences_in_range (GtkSourceSearch *search,
}
else
{
- GtkTextRegion *region = gtk_text_region_intersect (search->priv->region_to_scan,
+ GtkTextRegion *region = gtk_text_region_intersect (search->priv->scan_region,
&match_start,
&match_end);
@@ -553,23 +544,18 @@ scan_subregion (GtkSourceSearch *search,
adjust_subregion (search, start, end);
remove_occurrences_in_range (search, start, end);
- if (search->priv->region_not_scanned != NULL)
- {
- gtk_text_region_subtract (search->priv->region_not_scanned, start, end);
- }
-
- if (search->priv->region_to_scan != NULL)
+ if (search->priv->scan_region != NULL)
{
DEBUG ({
g_print ("Region to scan, before:\n");
- gtk_text_region_debug_print (search->priv->region_to_scan);
+ gtk_text_region_debug_print (search->priv->scan_region);
});
- gtk_text_region_subtract (search->priv->region_to_scan, start, end);
+ gtk_text_region_subtract (search->priv->scan_region, start, end);
DEBUG ({
g_print ("Region to scan, after:\n");
- gtk_text_region_debug_print (search->priv->region_to_scan);
+ gtk_text_region_debug_print (search->priv->scan_region);
});
}
@@ -657,7 +643,7 @@ scan_chunk_region (GtkSourceSearch *search)
GtkTextIter end;
while (nb_remaining_lines > 0 &&
- get_first_subregion (search->priv->region_to_scan, &start, &end))
+ get_first_subregion (search->priv->scan_region, &start, &end))
{
GtkTextIter limit = start;
gint start_line;
@@ -700,27 +686,20 @@ idle_scan_cb (GtkSourceSearch *search)
scan_chunk_region (search);
}
- if (is_text_region_empty (search->priv->region_to_scan))
+ if (is_text_region_empty (search->priv->scan_region))
{
finished = TRUE;
search->priv->idle_scan_id = 0;
g_object_notify (G_OBJECT (search->priv->buffer), "search-occurrences-count");
- if (search->priv->region_to_scan != NULL)
+ if (search->priv->scan_region != NULL)
{
- gtk_text_region_destroy (search->priv->region_to_scan, TRUE);
- search->priv->region_to_scan = NULL;
+ gtk_text_region_destroy (search->priv->scan_region, TRUE);
+ search->priv->scan_region = NULL;
}
}
- if (is_text_region_empty (search->priv->region_not_scanned) &&
- search->priv->region_not_scanned != NULL)
- {
- gtk_text_region_destroy (search->priv->region_not_scanned, TRUE);
- search->priv->region_not_scanned = NULL;
- }
-
return !finished;
}
@@ -741,21 +720,21 @@ add_subregion_to_scan (GtkSourceSearch *search,
GtkTextIter start = *subregion_start;
GtkTextIter end = *subregion_end;
- if (search->priv->region_to_scan == NULL)
+ if (search->priv->scan_region == NULL)
{
- search->priv->region_to_scan = gtk_text_region_new (search->priv->buffer);
+ search->priv->scan_region = gtk_text_region_new (search->priv->buffer);
}
DEBUG ({
g_print ("add_subregion_to_scan(): region to scan, before:\n");
- gtk_text_region_debug_print (search->priv->region_to_scan);
+ gtk_text_region_debug_print (search->priv->scan_region);
});
- gtk_text_region_add (search->priv->region_to_scan, &start, &end);
+ gtk_text_region_add (search->priv->scan_region, &start, &end);
DEBUG ({
g_print ("add_subregion_to_scan(): region to scan, after:\n");
- gtk_text_region_debug_print (search->priv->region_to_scan);
+ gtk_text_region_debug_print (search->priv->scan_region);
});
install_idle_scan (search);
@@ -782,12 +761,9 @@ update (GtkSourceSearch *search)
clear_search (search);
- search->priv->region_not_scanned = gtk_text_region_new (search->priv->buffer);
- search->priv->region_to_scan = gtk_text_region_new (search->priv->buffer);
+ search->priv->scan_region = gtk_text_region_new (search->priv->buffer);
gtk_text_buffer_get_bounds (search->priv->buffer, &start, &end);
-
- gtk_text_region_add (search->priv->region_not_scanned, &start, &end);
add_subregion_to_scan (search, &start, &end);
}
@@ -1033,12 +1009,12 @@ _gtk_source_search_update_highlight (GtkSourceSearch *search,
g_return_if_fail (end != NULL);
if (dispose_has_run (search) ||
- is_text_region_empty (search->priv->region_to_scan))
+ is_text_region_empty (search->priv->scan_region))
{
return;
}
- region_to_highlight = gtk_text_region_intersect (search->priv->region_to_scan,
+ region_to_highlight = gtk_text_region_intersect (search->priv->scan_region,
start,
end);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]