[california/wip/732671-double: 9/10] Don't use TreeSet to store mutating objects



commit 01ed9ba408ee15f7545a77ad2a31418c451e7728
Author: Jim Nelson <jim yorba org>
Date:   Wed Sep 10 14:45:34 2014 -0700

    Don't use TreeSet to store mutating objects

 src/view/common/common-events-cell.vala |   37 ++++++++++---------------------
 src/view/week/week-day-pane.vala        |   35 ++++++++++++++++------------
 2 files changed, 32 insertions(+), 40 deletions(-)
---
diff --git a/src/view/common/common-events-cell.vala b/src/view/common/common-events-cell.vala
index 8f57872..804d8f2 100644
--- a/src/view/common/common-events-cell.vala
+++ b/src/view/common/common-events-cell.vala
@@ -85,7 +85,7 @@ internal abstract class EventsCell : Gtk.EventBox, InstanceContainer {
     /**
      * @inheritDoc
      */
-    public int event_count { get { return sorted_events.size; } }
+    public int event_count { get { return days_events.size; } }
     
     /**
      * @inheritDoc
@@ -99,7 +99,7 @@ internal abstract class EventsCell : Gtk.EventBox, InstanceContainer {
      */
     public View.Palette palette { get; private set; }
     
-    private Gee.TreeSet<Component.Event> sorted_events = new 
Gee.TreeSet<Component.Event>(all_day_comparator);
+    private Gee.HashSet<Component.Event> days_events = new Gee.HashSet<Component.Event>();
     private Gee.HashMap<int, Component.Event> line_to_event = new Gee.HashMap<int, Component.Event>();
     private Gtk.DrawingArea canvas = new Gtk.DrawingArea();
     
@@ -216,14 +216,14 @@ internal abstract class EventsCell : Gtk.EventBox, InstanceContainer {
     public void clear_events() {
         line_to_event.clear();
         
-        foreach (Component.Event event in sorted_events.to_array())
-            internal_remove_event(event);
+        traverse_safely<Component.Event>(days_events)
+            .iterate(event => internal_remove_event(event));
         
         queue_draw();
     }
     
     public void add_event(Component.Event event) {
-        if (!sorted_events.add(event)) {
+        if (!days_events.add(event)) {
             debug("Unable to add event %Xh to cell for %s: already present", (uint) event,
                 date.to_string());
             
@@ -241,7 +241,7 @@ internal abstract class EventsCell : Gtk.EventBox, InstanceContainer {
     }
     
     private bool internal_remove_event(Component.Event event) {
-        if (!sorted_events.remove(event)) {
+        if (!days_events.remove(event)) {
             debug("Unable to remove event %Xh from cell for %s: not present in sorted_events",
                 (uint) event, date.to_string());
             
@@ -271,7 +271,7 @@ internal abstract class EventsCell : Gtk.EventBox, InstanceContainer {
      * calendar in question has any events in this date.
      */
     public void notify_calendar_visibility_changed(Backing.CalendarSource calendar_source) {
-        if (!traverse<Component.Event>(sorted_events).any((event) => event.calendar_source == 
calendar_source))
+        if (!traverse<Component.Event>(days_events).any((event) => event.calendar_source == calendar_source))
             return;
         
         // found one
@@ -282,7 +282,7 @@ internal abstract class EventsCell : Gtk.EventBox, InstanceContainer {
     // Called internally by other Cells when (a) they're in charge of assigning a multi-day event
     // its line number for the week and (b) that line number has changed.
     private void notify_assigned_line_number_changed(Gee.Collection<Component.Event> events) {
-        if (!traverse<Component.Event>(sorted_events).contains_any(events))
+        if (!traverse<Component.Event>(days_events).contains_any(events))
             return;
         
         assign_line_numbers();
@@ -302,10 +302,10 @@ internal abstract class EventsCell : Gtk.EventBox, InstanceContainer {
         // reassigned because of this
         Gee.ArrayList<Component.Event> reassigned = new Gee.ArrayList<Component.Event>();
         
+        Gee.TreeSet<Component.Event> sorted_events = traverse<Component.Event>(days_events)
+            .filter(event => event.calendar_source.visible)
+            .to_tree_set(all_day_comparator);
         foreach (Component.Event event in sorted_events) {
-            if (!event.calendar_source.visible)
-                continue;
-            
             bool notify_reassigned = false;
             if (event.is_day_spanning) {
                 // get the first day of this week the event exists in ... if not the current cell's
@@ -390,25 +390,12 @@ internal abstract class EventsCell : Gtk.EventBox, InstanceContainer {
     private void on_span_updated(Object object, ParamSpec param) {
         Component.Event event = (Component.Event) object;
         
-        // remove from cell if no longer in this day, otherwise remove and add again to sorted_events
-        // to re-sort
+        // remove from cell if no longer in this day
         if (!(date in event.get_event_date_span(Calendar.Timezone.local))) {
             debug("Removing event %Xh from cell for %s: no longer in date span", (uint) event,
                 date.to_string());
             
             remove_event(event);
-        } else if (sorted_events.remove(event)) {
-            debug("Re-sorting event %Xh in cell for %s: date/time changed", (uint) event,
-                date.to_string());
-            
-            if (!sorted_events.add(event)) {
-                debug("Unable to re-sort event %Xh in cell for %s: already present", (uint) event,
-                    date.to_string());
-            }
-            
-            assign_line_numbers();
-        } else {
-            debug("Unknown event %Xh associated with cell %s", (uint) event, date.to_string());
         }
         
         queue_draw();
diff --git a/src/view/week/week-day-pane.vala b/src/view/week/week-day-pane.vala
index 0298618..1835291 100644
--- a/src/view/week/week-day-pane.vala
+++ b/src/view/week/week-day-pane.vala
@@ -52,7 +52,7 @@ internal class DayPane : Pane, Common.InstanceContainer {
      */
     public Calendar.Span contained_span { get { return date; } }
     
-    private Gee.TreeSet<Component.Event> days_events = new Gee.TreeSet<Component.Event>();
+    private Gee.HashSet<Component.Event> days_events = new Gee.HashSet<Component.Event>();
     private Scheduled? scheduled_monitor = null;
     
     public DayPane(Grid owner, Calendar.Date date) {
@@ -137,11 +137,9 @@ internal class DayPane : Pane, Common.InstanceContainer {
     private void on_update_date_time(Object object, ParamSpec param) {
         Component.Event event = (Component.Event) object;
         
-        // remove entirely if not in this date any more, otherwise remove and re-add to re-sort
+        // remove entirely if not in this date any more
         if (!(date in event.get_event_date_span(Calendar.System.timezone)))
             remove_event(event);
-        else if (days_events.remove(event))
-            days_events.add(event);
         
         queue_draw();
     }
@@ -223,6 +221,20 @@ internal class DayPane : Pane, Common.InstanceContainer {
         return true;
     }
     
+    private bool filter_date_spanning_events(Component.Event event) {
+        // All-day events are handled in separate container ...
+        if (event.is_all_day)
+            return false;
+        
+        // ... as are events that span days (or outside this date, although that technically
+        // shouldn't happen)
+        Calendar.DateSpan date_span = event.get_event_date_span(Calendar.Timezone.local);
+        if (!date_span.is_same_day || !(date in date_span))
+            return false;
+        
+        return true;
+    }
+    
     // note that a painter's algorithm should be used here: background should be painted before
     // calling base method, and foreground afterward
     protected override bool on_draw(Cairo.Context ctx) {
@@ -237,17 +249,10 @@ internal class DayPane : Pane, Common.InstanceContainer {
         // each event is drawn with a slightly-transparent rectangle with a solid hairline bounding
         Palette.prepare_hairline(ctx, palette.border);
         
-        foreach (Component.Event event in days_events) {
-            // All-day events are handled in separate container ...
-            if (event.is_all_day)
-                continue;
-            
-            // ... as are events that span days (or outside this date, although that technically
-            // shouldn't happen)
-            Calendar.DateSpan date_span = event.get_event_date_span(Calendar.Timezone.local);
-            if (!date_span.is_same_day || !(date in date_span))
-                continue;
-            
+        Gee.TreeSet<Component.Event> sorted_events = traverse<Component.Event>(days_events)
+            .filter(filter_date_spanning_events)
+            .to_tree_set();
+        foreach (Component.Event event in sorted_events) {
             Calendar.WallTime start_time =
                 event.exact_time_span.start_exact_time.to_timezone(Calendar.Timezone.local).to_wall_time();
             Calendar.WallTime end_time =


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]