r7236 - in dumbhippo/trunk/client: common/ddm linux linux/engine-dbus



Author: otaylor
Date: 2008-01-18 07:59:13 -0600 (Fri, 18 Jan 2008)
New Revision: 7236

Added:
   dumbhippo/trunk/client/common/ddm/ddm-client-notification-internal.h
Modified:
   dumbhippo/trunk/client/common/ddm/ddm-client-notification.c
   dumbhippo/trunk/client/common/ddm/ddm-client-notification.h
   dumbhippo/trunk/client/common/ddm/ddm-client.c
   dumbhippo/trunk/client/common/ddm/ddm-client.h
   dumbhippo/trunk/client/common/ddm/ddm-data-model.c
   dumbhippo/trunk/client/common/ddm/ddm-data-resource-internal.h
   dumbhippo/trunk/client/common/ddm/ddm-data-resource.c
   dumbhippo/trunk/client/common/ddm/ddm-feed.c
   dumbhippo/trunk/client/common/ddm/ddm-feed.h
   dumbhippo/trunk/client/common/ddm/ddm-local-client.c
   dumbhippo/trunk/client/common/ddm/ddm-work-item.c
   dumbhippo/trunk/client/common/ddm/ddm-work-item.h
   dumbhippo/trunk/client/common/ddm/ddm.h
   dumbhippo/trunk/client/linux/Makefile-libddm.am
   dumbhippo/trunk/client/linux/engine-dbus/hippo-dbus-model-client.c
Log:
- Keep a "notify timestamp" for each feed ... this is the minimum
  timestamp of items that need to be sent out in change notifications.

- Store feed notify timestamps in DDMClientNotificationSet and 
  pass DDMClientNotificationSet to DDMClient when notifying so
  that the client can look up the feed timestamps.

- Only send the items that changed or might have changed when sending
  feeds over D-BUS, instead of resending the entire feed each time
  (which was causing unnecesssary remove/add cycles.)


Copied: dumbhippo/trunk/client/common/ddm/ddm-client-notification-internal.h (from rev 7225, dumbhippo/trunk/client/common/ddm/ddm-client-notification.h)
===================================================================
--- dumbhippo/trunk/client/common/ddm/ddm-client-notification.h	2008-01-17 20:06:06 UTC (rev 7225)
+++ dumbhippo/trunk/client/common/ddm/ddm-client-notification-internal.h	2008-01-18 13:59:13 UTC (rev 7236)
@@ -0,0 +1,30 @@
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
+
+#ifndef __DDM_CLIENT_NOTIFICATION_INTERNAL_H__
+#define __DDM_CLIENT_NOTIFICATION_INTERNAL_H__
+
+#include "ddm-client-notification.h"
+#include "ddm-client.h"
+#include "ddm-data-model.h"
+#include "ddm-data-resource.h"
+
+G_BEGIN_DECLS
+
+DDMClientNotificationSet *_ddm_client_notification_set_new (DDMDataModel *model);
+
+void _ddm_client_notification_set_add (DDMClientNotificationSet *notification_set,
+				       DDMDataResource          *resource,
+				       DDMClient                *client,
+				       DDMDataFetch             *fetch,
+				       GSList                   *changed_properties);
+
+void   _ddm_client_notification_set_add_feed_timestamp (DDMClientNotificationSet *notification_set,
+                                                        DDMFeed                  *feed,
+                                                        gint64                    timestamp);
+
+ void _ddm_client_notification_set_add_work_items (DDMClientNotificationSet *notification_set);
+
+G_END_DECLS
+
+#endif /* __DDM_CLIENT_NOTIFICATION_INTERNAL_H__ */
+

Modified: dumbhippo/trunk/client/common/ddm/ddm-client-notification.c
===================================================================
--- dumbhippo/trunk/client/common/ddm/ddm-client-notification.c	2008-01-18 04:50:58 UTC (rev 7235)
+++ dumbhippo/trunk/client/common/ddm/ddm-client-notification.c	2008-01-18 13:59:13 UTC (rev 7236)
@@ -1,6 +1,7 @@
 /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
 
 #include "ddm-client-notification.h"
+#include "ddm-client-notification-internal.h"
 #include "ddm-data-model-internal.h"
 #include "ddm-work-item.h"
 
@@ -9,6 +10,7 @@
 
     DDMDataModel *model;
     GHashTable *work_items;
+    GHashTable *feed_timestamps;
 };
 
 DDMClientNotificationSet *
@@ -30,7 +32,7 @@
 }
 
 DDMClientNotificationSet *
