Skip to content

Commit 2a8c8a8

Browse files
committed
Fix slow list_version queries who have O(#symbols*#versions*#snapshots) complexity
1 parent 9395e4c commit 2a8c8a8

File tree

3 files changed

+34
-7
lines changed

3 files changed

+34
-7
lines changed

CHANGES.md

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
### 1.61
44
* Feature: #288 Mapping reads and writes over chunks in chunkstore
55
* Bugfix: #508 VersionStore: list_symbols and read now always returns latest version
6+
* Bugfix: #512 Improved performance for list_versions
67

78
### 1.60 (2018-2-13)
89
* Bugfix: #503 ChunkStore: speedup check for -1 segments

arctic/store/version_store.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -247,19 +247,23 @@ def list_versions(self, symbol=None, snapshot=None, latest_only=False):
247247
raise NoDataFoundException('No snapshot %s in library %s' % (snapshot, self._arctic_lib.get_name()))
248248

249249
versions = []
250+
snapshots = None
250251
for symbol in symbols:
251252
query['symbol'] = symbol
252253
seen_symbols = set()
253254
for version in self._versions.find(query, projection=['symbol', 'version', 'parent', 'metadata.deleted'], sort=[('version', -1)]):
254255
if latest_only and version['symbol'] in seen_symbols:
255256
continue
257+
if snapshots is None:
258+
# populate only once and if is really going to be used
259+
snapshots = {ss.get('_id'): ss.get('name') for ss in self._snapshots.find()}
256260
seen_symbols.add(version['symbol'])
257261
meta = version.get('metadata')
258262
versions.append({'symbol': version['symbol'], 'version': version['version'],
259263
'deleted': meta.get('deleted', False) if meta else False,
260264
# We return offset-aware datetimes in Local Time.
261265
'date': ms_to_datetime(datetime_to_ms(version['_id'].generation_time)),
262-
'snapshots': self._find_snapshots(version.get('parent', []))})
266+
'snapshots': [snapshots.get(s) for s in version.get('parent', [])]})
263267
return versions
264268

265269
def _find_snapshots(self, parent_ids):

tests/unit/store/test_version_store.py

+28-6
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,41 @@ def test_delete_version_version_not_found():
2929
def test_list_versions_localTime():
3030
# Object ID's are stored in UTC. We need to ensure that the returned times
3131
# for versions are in the local TimeZone
32-
vs = create_autospec(VersionStore, instance=True,
33-
_versions=Mock())
34-
vs._find_snapshots.return_value = 'snap'
32+
vs = create_autospec(VersionStore, instance=True, _versions=Mock(), _snapshots=Mock())
33+
mocked_snap_resp = [{'_id': 'abcde', 'name': 'snap'}]
34+
vs._snapshots.find.return_value = mocked_snap_resp
35+
vs._snapshots.find_one.return_value = mocked_snap_resp
3536
date = dt(2013, 4, 1, 9, 0)
3637
vs._versions.find.return_value = [{'_id': bson.ObjectId.from_datetime(date),
37-
'symbol': 's', 'version': 10, 'metadata': None}]
38-
38+
'symbol': 's',
39+
'version': 10,
40+
'metadata': None,
41+
'parent': [mocked_snap_resp[0]['_id']]}]
3942
version = list(VersionStore.list_versions(vs, "symbol"))[0]
4043
local_date = date.replace(tzinfo=mktz("UTC"))
4144
assert version == {'symbol': version['symbol'], 'version': version['version'],
4245
# We return naive datetimes in 'default' time, which is London for us
4346
'date': local_date,
44-
'snapshots': 'snap',
47+
'snapshots': ['snap'],
48+
'deleted': False}
49+
50+
51+
def test_list_versions_no_snapshot():
52+
vs = create_autospec(VersionStore, instance=True, _versions=Mock(), _snapshots=Mock())
53+
vs._snapshots.find.return_value = []
54+
vs._snapshots.find_one.return_value = []
55+
date = dt(2013, 4, 1, 9, 0)
56+
vs._versions.find.return_value = [{'_id': bson.ObjectId.from_datetime(date),
57+
'symbol': 's',
58+
'version': 10,
59+
'metadata': None,
60+
'parent': []}]
61+
version = list(VersionStore.list_versions(vs, "symbol"))[0]
62+
local_date = date.replace(tzinfo=mktz("UTC"))
63+
assert version == {'symbol': version['symbol'],
64+
'version': version['version'],
65+
'date': local_date,
66+
'snapshots': [],
4567
'deleted': False}
4668

4769

0 commit comments

Comments
 (0)