Subject: [PATCH] Invert index_updated logic #2095

From: Aleksey Lim <[email-masked]>
Date: Wed, 14 Jul 2010 11:53:27 +0000

---
 src/carquinyol/datastore.py     |   14 ++++++++------
 src/carquinyol/indexstore.py    |   25 +++++++++++++++++++++++++
 src/carquinyol/layoutmanager.py |   25 -------------------------
 3 files changed, 33 insertions(+), 31 deletions(-)

diff --git a/src/carquinyol/datastore.py b/src/carquinyol/datastore.py
index a556869..82a6207 100644
--- a/src/carquinyol/datastore.py
+++ b/src/carquinyol/datastore.py
@@ -62,6 +62,7 @@ class DataStore(dbus.service.Object):
         self._file_store = FileStore()
         self._optimizer = Optimizer(self._file_store, self._metadata_store)
         self._index_store = IndexStore()
+        self._index_updating = False
 
         if migrated:
             self._rebuild_index()
@@ -74,7 +75,7 @@ class DataStore(dbus.service.Object):
             self._rebuild_index()
             return
 
-        if not layoutmanager.get_instance().index_updated:
+        if not self._index_store.index_updated:
             logging.debug('Index is not up-to-date, will update')
             self._update_index()
 
@@ -97,7 +98,6 @@ class DataStore(dbus.service.Object):
 
     def _rebuild_index(self):
         """Remove and recreate index."""
-        layoutmanager.get_instance().index_updated = False
         self._index_store.close_index()
         self._index_store.remove_index()
         self._index_store.open_index()
@@ -108,6 +108,7 @@ class DataStore(dbus.service.Object):
         uids = layoutmanager.get_instance().find_all()
         logging.debug('Going to update the index with object_ids %r',
             uids)
+        self._index_updating = True
         gobject.idle_add(lambda: self.__update_index_cb(uids),
                             priority=gobject.PRIORITY_LOW)
 
@@ -126,8 +127,9 @@ class DataStore(dbus.service.Object):
                     logging.exception('Error processing %r', uid)
 
         if not uids:
+            self._index_store.flush()
+            self._index_updating = False
             logging.debug('Finished updating index.')
-            layoutmanager.get_instance().index_updated = True
             return False
         else:
             return True
@@ -216,14 +218,14 @@ class DataStore(dbus.service.Object):
         logging.debug('datastore.find %r', query)
         t = time.time()
 
-        if layoutmanager.get_instance().index_updated:
+        if not self._index_updating:
             try:
                 uids, count = self._index_store.find(query)
             except Exception:
                 logging.exception('Failed to query index, will rebuild')
                 self._rebuild_index()
 
-        if not layoutmanager.get_instance().index_updated:
+        if self._index_updating:
             logging.warning('Index updating, returning all entries')
             return self._find_all(query, properties)
 
@@ -290,7 +292,7 @@ class DataStore(dbus.service.Object):
             raise ValueError('Only ''activity'' is a supported property name')
         if query:
             raise ValueError('The query parameter is not supported')
-        if layoutmanager.get_instance().index_updated:
+        if not self._index_updating:
             return self._index_store.get_activities()
         else:
             logging.warning('Index updating, returning an empty list')
diff --git a/src/carquinyol/indexstore.py b/src/carquinyol/indexstore.py
index 8a69334..fbef496 100644
--- a/src/carquinyol/indexstore.py
+++ b/src/carquinyol/indexstore.py
@@ -214,6 +214,8 @@ class IndexStore(object):
         self._database = None
         self._flush_timeout = None
         self._pending_writes = 0
+        self._index_updated_path = os.path.join(
+                layoutmanager.get_instance().get_root_path(), 'index_updated')
 
     def open_index(self):
         index_path = layoutmanager.get_instance().get_index_path()
@@ -298,6 +300,7 @@ class IndexStore(object):
 
     def delete(self, uid):
         self._database.delete_document(_PREFIX_FULL_VALUE + _PREFIX_UID + uid)
+        self._flush()
 
     def get_activities(self):
         activities = []
@@ -306,6 +309,25 @@ class IndexStore(object):
             activities.append(term.term[len(prefix):])
         return activities
 
+    def flush(self):
+        self._flush(True)
+
+    def get_index_updated(self):
+        return os.path.exists(self._index_updated_path)
+
+    index_updated = property(get_index_updated)
+
+    def _set_index_updated(self, index_updated):
+        if index_updated != self.index_updated:
+            if index_updated:
+                index_updated_file = open(self._index_updated_path, 'w')
+                # index_updated = True will happen every
+                # indexstore._FLUSH_TIMEOUT seconds, so it is ok to fsync
+                os.fsync(index_updated_file.fileno())
+                index_updated_file.close()
+            else:
+                os.remove(self._index_updated_path)
+
     def _flush_timeout_cb(self):
         self._flush(True)
         return False
@@ -314,6 +336,8 @@ class IndexStore(object):
         """Called after any database mutation"""
         logging.debug('IndexStore.flush: %r %r', force, self._pending_writes)
 
+        self._set_index_updated(False)
+
         if self._flush_timeout is not None:
             gobject.source_remove(self._flush_timeout)
             self._flush_timeout = None
@@ -322,6 +346,7 @@ class IndexStore(object):
         if force or self._pending_writes > _FLUSH_THRESHOLD:
             self._database.flush()
             self._pending_writes = 0
+            self._set_index_updated(True)
         else:
             self._flush_timeout = gobject.timeout_add_seconds(_FLUSH_TIMEOUT,
                                                       self._flush_timeout_cb)
diff --git a/src/carquinyol/layoutmanager.py b/src/carquinyol/layoutmanager.py
index 8402b6d..5c67203 100644
--- a/src/carquinyol/layoutmanager.py
+++ b/src/carquinyol/layoutmanager.py
@@ -37,16 +37,6 @@ class LayoutManager(object):
         self._create_if_needed(self.get_checksums_dir())
         self._create_if_needed(self.get_queue_path())
 
-        index_updated_path = os.path.join(self._root_path, 'index_updated')
-        if os.path.exists(index_updated_path):
-            self._index_updated = True
-        elif self._is_empty():
-            open(index_updated_path, 'w').close()
-            self.set_version(CURRENT_LAYOUT_VERSION)
-            self._index_updated = True
-        else:
-            self._index_updated = False
-
     def _create_if_needed(self, path):
         if not os.path.exists(path):
             os.makedirs(path)
@@ -89,21 +79,6 @@ class LayoutManager(object):
     def get_queue_path(self):
         return os.path.join(self.get_checksums_dir(), 'queue')
 
-    def _is_index_updated(self):
-        return self._index_updated
-
-    def _set_index_updated(self, index_updated):
-        if index_updated != self._index_updated:
-            self._index_updated = index_updated
-
-            index_updated_path = os.path.join(self._root_path, 'index_updated')
-            if os.path.exists(index_updated_path):
-                os.remove(index_updated_path)
-            else:
-                open(index_updated_path, 'w').close()
-
-    index_updated = property(_is_index_updated, _set_index_updated)
-
     def find_all(self):
         uids = []
         for f in os.listdir(self._root_path):
-- 
1.7.1.1