-_ddm_client_notification_set_ref (DDMClientNotificationSet *notification_set)
+ddm_client_notification_set_ref (DDMClientNotificationSet *notification_set)
 {
     g_return_val_if_fail (notification_set != NULL, NULL);
     g_return_val_if_fail (notification_set->refcount > 0, NULL);
@@ -41,7 +43,7 @@
 }
 
 void
-_ddm_client_notification_set_unref (DDMClientNotificationSet *notification_set)
+ddm_client_notification_set_unref (DDMClientNotificationSet *notification_set)
 {
     g_return_if_fail (notification_set != NULL);
     g_return_if_fail (notification_set->refcount > 0);
@@ -49,6 +51,8 @@
     notification_set->refcount--;
     if (notification_set->refcount == 0) {
         g_hash_table_destroy(notification_set->work_items);
+        if (notification_set->feed_timestamps)
+            g_hash_table_destroy(notification_set->feed_timestamps);
         g_free(notification_set);
     }
 }
@@ -66,13 +70,54 @@
 
     work_item = g_hash_table_lookup(notification_set->work_items, client);
     if (work_item == NULL) {
-        work_item = _ddm_work_item_notify_client_new(notification_set->model, client);
+        work_item = _ddm_work_item_notify_client_new(notification_set->model, notification_set, client);
         g_hash_table_insert(notification_set->work_items, client, work_item);
     }
 
     _ddm_work_item_notify_client_add(work_item, resource, fetch, changed_properties);
 }
 
+
+void
+_ddm_client_notification_set_add_feed_timestamp (DDMClientNotificationSet *notification_set,
+                                                 DDMFeed                  *feed,
+                                                 gint64                    timestamp)
+{
+    gint64 *timestamp_ptr;
+    
+    if (notification_set->feed_timestamps == NULL) {
+        notification_set->feed_timestamps = g_hash_table_new_full(g_direct_hash, NULL,
+                                                                 (GDestroyNotify)g_object_unref,
+                                                                 (GDestroyNotify)g_free);
+    }
+
+    timestamp_ptr = g_hash_table_lookup(notification_set->feed_timestamps, feed);
+    if (timestamp_ptr == NULL) {
+        timestamp_ptr = g_new(gint64, 1);
+        *timestamp_ptr = timestamp;
+
+        g_hash_table_insert(notification_set->feed_timestamps, g_object_ref(feed), timestamp_ptr);
+    } else {
+        *timestamp_ptr = MIN(*timestamp_ptr, timestamp);
+    }
+}
+
+gint64
+ddm_client_notification_set_get_feed_timestamp (DDMClientNotificationSet *notification_set,
+                                                DDMFeed                  *feed)
+{
+    gint64 *timestamp_ptr;
+    
+    if (notification_set->feed_timestamps == NULL)
+        return G_MAXINT64;
+
+    timestamp_ptr = g_hash_table_lookup(notification_set->feed_timestamps, feed);
+    if (timestamp_ptr == NULL)
+        return G_MAXINT64;
+
+    return *timestamp_ptr;
+}
+
 static void
 add_work_item_foreach (gpointer key,
                        gpointer value,

Modified: dumbhippo/trunk/client/common/ddm/ddm-client-notification.h
===================================================================
--- dumbhippo/trunk/client/common/ddm/ddm-client-notification.h	2008-01-18 04:50:58 UTC (rev 7235)
+++ dumbhippo/trunk/client/common/ddm/ddm-client-notification.h	2008-01-18 13:59:13 UTC (rev 7236)
@@ -3,39 +3,18 @@
 #ifndef __DDM_CLIENT_NOTIFICATION_H__
 #define __DDM_CLIENT_NOTIFICATION_H__
 
-#include "ddm-client.h"
-#include "ddm-data-model.h"
-#include "ddm-data-resource.h"
+#include <ddm/ddm-feed.h>
 
 G_BEGIN_DECLS
 
-/* A "client notification set" is used to track notifications to send
- * out to the different clients. At idle, we iterate over all
- * resources that have changed and add them to the client notification
- * set using _ddm_data_resource_resolve_notifications(). This creates
- * a work item for each client.
- *
- * We then add the work items to the queue, the standard process runs
- * to make sure that we have all fetches complete we need to send out
- * the notification, and when the fetches are complete, we fire the
- * notification on the DDDClient.
- */
-
 typedef struct _DDMClientNotificationSet DDMClientNotificationSet;
 
-DDMClientNotificationSet *_ddm_client_notification_set_new (DDMDataModel *model);
-DDMClientNotificationSet *_ddm_client_notification_set_ref (DDMClientNotificationSet *notification_set);
+DDMClientNotificationSet *ddm_client_notification_set_ref    (DDMClientNotificationSet *notification_set);
+void                      ddm_client_notification_set_unref (DDMClientNotificationSet *notification_set);
 
-void _ddm_client_notification_set_unref (DDMClientNotificationSet *notification_set);
+gint64 ddm_client_notification_set_get_feed_timestamp (DDMClientNotificationSet *notification_set,
+                                                       DDMFeed                  *feed);
 
-void _ddm_client_notification_set_add (DDMClientNotificationSet *notification_set,
-				       DDMDataResource          *resource,
-				       DDMClient                *client,
-				       DDMDataFetch             *fetch,
-				       GSList                   *changed_properties);
-
-void _ddm_client_notification_set_add_work_items (DDMClientNotificationSet *notification_set);
-
 G_END_DECLS
 
 #endif /* __DDM_CLIENT_NOTIFICATION_H__ */

Modified: dumbhippo/trunk/client/common/ddm/ddm-client.c
===================================================================
--- dumbhippo/trunk/client/common/ddm/ddm-client.c	2008-01-18 04:50:58 UTC (rev 7235)
+++ dumbhippo/trunk/client/common/ddm/ddm-client.c	2008-01-18 13:59:13 UTC (rev 7236)
@@ -24,14 +24,15 @@
 }
 
 void
