Source code for ploneintranet.microblog.utils

# coding=utf-8
from BTrees import LLBTree

import time


[docs]def longkeysortreverse(btreeish, minv=None, maxv=None, limit=None): """Performance optimized keyspace accessor. Returns an iterable of btreeish keys, reverse sorted by key. Expects a btreeish with long(microsec) keys. In case a limit, but neither minv nor maxv is given, optimizates by not sorting the whole keyspace, but instead heuristically chunk the keyspace and sort only chunks, until the limit is reached. The reason for this is that we want the most recent slice, which is last in the accessor, so we cannot just start iterating the slice. Basically we want to iterate backwards. """ try: accessor = btreeish.keys except AttributeError: accessor = LLBTree.TreeSet(btreeish).keys if minv or limit is None: return _longkeysortreverse_direct(accessor, minv, maxv, limit) else: return _longkeysortreverse_optimized(accessor, maxv, limit)
[docs]def _longkeysortreverse_direct(accessor, minv, maxv, limit): """minv or limit is None: do not optimize""" i = 0 keys = sorted(accessor(min=minv, max=maxv), reverse=True) for key in keys: yield key i += 1 if i == limit: return # reached limit return # reached end of keyset
[docs]def _longkeysortreverse_optimized(accessor, maxv, limit): """not minv and limit is not None: Optimize by winding backward until limit is reached. This is the normal scenario: walking back 15 at a time. """ i = 0 # first auto-chunk: last hour if maxv: # no use searching for more recent updates than maxv tmin = long(maxv - 3600 * 1e6) else: tmin = long((time.time() - 3600) * 1e6) keys = sorted(accessor(min=tmin, max=maxv), reverse=True) for key in keys: yield key i += 1 if i == limit: return # no need to sort 2nd and 3rd chunks # second auto-chunk: last day until last hour tmax = tmin - 1 # avoid off-by-one error tmin = long(tmax - 23 * 3600 * 1e6) keys = sorted(accessor(min=tmin, max=tmax), reverse=True) for key in keys: yield key i += 1 if i == limit: return # no need to sort 3rd chunk # final auto-chunk: everything else tmax = tmin - 1 # avoid off-by-one error keys = sorted(accessor(max=tmax), reverse=True) for key in keys: yield key i += 1 if i == limit: return