Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Silbe <sascha-pgp@silbe.org>2013-06-22 07:19:02 (GMT)
committer Sascha Silbe <sascha-pgp@silbe.org>2013-06-22 07:19:02 (GMT)
commit2111710c5f18fa0409fa181e5bebf660fc7823cb (patch)
tree049f0da7ef90322f9411bc7410ca889e4acb4361
parent5a1d619477c14c82be3bcc199a203a594899b234 (diff)
fsemulation: don't try to duplicate data store / Xapian matching
_matches_root_query() was meant to verify that a requested entity has actually been exported by the user (using root_query). But in order to do that, a lot of the matching functionality in the data store (usually implemented using Xapian) would have to be duplicated for any except the most basic export selections to work. E.g. exporting based on tags needs to work on parts (words) of a single value, rather than an exact match on the full string. Instead, let the data store do the verification by using its searching API even if we already know the object id. There's some performance impact to this, but it's not clear a reasonably functional _matches_root_query() would be much faster.
-rw-r--r--fsemulation.py33
1 files changed, 21 insertions, 12 deletions
diff --git a/fsemulation.py b/fsemulation.py
index 5077265..58120fb 100644
--- a/fsemulation.py
+++ b/fsemulation.py
@@ -120,8 +120,8 @@ class DataStore(object):
Only return the latest version of each entry for data stores with
version support.
"""
- query = dict(query or {})
- query.update(self._root_query)
+ query = self._merge_root_query(query)
+
if self._data_store.dbus_interface == DS_DBUS_INTERFACE2:
options = {'metadata': ['tree_id', 'version_id'],
'order_by': ['-timestamp']}
@@ -149,8 +149,7 @@ class DataStore(object):
Returns a list of tuples containing the object_id and metadata.
"""
- query = dict(query or {})
- query.update(self._root_query)
+ query = self._merge_root_query(query)
properties = list(_USEFUL_PROPS)
if self._data_store.dbus_interface == DS_DBUS_INTERFACE2:
@@ -187,14 +186,14 @@ class DataStore(object):
def list_tree_ids(self, query=None):
"""Retrieve the tree_ids of all (matching) data store entries"""
+ query = self._merge_root_query(query)
return [unicode(entry[0]) for entry in self.list_object_ids(query)]
def list_property_values(self, name, query=None):
"""Return all unique values of the given property"""
assert isinstance(name, unicode)
+ query = self._merge_root_query(query)
- query = dict(query or {})
- query.update(self._root_query)
if self._data_store.dbus_interface == DS_DBUS_INTERFACE2:
options = {'metadata': [name], 'all_versions': True}
entries = self._data_store.find(query, options,
@@ -219,7 +218,7 @@ class DataStore(object):
return False
raise
- return self._matches_root_query(entry)
+ return True
def check_tree_id(self, tree_id):
"""Return True if the given tree_id identifies a data store entry"""
@@ -283,11 +282,17 @@ class DataStore(object):
else:
assert isinstance(object_id, unicode)
+ query['uid'] = object_id
+ results = self._data_store.find(query, names or [],
+ timeout=DBUS_TIMEOUT_MAX,
+ byte_arrays=True)[0]
+
metadata = self._data_store.get_properties(object_id,
byte_arrays=True)
- if not self._matches_root_query(metadata):
+ if not results:
raise ValueError('Object %r does not exist' % (object_id, ))
+ metadata = results[0]
metadata['uid'] = object_id
if names:
metadata = dict([(name, metadata[name]) for name in names
@@ -436,10 +441,14 @@ class DataStore(object):
timeout=DBUS_TIMEOUT_MAX)
return unicode(object_id)
- def _matches_root_query(self, metadata):
- """Return True if metadata matches the root query"""
- return not [True for key, value in self._root_query.items()
- if metadata.get(key) != value]
+ def _merge_root_query(self, query):
+ query = dict(query or {})
+ xapian_query = query.get('query', '')
+ query.update(self._root_query)
+ if ('query' in self._root_query) and xapian_query:
+ query['query'] = '(%s) AND (%s)' % (self._root_query['query'],
+ xapian_query)
+ return query
def _convert_metadata(self, metadata):
"""Convert metadata (as returned by the data store) to a unicode dict