-ddm_client_notify (DDMClient       *client,
-		   DDMDataResource *resource,
-		   GSList          *changed_properties,
-		   gpointer         notification_data)
+ddm_client_notify (DDMClient                *client,
+                   DDMClientNotificationSet *notification_set,
+		   DDMDataResource          *resource,
+		   GSList                   *changed_properties,
+		   gpointer                  notification_data)
 {
     g_return_if_fail(DDM_IS_CLIENT(client));
 
-    DDM_CLIENT_GET_IFACE(client)->notify(client, resource, changed_properties, notification_data);
+    DDM_CLIENT_GET_IFACE(client)->notify(client, notification_set, resource, changed_properties, notification_data);
 }
 
 void

Modified: dumbhippo/trunk/client/common/ddm/ddm-client.h
===================================================================
--- dumbhippo/trunk/client/common/ddm/ddm-client.h	2008-01-18 04:50:58 UTC (rev 7235)
+++ dumbhippo/trunk/client/common/ddm/ddm-client.h	2008-01-18 13:59:13 UTC (rev 7236)
@@ -10,6 +10,7 @@
 #define __DDM_CLIENT_H__
 
 #include <ddm/ddm-data-resource.h>
+#include <ddm/ddm-client-notification.h>
 #include <glib-object.h>
 
 G_BEGIN_DECLS
@@ -38,10 +39,11 @@
 
     /* Called for each resource that has changed
      */
-    void     (* notify)             (DDMClient       *client,
-                                     DDMDataResource *resource,
-                                     GSList          *changed_properties,
-                                     gpointer         notification_data);
+    void     (* notify)             (DDMClient                *client,
+                                     DDMClientNotificationSet *notification_set,
+                                     DDMDataResource          *resource,
+                                     GSList                   *changed_properties,
+                                     gpointer                  notification_data);
 
     /* This notification is all done, send it off
      */
@@ -53,6 +55,7 @@
 
 gpointer ddm_client_begin_notification (DDMClient       *client);
 void     ddm_client_notify             (DDMClient       *client,
+                                        DDMClientNotificationSet *notification_set,
                                         DDMDataResource *resource,
                                         GSList          *changed_properties,
                                         gpointer         notification_data);

Modified: dumbhippo/trunk/client/common/ddm/ddm-data-model.c
===================================================================
--- dumbhippo/trunk/client/common/ddm/ddm-data-model.c	2008-01-18 04:50:58 UTC (rev 7235)
+++ dumbhippo/trunk/client/common/ddm/ddm-data-model.c	2008-01-18 13:59:13 UTC (rev 7236)
@@ -5,6 +5,7 @@
 #include <stdarg.h>
 #include <string.h>
 
+#include "ddm-client-notification-internal.h"
 #include "ddm-data-model-internal.h"
 #include "ddm-data-model-backend.h"
 #include "ddm-data-resource-internal.h"
@@ -276,10 +277,12 @@
 {
     const char *id_string = ddm_data_query_get_id_string(query);
     DDMQName *qname = ddm_data_query_get_qname(query);
+    const char *fetch = ddm_data_query_get_fetch_string(query);
     
     g_debug("%s: Sending to server", id_string);
     g_debug("%s: uri=%s#%s", id_string, qname->uri, qname->name);
-    g_debug("%s: fetch=%s", id_string, ddm_data_query_get_fetch_string(query));
+    if (fetch != NULL)
+        g_debug("%s: fetch=%s", id_string, ddm_data_query_get_fetch_string(query));
     g_hash_table_foreach(ddm_data_query_get_params(query), dump_param_foreach, query);
 }
 
