def timeseries_time_value_pairs(response, **options): """ Return the ``response`` as a list of (time, value) pairs. ``options`` may contain a callable ``timestamp_cast_func`` used to cast the timestamp return values to times. Timestamps are milliseconds since the epoch as 64 bit signed integers. """ if not response: return response timestamp_cast_func = options.get('timestamp_cast_func', int) it = iter(response) return list(izip(imap(timestamp_cast_func, it), it))
def run_benchmark(self): group_names = [group['name'] for group in self.ARGUMENTS] group_values = [group['values'] for group in self.ARGUMENTS] for value_set in itertools.product(*group_values): pairs = list(izip(group_names, value_set)) arg_string = ', '.join(['%s=%s' % (p[0], p[1]) for p in pairs]) sys.stdout.write('Benchmark: %s... ' % arg_string) sys.stdout.flush() kwargs = dict(pairs) setup = functools.partial(self.setup, **kwargs) run = functools.partial(self.run, **kwargs) t = timeit.timeit(stmt=run, setup=setup, number=1000) sys.stdout.write('%f\n' % t) sys.stdout.flush()
def tsadd(self, name, *times_and_values, **options): """ Add any number of ``time``, ``value`` pairs to the time series that is specified by the given key ``name``. Pairs can be specified as ``times_and_values``, in the form of: ``time1``, ``value1``, ``time2``, ``value2``,... This is useful in storing time series like data where the ``name`` could define a metric, the ``time`` is the time when the metric was generated and ``value`` is the value of the metric at the given time. ``times`` can be of different types. They are converted to timestamps - 64 bit signed integers - using a callable ``time_cast_func`` within options. ``times`` should be python datetimes if ``time_cast_func`` isn't set. A naive datetime is accounted an UTC datetime. ``times`` could be the time in seconds since the epoch (unix time) as a floating point number in case ``time_cast_func`` is set to ``unixtime_to_timestamp`` for instance. Note: The unix time is naive, that is, it doesn't know its timezone. ``times`` MUST be in UTC! To provide raw timestamps set ``time_cast_func`` to None. """ pieces = ['TSADD', name] if times_and_values: if len(times_and_values) % 2 != 0: raise RedisError("TSADD requires an equal number of " "times and values") time_cast_func = options.get('time_cast_func', DatetimeToTimestamp(pytz.utc)) if time_cast_func is None: pieces.extend(times_and_values) else: pieces.extend( chain.from_iterable(izip(imap(time_cast_func, times_and_values[0::2]), times_and_values[1::2]))) return self.execute_command(*pieces)
def sort(self, name, start=None, num=None, by=None, get=None, desc=False, alpha=False, store=None, groups=None): """Sort and return the list, set or sorted set at ``name``. ``start`` and ``num`` allow for paging through the sorted data ``by`` allows using an external key to weight and sort the items. Use an "*" to indicate where in the key the item value is located ``get`` allows for returning items from external keys rather than the sorted data itself. Use an "*" to indicate where int he key the item value is located ``desc`` allows for reversing the sort ``alpha`` allows for sorting lexicographically rather than numerically ``store`` allows for storing the result of the sort into the key ``store`` ClusterImpl: A full implementation of the server side sort mechanics because many of the options work on multiple keys that can exist on multiple servers. """ if (start is None and num is not None) or \ (start is not None and num is None): raise RedisError( "RedisError: ``start`` and ``num`` must both be specified") try: data_type = b(self.type(name)) if data_type == b("none"): return [] elif data_type == b("set"): data = list(self.smembers(name))[:] elif data_type == b("list"): data = self.lrange(name, 0, -1) else: raise RedisClusterException( "Unable to sort data type : {}".format(data_type)) if by is not None: # _sort_using_by_arg mutates data so we don't # need need a return value. self._sort_using_by_arg(data, by, alpha) elif not alpha: data.sort(key=self._strtod_key_func) else: data.sort() if desc: data = data[::-1] if not (start is None and num is None): data = data[start:start + num] if get: data = self._retrive_data_from_sort(data, get) if store is not None: if data_type == b("set"): self.delete(store) self.rpush(store, *data) elif data_type == b("list"): self.delete(store) self.rpush(store, *data) else: raise RedisClusterException( "Unable to store sorted data for data type : {}". format(data_type)) return len(data) if groups: if not get or isinstance(get, basestring) or len(get) < 2: raise DataError('when using "groups" the "get" argument ' 'must be specified and contain at least ' 'two keys') n = len(get) return list(izip(*[data[i::n] for i in range(n)])) else: return data except KeyError: return []
def sort(self, name, start=None, num=None, by=None, get=None, desc=False, alpha=False, store=None, groups=None): """Sort and return the list, set or sorted set at ``name``. :start: and :num: allow for paging through the sorted data :by: allows using an external key to weight and sort the items. Use an "*" to indicate where in the key the item value is located :get: allows for returning items from external keys rather than the sorted data itself. Use an "*" to indicate where int he key the item value is located :desc: allows for reversing the sort :alpha: allows for sorting lexicographically rather than numerically :store: allows for storing the result of the sort into the key `store` ClusterImpl: A full implementation of the server side sort mechanics because many of the options work on multiple keys that can exist on multiple servers. """ if (start is None and num is not None) or \ (start is not None and num is None): raise RedisError("RedisError: ``start`` and ``num`` must both be specified") try: data_type = b(self.type(name)) if data_type == b("none"): return [] elif data_type == b("set"): data = list(self.smembers(name))[:] elif data_type == b("list"): data = self.lrange(name, 0, -1) else: raise RedisClusterException("Unable to sort data type : {0}".format(data_type)) if by is not None: # _sort_using_by_arg mutates data so we don't # need need a return value. self._sort_using_by_arg(data, by, alpha) elif not alpha: data.sort(key=self._strtod_key_func) else: data.sort() if desc: data = data[::-1] if not (start is None and num is None): data = data[start:start + num] if get: data = self._retrive_data_from_sort(data, get) if store is not None: if data_type == b("set"): self.delete(store) self.rpush(store, *data) elif data_type == b("list"): self.delete(store) self.rpush(store, *data) else: raise RedisClusterException("Unable to store sorted data for data type : {0}".format(data_type)) return len(data) if groups: if not get or isinstance(get, basestring) or len(get) < 2: raise DataError('when using "groups" the "get" argument ' 'must be specified and contain at least ' 'two keys') n = len(get) return list(izip(*[data[i::n] for i in range(n)])) else: return data except KeyError: return []