@@ -762,7 +765,7 @@
     g_hash_table_remove_all(model->changed_resources);
 
     _ddm_client_notification_set_add_work_items(notification_set);
-    _ddm_client_notification_set_unref(notification_set);
+    ddm_client_notification_set_unref(notification_set);
 }
 
 static void

Modified: dumbhippo/trunk/client/common/ddm/ddm-data-resource-internal.h
===================================================================
--- dumbhippo/trunk/client/common/ddm/ddm-data-resource-internal.h	2008-01-18 04:50:58 UTC (rev 7235)
+++ dumbhippo/trunk/client/common/ddm/ddm-data-resource-internal.h	2008-01-18 13:59:13 UTC (rev 7236)
@@ -37,6 +37,8 @@
 void _ddm_data_resource_resolve_notifications (DDMDataResource          *resource,
                                                DDMClientNotificationSet *notification_set);
 
+void _ddm_data_resource_reset_notify_timestamps (DDMDataResource *resource);
+
 void _ddm_data_resource_dump(DDMDataResource *resource);
 
 G_END_DECLS

Modified: dumbhippo/trunk/client/common/ddm/ddm-data-resource.c
===================================================================
--- dumbhippo/trunk/client/common/ddm/ddm-data-resource.c	2008-01-18 04:50:58 UTC (rev 7235)
+++ dumbhippo/trunk/client/common/ddm/ddm-data-resource.c	2008-01-18 13:59:13 UTC (rev 7236)
@@ -4,6 +4,7 @@
 #include <string.h>
 #include <stdlib.h>
 
+#include "ddm-client-notification-internal.h"
 #include "ddm-data-fetch.h"
 #include "ddm-feed.h"
 #include "ddm-data-model-internal.h"
@@ -2233,20 +2234,44 @@
     }
 }
 
+static void
+add_to_notification_set(DDMDataResource          *resource,
+                        DDMClientNotificationSet *notification_set,
+                        DDMClient                *client,
+                        DDMDataFetch             *fetch,
+                        GSList                   *changed_properties)
+{
+    GSList *l;
+    
+    _ddm_client_notification_set_add(notification_set,
+                                     resource,
+                                     client,
+                                     fetch,
+                                     changed_properties);
+
+    for (l = resource->properties; l; l = l->next) {
+        DDMDataProperty *property = l->data;
+        if (property->value.type == DDM_DATA_FEED && property->value.u.feed != NULL &&
+            g_slist_find(changed_properties, property->qname) != NULL)
+            _ddm_client_notification_set_add_feed_timestamp(notification_set, property->value.u.feed,
+                                                            ddm_feed_get_notify_timestamp(property->value.u.feed));
+    }
+}
+
 void
 _ddm_data_resource_resolve_notifications (DDMDataResource          *resource,
                                           DDMClientNotificationSet *notification_set)
 {
     GSList *l;
     
+    
     for (l = resource->clients; l; l = l->next) {
         DataClient *data_client = l->data;
 
-        _ddm_client_notification_set_add(notification_set,
-                                         resource,
-                                         data_client->client,
-                                         data_client->fetch,
-                                         resource->changed_properties);
+        add_to_notification_set(resource, notification_set,
+                                data_client->client,
+                                data_client->fetch,
+                                resource->changed_properties);
     }
 
     if (data_resource_needs_local_notifications(resource, resource->changed_properties)) {
@@ -2257,13 +2282,19 @@
          *
          * See also comment in ddm-data-query.c:mark_received_fetches()
          */
-        _ddm_client_notification_set_add(notification_set,
-                                         resource,
-                                         _ddm_data_model_get_local_client(resource->model),
-                                         resource->received_fetch,
-                                         resource->changed_properties);
+        add_to_notification_set(resource, notification_set,
+                                _ddm_data_model_get_local_client(resource->model),
+                                resource->received_fetch,
+                                resource->changed_properties);
+        
     }
 
     g_slist_free(resource->changed_properties);
     resource->changed_properties = NULL;
+    
+    for (l = resource->properties; l; l = l->next) {
+        DDMDataProperty *property = l->data;
+        if (property->value.type == DDM_DATA_FEED && property->value.u.feed != NULL)
+            ddm_feed_reset_notify_timestamp(property->value.u.feed);
+    }
 }

Modified: dumbhippo/trunk/client/common/ddm/ddm-feed.c
===================================================================
--- dumbhippo/trunk/client/common/ddm/ddm-feed.c	2008-01-18 04:50:58 UTC (rev 7235)
+++ dumbhippo/trunk/client/common/ddm/ddm-feed.c	2008-01-18 13:59:13 UTC (rev 7236)
@@ -16,6 +16,7 @@
 
     GList *items;
     GHashTable *nodes_by_resource;
+    gint notify_timestamp;
 };
 
 struct _DDMFeedClass {
@@ -47,6 +48,7 @@
 {
     feed->items = NULL;
     feed->nodes_by_resource = g_hash_table_new(g_direct_hash, NULL);
+    feed->notify_timestamp = 0;
 }
 
 static void
@@ -167,6 +169,8 @@
         g_signal_emit(feed, signals[ITEM_ADDED], 0, resource, timestamp);
     }
 
+    feed->notify_timestamp = MIN(feed->notify_timestamp, timestamp);
+
     return TRUE;
 }
 
@@ -193,6 +197,8 @@
     ddm_data_resource_unref(item->resource);
     g_slice_free(DDMFeedItem, item);
 
+    feed->notify_timestamp = 0;
+
     return TRUE;
 }
 
@@ -227,6 +233,8 @@
     g_return_if_fail(DDM_IS_FEED(feed));
 
     ddm_feed_clear_internal(feed, TRUE);
+    
+    feed->notify_timestamp = 0;
 }
 
 gboolean
@@ -237,7 +245,23 @@
     return feed->items == NULL;
 }
 
+gint64
+ddm_feed_get_notify_timestamp (DDMFeed *feed)
+{
+    g_return_val_if_fail(DDM_IS_FEED(feed), G_MAXINT64);
+    
+    return feed->notify_timestamp;
+}
+
 void
+ddm_feed_reset_notify_timestamp (DDMFeed *feed)
+{
+    g_return_if_fail(DDM_IS_FEED(feed));
+    
+    feed->notify_timestamp = G_MAXINT64;
+}
+
+void
 ddm_feed_iter_init (DDMFeedIter      *iter,
                     DDMFeed          *feed)
 {

Modified: dumbhippo/trunk/client/common/ddm/ddm-feed.h
===================================================================
--- dumbhippo/trunk/client/common/ddm/ddm-feed.h	2008-01-18 04:50:58 UTC (rev 7235)
+++ dumbhippo/trunk/client/common/ddm/ddm-feed.h	2008-01-18 13:59:13 UTC (rev 7236)
@@ -58,6 +58,27 @@
 void     ddm_feed_clear       (DDMFeed         *feed);
 gboolean ddm_feed_is_empty    (DDMFeed          *feed);
 
+/* We handle keeping track of what feed items need to be notified to
+ * downstream clients very simply ... we just keep a single item
+ * timestamp to track what items might not have been sent to
+ * clients. This means that we'll occasionally oversend updates (in
+ * particular, we have to resend the entire feed on any removal) but
+ * we expects to have mostly adds at the end of the feed, and keeping
+ * a log is a) more complicated b) and poses a problem if nobody is
+ * consuming and clearing the log. (Which will be the case for the
+ * data model when used in an application instead of in the
+ * engine... there is no "downstream' to the applications.)
+ */
+
+/* Gets the minimum timestamp for items that need to be resent for a
+ * notification. A timestamp of 0 means "resend everything", so the
+ * first property update should be sent as a REPLACE not an ADD.
+ */
+gint64 ddm_feed_get_notify_timestamp   (DDMFeed *feed);
+
+/* Call when all notifications have been sent out */
+void   ddm_feed_reset_notify_timestamp (DDMFeed *feed);
+
 void     ddm_feed_iter_init   (DDMFeedIter      *iter,
                                DDMFeed          *feed);
 gboolean ddm_feed_iter_next   (DDMFeedIter      *iter,

Modified: dumbhippo/trunk/client/common/ddm/ddm-local-client.c
===================================================================
--- dumbhippo/trunk/client/common/ddm/ddm-local-client.c	2008-01-18 04:50:58 UTC (rev 7235)
+++ dumbhippo/trunk/client/common/ddm/ddm-local-client.c	2008-01-18 13:59:13 UTC (rev 7236)
@@ -53,10 +53,11 @@
 }
 
 static void
-ddm_local_client_notify (DDMClient       *client,
-                         DDMDataResource *resource,
-                         GSList          *changed_properties,
-                         gpointer         notification_data)
+ddm_local_client_notify (DDMClient                *client,
+                         DDMClientNotificationSet *notification_set,
+                         DDMDataResource          *resource,
+                         GSList                   *changed_properties,
+                         gpointer                  notification_data)
 {
     _ddm_data_resource_send_local_notifications(resource, changed_properties);
 }

Modified: dumbhippo/trunk/client/common/ddm/ddm-work-item.c
===================================================================
--- dumbhippo/trunk/client/common/ddm/ddm-work-item.c	2008-01-18 04:50:58 UTC (rev 7235)
+++ dumbhippo/trunk/client/common/ddm/ddm-work-item.c	2008-01-18 13:59:13 UTC (rev 7236)
@@ -26,6 +26,7 @@
 
     union {
         struct {
+            DDMClientNotificationSet *notification_set;
             DDMClient *client;
             GHashTable *resources;
         } notify;
@@ -63,8 +64,9 @@
 }
 
 DDMWorkItem *
-_ddm_work_item_notify_client_new (DDMDataModel *model,
-                                  DDMClient    *client)
+_ddm_work_item_notify_client_new (DDMDataModel             *model,
+                                  DDMClientNotificationSet *notification_set,
+                                  DDMClient                *client)
 {
     DDMWorkItem *item = g_new0(DDMWorkItem, 1);
     item->refcount = 1;
@@ -72,6 +74,7 @@
     item->type = ITEM_NOTIFY;
     item->min_serial = -1;
 
+    item->u.notify.notification_set = ddm_client_notification_set_ref(notification_set);
     item->u.notify.client = g_object_ref(client);
     item->u.notify.resources = g_hash_table_new_full(g_direct_hash, NULL,
                                                      NULL,
@@ -148,6 +151,7 @@
         case ITEM_NOTIFY:
             g_object_unref(item->u.notify.client);
             g_hash_table_destroy(item->u.notify.resources);
+            ddm_client_notification_set_unref(item->u.notify.notification_set);
             break;
         case ITEM_QUERY_RESPONSE:
             break;
@@ -304,6 +308,7 @@
     NotifyProcessClosure *closure = data;
 
     ddm_client_notify(closure->item->u.notify.client,
+                      closure->item->u.notify.notification_set,
                       notify_resource->resource,
                       notify_resource->changed_properties,
                       closure->notification_data);

Modified: dumbhippo/trunk/client/common/ddm/ddm-work-item.h
===================================================================
--- dumbhippo/trunk/client/common/ddm/ddm-work-item.h	2008-01-18 04:50:58 UTC (rev 7235)
+++ dumbhippo/trunk/client/common/ddm/ddm-work-item.h	2008-01-18 13:59:13 UTC (rev 7236)
@@ -4,6 +4,7 @@
 #define __DDM_WORK_ITEM_H__
 
 #include "ddm-client.h"
+#include "ddm-client-notification.h"
 #include "ddm-data-fetch.h"
 #include "ddm-data-model.h"
 
@@ -21,8 +22,9 @@
 
 typedef struct _DDMWorkItem DDMWorkItem;
 
-DDMWorkItem *_ddm_work_item_notify_client_new (DDMDataModel    *model,
-					       DDMClient       *client);
+DDMWorkItem *_ddm_work_item_notify_client_new (DDMDataModel             *model,
+                                               DDMClientNotificationSet *notification_set,
+					       DDMClient                *client);
 
 void _ddm_work_item_notify_client_add (DDMWorkItem     *item,
 				       DDMDataResource *resource,

Modified: dumbhippo/trunk/client/common/ddm/ddm.h
===================================================================
--- dumbhippo/trunk/client/common/ddm/ddm.h	2008-01-18 04:50:58 UTC (rev 7235)
+++ dumbhippo/trunk/client/common/ddm/ddm.h	2008-01-18 13:59:13 UTC (rev 7236)
@@ -15,6 +15,7 @@
 #define DDM_INSIDE_DDM_H 1
 
 #include <ddm/ddm-client.h>
+#include <ddm/ddm-client-notification.h>
 #include <ddm/ddm-data-fetch.h>
 #include <ddm/ddm-data-model.h>
 #include <ddm/ddm-data-model-backend.h>

Modified: dumbhippo/trunk/client/linux/Makefile-libddm.am
===================================================================
--- dumbhippo/trunk/client/linux/Makefile-libddm.am	2008-01-18 04:50:58 UTC (rev 7235)
+++ dumbhippo/trunk/client/linux/Makefile-libddm.am	2008-01-18 13:59:13 UTC (rev 7236)
@@ -46,6 +46,7 @@
 	$(COMMONSRCDIR)/ddm/ddm-client.c			\
 	$(COMMONSRCDIR)/ddm/ddm-client-notification.c		\
 	$(COMMONSRCDIR)/ddm/ddm-client-notification.h		\
+	$(COMMONSRCDIR)/ddm/ddm-client-notification-internal.h  \
 	$(COMMONSRCDIR)/ddm/ddm-condition-parser.c		\
 	$(COMMONSRCDIR)/ddm/ddm-condition.c			\
 	$(COMMONSRCDIR)/ddm/ddm-data-fetch.c			\

Modified: dumbhippo/trunk/client/linux/engine-dbus/hippo-dbus-model-client.c
===================================================================
--- dumbhippo/trunk/client/linux/engine-dbus/hippo-dbus-model-client.c	2008-01-18 04:50:58 UTC (rev 7235)
+++ dumbhippo/trunk/client/linux/engine-dbus/hippo-dbus-model-client.c	2008-01-18 13:59:13 UTC (rev 7236)
@@ -9,13 +9,13 @@
 
 static void hippo_dbus_model_client_iface_init(DDMClientIface *iface);
 
-static void add_resource_to_message (HippoDBusModelClient *client,
-                                     DBusMessageIter      *resource_array_iter,
-                                     DDMDataResource      *resource,
-                                     DDMDataFetch         *fetch,
-                                     gboolean              indirect,
-                                     gboolean              is_notification,
-                                     GSList               *changed_properties);
+static void add_resource_to_message (HippoDBusModelClient     *client,
+                                     DDMClientNotificationSet *notification_set,
+                                     DBusMessageIter          *resource_array_iter,
+                                     DDMDataResource          *resource,
+                                     DDMDataFetch             *fetch,
+                                     gboolean                  indirect,
+                                     GSList                   *changed_properties);
 
 struct _HippoDBusModelClient {
     GObject parent;
@@ -303,35 +303,47 @@
 }
 
 static void
-add_property_children_to_message(HippoDBusModelClient *client,
-                                 DBusMessageIter      *resource_array_iter,
-                                 DDMDataProperty      *property,
-                                 DDMDataFetch         *children)
+add_property_children_to_message(HippoDBusModelClient     *client,
+                                 DDMClientNotificationSet *notification_set,
+                                 DBusMessageIter          *resource_array_iter,
+                                 DDMDataProperty          *property,
+                                 DDMDataFetch             *children)
 {
     DDMDataValue value;
             
     ddm_data_property_get_value(property, &value);
     
     if (value.type == DDM_DATA_RESOURCE) {
-        add_resource_to_message(client, resource_array_iter, value.u.resource, children, TRUE, FALSE, NULL);
+        add_resource_to_message(client, notification_set, resource_array_iter, value.u.resource, children, TRUE, NULL);
     } else if (value.type == (DDM_DATA_RESOURCE | DDM_DATA_LIST)) {
         GSList *l;
         for (l = value.u.list; l; l = l->next)
-            add_resource_to_message(client, resource_array_iter, l->data, children, TRUE, FALSE, NULL);
+            add_resource_to_message(client, notification_set, resource_array_iter, l->data, children, TRUE, NULL);
     } else if (value.type == DDM_DATA_FEED && value.u.feed != NULL) {
         DDMFeedIter feed_iter;
         DDMDataResource *item_resource;
+        gint64 min_timestamp;
+        gint64 item_timestamp;
 
+        if (notification_set != NULL)
+            min_timestamp = ddm_client_notification_set_get_feed_timestamp(notification_set, value.u.feed);
+        else
+            min_timestamp = 0;
+
         ddm_feed_iter_init(&feed_iter, value.u.feed);
-        while (ddm_feed_iter_next(&feed_iter, &item_resource, NULL)) {
-            add_resource_to_message(client, resource_array_iter, item_resource, children, TRUE, FALSE, NULL);
+        while (ddm_feed_iter_next(&feed_iter, &item_resource, &item_timestamp)) {
+            if (item_timestamp < min_timestamp)
+                break;
+                
+            add_resource_to_message(client, notification_set, resource_array_iter, item_resource, children, TRUE, NULL);
         }
     }
 }
 
 static void
-add_property_to_message(DBusMessageIter *property_array_iter,
-                        DDMDataProperty *property)
+add_property_to_message(DBusMessageIter          *property_array_iter,
+                        DDMDataProperty          *property,
+                        DDMClientNotificationSet *notification_set)
 {
     DDMDataCardinality cardinality;
     DDMDataValue value;
@@ -361,11 +373,20 @@
             DDMFeedIter feed_iter;
             DDMDataResource *item_resource;
             gint64 item_timestamp;
+            gint64 min_timestamp;
             gboolean first;
 
+            if (notification_set != NULL)
+                min_timestamp = ddm_client_notification_set_get_feed_timestamp(notification_set, value.u.feed);
+            else
+                min_timestamp = 0;
+
             ddm_feed_iter_init(&feed_iter, value.u.feed);
-            first = TRUE;
+            first = min_timestamp == 0;
             while (ddm_feed_iter_next(&feed_iter, &item_resource, &item_timestamp)) {
+                if (item_timestamp < min_timestamp)
+                    break;
+                
                 add_feed_property_value_to_message(property_array_iter, property_qname,
                                                    first ? DDM_DATA_UPDATE_REPLACE : DDM_DATA_UPDATE_ADD,
                                                    item_resource, item_timestamp);
@@ -380,13 +401,13 @@
 }
 
 static void
-add_resource_to_message(HippoDBusModelClient *client,
-                        DBusMessageIter      *resource_array_iter,
-                        DDMDataResource      *resource,
-                        DDMDataFetch         *fetch,
-                        gboolean              indirect,
-                        gboolean              is_notification,
-                        GSList               *changed_properties)
+add_resource_to_message(HippoDBusModelClient     *client,
+                        DDMClientNotificationSet *notification_set,
+                        DBusMessageIter          *resource_array_iter,
+                        DDMDataResource          *resource,
+                        DDMDataFetch             *fetch,
+                        gboolean                  indirect,
+                        GSList                   *changed_properties)
 {
     DDMDataFetchIter fetch_iter;
     DataClientConnection *connection;
@@ -404,7 +425,7 @@
         g_hash_table_insert(client->connections, (char *)ddm_data_resource_get_resource_id(resource), connection);
     }
 
-    if (is_notification) {
+    if (notification_set != NULL && !indirect) {
         new_fetch = ddm_data_fetch_ref(fetch);
     } else {
         if (connection->fetch)
@@ -438,10 +459,10 @@
             if (!children)
                 continue;
             
-            if (is_notification && g_slist_find(changed_properties, ddm_data_property_get_qname(property)) == NULL)
+            if (notification_set != NULL && !indirect && g_slist_find(changed_properties, ddm_data_property_get_qname(property)) == NULL)
                 continue;
             
-            add_property_children_to_message(client, resource_array_iter, property, children);
+            add_property_children_to_message(client, notification_set, resource_array_iter, property, children);
         }
         ddm_data_fetch_iter_clear(&fetch_iter);
     }
@@ -464,10 +485,10 @@
 
             ddm_data_fetch_iter_next(&fetch_iter, &property, NULL);
 
-            if (is_notification && g_slist_find(changed_properties, ddm_data_property_get_qname(property)) == NULL)
+            if (notification_set != NULL && !indirect && g_slist_find(changed_properties, ddm_data_property_get_qname(property)) == NULL)
                 continue;
             
-            add_property_to_message(&property_array_iter, property);
+            add_property_to_message(&property_array_iter, property, notification_set);
         }
         
         ddm_data_fetch_iter_clear(&fetch_iter);
@@ -531,10 +552,11 @@
 }
 
 static void
-hippo_dbus_model_client_notify (DDMClient       *client,
-                                DDMDataResource *resource,
-                                GSList          *changed_properties,
-                                gpointer         notification_data)
+hippo_dbus_model_client_notify (DDMClient                *client,
+                                DDMClientNotificationSet *notification_set,
+                                DDMDataResource          *resource,
+                                GSList                   *changed_properties,
+                                gpointer                  notification_data)
 {
     HippoDBusModelClient *dbus_client = HIPPO_DBUS_MODEL_CLIENT(client);
     DataClientConnection *client_connection = g_hash_table_lookup(dbus_client->connections,
@@ -550,10 +572,10 @@
 
     dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(ssba(ssyyyv))", &array_iter);
 
-    add_resource_to_message(dbus_client, &array_iter,
+    add_resource_to_message(dbus_client, notification_set, &array_iter,
                             resource, client_connection->fetch,
                             FALSE,
-                            TRUE, changed_properties);
+                            changed_properties);
     
     dbus_message_iter_close_container(&iter, &array_iter);
 
@@ -639,7 +661,7 @@
     dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(ssba(ssyyyv))", &array_iter);
 
     for (l = results; l; l = l->next) {
-        add_resource_to_message(closure->client, &array_iter, l->data, closure->fetch, FALSE, FALSE, NULL);
+        add_resource_to_message(closure->client, NULL, &array_iter, l->data, closure->fetch, FALSE, NULL);
     }
     
     dbus_message_iter_close_container(&iter, &array_iter);



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