diff --git a/README.md b/README.md index 05c47d9..5782ed3 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,8 @@ + Push and Pop support batch operation + Using Lua scripts to save RTT (Round Trip Time) + Support getting indexes of members -+ Support pushing only if a member not inside the queue ++ Support pushing only if a member not inside the queue ++ All commands are `atomic` ## Data types @@ -110,9 +111,9 @@ q.push_ni(1) # got [3, False] q.ttl(10) # set the lifetime in seconds q.range(0, -1) # got ['1', '2', '3'] q.range(0, 1) # got ['1', '2'] -q.indexofone(1); # got 0 -q.indexofone(2); # got 1 -q.indexofone(4); # got None +q.indexof_one(1); # got 0 +q.indexof_one(2); # got 1 +q.indexof_one(4); # got None q.indexofmany([1, 2, 4]); # got {1: 0, 2: 1, 4: None} # push only if the member not inside the queue q.push_ni(4) # got [4, True] @@ -143,9 +144,9 @@ dq.push_back_ni(5) pq = PriorityQueue("fastrq_priority_queue") pq.push({'alibaba': 1}) pq.push({'google': 0, 'microsoft': 2}) -pq.indexofone('google'); # got 0 -pq.indexofone('alibaba'); # got 1 -pq.indexofone('baidu'); # got None +pq.indexof_one('google'); # got 0 +pq.indexof_one('alibaba'); # got 1 +pq.indexof_one('baidu'); # got None pq.pop() pq.pop(2) pq.push_ni('ibm', 4) @@ -154,9 +155,9 @@ pq.push_ni('amazon', 5) # stack s = Stack("fastrq_stack") s.push([1,2,3]) -s.indexofone(1); # got 2 -s.indexofone(2); # got 1 -s.indexofone(3); # got 0 +s.indexof_one(1); # got 2 +s.indexof_one(2); # got 1 +s.indexof_one(3); # got 0 s.pop() s.push_ni(4) diff --git a/fastrq/__init__.py b/fastrq/__init__.py index 279dd82..1e947d5 100755 --- a/fastrq/__init__.py +++ b/fastrq/__init__.py @@ -1,3 +1,27 @@ +""" Fastrq: Queue, Stack and Priority Queue built on Redis. + +Data types: + +- Queue: nothing more to say +- Capped Queue: Queue with fixed capacity. +- Overflow-able Capped Queue: Queue with fixed capacity, and is overflow-able. + +- Stack: nothing more to say +- Capped Stack: Stack with fixed capacity + +- Deque: nothing more to say +- Capped Deque: Deque with fixed capacity +- Overflow-able Capped Deque: Deque with fixed capacity, and is overflow-able. + +- Priority Queue: nothing more to say +- Capped Priority Queue: Priority Queue with fixed capacity +- Overflow-able Priority Queue: Priority Queue with fixed capacity, and is overflow-able. + +more detail, see https://github.com/limen/fastrq + +""" + + from __future__ import absolute_import from . import queue, deque, stack, priorityqueue @@ -6,9 +30,11 @@ name = 'fastrq' __version__ = '0.1.3' + def version(): return __version__ + __all__ = [ queue, deque, diff --git a/fastrq/base.py b/fastrq/base.py index c7add18..ac37289 100755 --- a/fastrq/base.py +++ b/fastrq/base.py @@ -1,5 +1,9 @@ +from __future__ import absolute_import + from redis import StrictRedis +from . import loader + class Base(object): def __init__(self, key): @@ -8,6 +12,9 @@ def __init__(self, key): def __len__(self): return None + + def load_script(self, command): + return loader.load(command) def connect(self): if self._redis is None: @@ -44,10 +51,8 @@ def length(self): def destruct(self): return self.connect().delete(self._key) - def _makevalues(self, values): - if isinstance(values, tuple) or isinstance(values, list): - return tuple(values) - return values, + def _make_members(self, members): + return members if isinstance(members, list) else [members] def _run_lua_script(self, script, keys=(), args=()): func = self.connect().register_script(script) diff --git a/fastrq/deque.py b/fastrq/deque.py index 80254ee..684acc2 100755 --- a/fastrq/deque.py +++ b/fastrq/deque.py @@ -1,53 +1,145 @@ from __future__ import absolute_import from .base import Base -from .loader import load class Deque(Base): + """Deque + + Usage: + dq = Deque("hello-deque") + dq.push_front("1") + dq.push_back("2") + dq.pop_front() + dq.pop_back() + + """ def __len__(self): return self.connect().llen(self._key) - def push_front(self, values): - script = load('deque_push_front') - return self._run_lua_script(script, [self._key], self._makevalues(values)) + def push_front(self, members): + """Push member(s) from the front end + + Args: + members (str/list): + + Returns: + int: The queue length + + """ + script = self.load_script('deque_push_front') + return self._run_lua_script(script, [self._key], self._make_members(members)) - def push_back(self, values): - script = load('deque_push_back') - return self._run_lua_script(script, [self._key], self._makevalues(values)) + def push_back(self, members): + """Push member(s) from the back end + + Args: + members (str/list): - def push_front_ne(self, values): - script = load('deque_push_front_ne') - rt = self._run_lua_script(script, [self._key], self._makevalues(values)) + Returns: + int: The queue length + + """ + script = self.load_script('deque_push_back') + return self._run_lua_script(script, [self._key], self._make_members(members)) + + def push_front_ne(self, members): + """Push member(s) from the front end only if the queue + not already exists. + + Args: + members (str/list): + + Returns: + int/bool: False if the queue already exist else the queue length + + """ + script = self.load_script('deque_push_front_ne') + rt = self._run_lua_script(script, [self._key], self._make_members(members)) return False if rt == 'err_ae' else rt - def push_back_ne(self, values): - script = load('deque_push_back_ne') - rt = self._run_lua_script(script, [self._key], self._makevalues(values)) + def push_back_ne(self, members): + """Push member(s) from the back end only if the queue + not already exists. + + Args: + members (str/list): + + Returns: + int/bool: False if the queue already exist else the queue length + + """ + script = self.load_script('deque_push_back_ne') + rt = self._run_lua_script(script, [self._key], self._make_members(members)) return False if rt == 'err_ae' else rt - def push_front_ae(self, values): - script = load('deque_push_front_ae') - rt = self._run_lua_script(script, [self._key], self._makevalues(values)) + def push_front_ae(self, members): + """Push member(s) from the front end only if the queue already exists. + + Args: + members (str/list): + + Returns: + int/bool: False if the queue not already exist else the queue length + + """ + script = self.load_script('deque_push_front_ae') + rt = self._run_lua_script(script, [self._key], self._make_members(members)) return False if rt == 'err_ne' else rt - def push_back_ae(self, values): - script = load('deque_push_back_ae') - rt = self._run_lua_script(script, [self._key], self._makevalues(values)) + def push_back_ae(self, members): + """Push member(s) from the back end only if the queue already exists. + + Args: + members (str/list): + + Returns: + int/bool: False if the queue not already exist else the queue length + + """ + script = self.load_script('deque_push_back_ae') + rt = self._run_lua_script(script, [self._key], self._make_members(members)) return False if rt == 'err_ne' else rt def push_front_ni(self, member): - script = load('deque_push_front_not_in') + """Push from front end only if the member not already inside the queue + + Args: + member (str): the member to push + + Returns: + tuple: (int, bool), the queue length, True if pushed into else False + + """ + script = self.load_script('deque_push_front_not_in') r = self._run_lua_script(script, [self._key], [member]) - return [r[0], bool(r[1])] + return r[0], bool(r[1]) def push_back_ni(self, member): - script = load('deque_push_back_not_in') + """Push from back end only if the member not already inside the queue + + Args: + member (str): the member to push + + Returns: + tuple: (int, bool), the queue length, True if pushed into else False + + """ + script = self.load_script('deque_push_back_not_in') r = self._run_lua_script(script, [self._key], [member]) - return [r[0], bool(r[1])] + return r[0], bool(r[1]) def pop_front(self, count=1): - script = load('deque_pop_front') + """Pop member(s) from the front end + + Args: + count (int): How many members to pop. Defaults to 1. + + Returns: + list/str/None: list if count > 1, else str if queue is not empty, else None + + """ + script = self.load_script('deque_pop_front') p = self._run_lua_script(script, [self._key], (count,)) if count > 1: return [x for x in p if x is not None] @@ -55,7 +147,16 @@ def pop_front(self, count=1): return p[0] if len(p) > 0 else None def pop_back(self, count=1): - script = load('deque_pop_back') + """Pop member(s) from the back end + + Args: + count (int): How many members to pop. Defaults to 1. + + Returns: + list/str/None: list if count > 1, else str if queue is not empty, else None + + """ + script = self.load_script('deque_pop_back') p = self._run_lua_script(script, [self._key], (count,)) if count > 1: return [x for x in p if x is not None] @@ -63,15 +164,43 @@ def pop_back(self, count=1): return p[0] if len(p) > 0 else None def range(self, start, end): + """Get a range of members. Wrapper of LRANGE command + + Args: + start (int): + end (int): + + Returns: + list + + """ return self.connect().lrange(self._key, start, end) - def indexofone(self, member): - script = load('deque_indexof') + def indexof_one(self, member): + """Get the first index of a member + + Args: + member (str): the member to search + + Returns: + None/int: None if not found, else int + + """ + script = self.load_script('deque_indexof') r = self._run_lua_script(script, [self._key], [member]) return None if r[0] == -1 else r[0] - def indexofmany(self, members): - script = load('deque_indexof') + def indexof_many(self, members): + """Get the first index if each member + + Args: + members (list): members to search + + Returns: + dict: a dict whose key is the member and value is the member's index. + + """ + script = self.load_script('deque_indexof') indexes = {} r = self._run_lua_script(script, [self._key], members) for i, m in enumerate(members): @@ -80,85 +209,281 @@ def indexofmany(self, members): class CappedDeque(Deque): + """Deque with fixed capacity + + Usage: + capped_dq = CappedDeque("hello-cdq", 3) + + """ def __init__(self, key, cap): + """ + + Args: + key (str): queue ID + cap (int): capacity + """ super(CappedDeque, self).__init__(key) self._cap = cap - def push_front(self, values): - script = load('capped_deque_push_front') - return self._run_lua_script(script, [self._key], (self._cap,) + self._makevalues(values)) + def push_front(self, members): + """Push member(s) from the front end + + Args: + members (str/list): + + Returns: + str/int: "err_qf" if the queue is already full, + "err_qof" is the queue is lacked of capacity, + else the queue length + + """ + script = self.load_script('capped_deque_push_front') + return self._run_lua_script(script, [self._key], [self._cap] + self._make_members(members)) - def push_back(self, values): - script = load('capped_deque_push_back') - return self._run_lua_script(script, [self._key], (self._cap,) + self._makevalues(values)) + def push_back(self, members): + """Push member(s) from the back end + + Args: + members (str/list): + + Returns: + str/int: "err_qf" if the queue is already full, + "err_qof" is the queue is lacked of capacity, + else the queue length + + """ + script = self.load_script('capped_deque_push_back') + return self._run_lua_script(script, [self._key], [self._cap] + self._make_members(members)) - def push_front_ne(self, values): - script = load('capped_deque_push_front_ne') - rt = self._run_lua_script(script, [self._key], (self._cap,) + self._makevalues(values)) + def push_front_ne(self, members): + """Push member(s) from the front end only if the queue + not already exists. + + Args: + members (str/list): + + Returns: + str/int/bool: "err_qf" if the queue is already full, + "err_qof" is the queue is lacked of capacity, + else same to `Deque.push_front_ne` + + """ + script = self.load_script('capped_deque_push_front_ne') + rt = self._run_lua_script(script, [self._key], [self._cap] + self._make_members(members)) return False if rt == 'err_ae' else rt - def push_back_ne(self, values): - script = load('capped_deque_push_back_ne') - rt = self._run_lua_script(script, [self._key], (self._cap,) + self._makevalues(values)) + def push_back_ne(self, members): + """Push member(s) from the back end only if the queue + not already exists. + + Args: + members (str/list): + + Returns: + str/int/bool: "err_qf" if the queue is already full, + "err_qof" is the queue is lacked of capacity, + else same to `Deque.push_back_ne` + + """ + script = self.load_script('capped_deque_push_back_ne') + rt = self._run_lua_script(script, [self._key], [self._cap] + self._make_members(members)) return False if rt == 'err_ae' else rt - def push_front_ae(self, values): - script = load('capped_deque_push_front_ae') - rt = self._run_lua_script(script, [self._key], (self._cap,) + self._makevalues(values)) + def push_front_ae(self, members): + """Push member(s) from the front end only if the queue already exists. + + Args: + members (str/list): + + Returns: + str/int/bool: "err_qf" if the queue is already full, + "err_qof" is the queue is lacked of capacity, + else same to `Deque.push_front_ae` + + """ + script = self.load_script('capped_deque_push_front_ae') + rt = self._run_lua_script(script, [self._key], [self._cap] + self._make_members(members)) return False if rt == 'err_ne' else rt - def push_back_ae(self, values): - script = load('capped_deque_push_back_ae') - rt = self._run_lua_script(script, [self._key], (self._cap,) + self._makevalues(values)) + def push_back_ae(self, members): + """Push member(s) from the back end only if the queue already exists. + + Args: + members (str/list): + + Returns: + str/int/bool: "err_qf" if the queue is already full, + "err_qof" is the queue is lacked of capacity, + else same to `Deque.push_back_ae` + + """ + script = self.load_script('capped_deque_push_back_ae') + rt = self._run_lua_script(script, [self._key], [self._cap] + self._make_members(members)) return False if rt == 'err_ne' else rt def push_front_ni(self, member): - script = load('capped_deque_push_front_not_in') - r = self._run_lua_script(script, [self._key], (self._cap, member)) - return [r[0], bool(r[1])] if isinstance(r, list) else r + """Push a member from the front end only if it's + not already inside the queue. + + Args: + member (str): + + Returns: + str/int/bool: "err_qf" if the queue is already full, + "err_qof" is the queue is lacked of capacity, + else same to `Deque.push_front_ni` + + """ + script = self.load_script('capped_deque_push_front_not_in') + r = self._run_lua_script(script, [self._key], [self._cap, member]) + return (r[0], bool(r[1])) if isinstance(r, list) else r def push_back_ni(self, member): - script = load('capped_deque_push_back_not_in') - r = self._run_lua_script(script, [self._key], (self._cap, member)) - return [r[0], bool(r[1])] if isinstance(r, list) else r + """Push a member from the back end only if it's + not already inside the queue. + + Args: + member (str): + + Returns: + str/int/bool: "err_qf" if the queue is already full, + "err_qof" is the queue is lacked of capacity, + else same to `Deque.push_back_ni` + + """ + script = self.load_script('capped_deque_push_back_not_in') + r = self._run_lua_script(script, [self._key], [self._cap, member]) + return (r[0], bool(r[1])) if isinstance(r, list) else r class OfCappedDeque(CappedDeque): - def push_front(self, values): - script = load('of_capped_deque_push_front') - return self._run_lua_script(script, [self._key], (self._cap,) + self._makevalues(values)) + """Overflow-able capped deque - def push_back(self, values): - script = load('of_capped_deque_push_back') - return self._run_lua_script(script, [self._key], (self._cap,) + self._makevalues(values)) + Usage: + of_capped_dq = OfCappedDeque("hello-of-dq", 3) + + """ + def push_front(self, members): + """Push member(s) from the front end + + Args: + members (str/list): - def push_front_ne(self, values): - script = load('of_capped_deque_push_front_ne') - rt = self._run_lua_script(script, [self._key], (self._cap,) + self._makevalues(values)) - return False if rt == 'err_ae' else rt + Returns: + tuple: (int, list), the queue length and the members been forced out + + """ + script = self.load_script('of_capped_deque_push_front') + members = self._make_members(members) + return tuple(self._run_lua_script(script, [self._key], [self._cap] + members)) - def push_back_ne(self, values): - script = load('of_capped_deque_push_back_ne') - rt = self._run_lua_script(script, [self._key], (self._cap,) + self._makevalues(values)) - return False if rt == 'err_ae' else rt + def push_back(self, members): + """Push member(s) from the back end + + Args: + members (str/list): - def push_front_ae(self, values): - script = load('of_capped_deque_push_front_ae') - rt = self._run_lua_script(script, [self._key], (self._cap,) + self._makevalues(values)) - return False if rt == 'err_ne' else rt + Returns: + tuple: (int, list), the queue length and the members been forced out + + """ + script = self.load_script('of_capped_deque_push_back') + r = self._run_lua_script(script, [self._key], [self._cap] + self._make_members(members)) + return r[0], r[1] + + def push_front_ne(self, members): + """Push member(s) into the queue from front end + only if the queue ``not already exist`` + + Args: + members (str/list): + + Returns: + bool/tuple: False if the queue already exists, + else (int, list): queue length, members been forced out + + """ + script = self.load_script('of_capped_deque_push_front_ne') + rt = self._run_lua_script(script, [self._key], [self._cap] + self._make_members(members)) + return False if rt == 'err_ae' else (rt[0], rt[1]) - def push_back_ae(self, values): - script = load('of_capped_deque_push_back_ae') - rt = self._run_lua_script(script, [self._key], (self._cap,) + self._makevalues(values)) - return False if rt == 'err_ne' else rt + def push_back_ne(self, members): + """Push member(s) into the queue from back end + only if the queue ``not already exist`` + + Args: + members (str/list): + + Returns: + bool/tuple: False if the queue already exists, + else (int, list): queue length, members been forced out + + """ + script = self.load_script('of_capped_deque_push_back_ne') + rt = self._run_lua_script(script, [self._key], [self._cap] + self._make_members(members)) + return False if rt == 'err_ae' else (rt[0], rt[1]) + + def push_front_ae(self, members): + """Push member(s) into the queue from front end + only if the queue ``already exist`` + + Args: + members (str/list): + + Returns: + bool/tuple: False if the queue not already exists, + else (int, list): queue length, members been forced out + + """ + script = self.load_script('of_capped_deque_push_front_ae') + rt = self._run_lua_script(script, [self._key], [self._cap] + self._make_members(members)) + return False if rt == 'err_ne' else (rt[0], rt[1]) + + def push_back_ae(self, members): + """Push member(s) into the queue from back end + only if the queue ``already exist`` + + Args: + members (str/list): + + Returns: + bool/tuple: False if the queue not already exists, + else (int, list): queue length, members been forced out + + """ + script = self.load_script('of_capped_deque_push_back_ae') + rt = self._run_lua_script(script, [self._key], [self._cap] + self._make_members(members)) + return False if rt == 'err_ne' else (rt[0], rt[1]) def push_front_ni(self, member): - script = load('of_capped_deque_push_front_not_in') - r = self._run_lua_script(script, [self._key], (self._cap, member)) - return [r[0], r[1], bool(r[2])] if isinstance(r, list) else r + """Push member into the queue from front end + only if the member not already inside the queue. + + Args: + member (str): + + Returns: + tuple: (int, list, bool): queue length, members been forced out + and an indicator + + """ + script = self.load_script('of_capped_deque_push_front_not_in') + r = self._run_lua_script(script, [self._key], [self._cap, member]) + return (r[0], r[1], bool(r[2])) if isinstance(r, list) else r def push_back_ni(self, member): - script = load('of_capped_deque_push_back_not_in') + """Push member into the queue from back end + only if the member not already inside the queue. + + Args: + member (str): + + Returns: + tuple: (int, list, bool): queue length, members been forced out + and an indicator + + """ + script = self.load_script('of_capped_deque_push_back_not_in') r = self._run_lua_script(script, [self._key], (self._cap, member)) - return [r[0], r[1], bool(r[2])] if isinstance(r, list) else r + return (r[0], r[1], bool(r[2])) if isinstance(r, list) else r diff --git a/fastrq/loader.py b/fastrq/loader.py index 95a7cc8..8bc5550 100755 --- a/fastrq/loader.py +++ b/fastrq/loader.py @@ -1,4 +1,4 @@ -_scripts = {} +_scripts = dict() _scripts['not_exist'] = """ if redis.call('exists',KEYS[1])==1 then @@ -509,7 +509,12 @@ 'capped_priority_queue_indexof': 'priority_queue_indexof', } + def load(command): + """Load Lua script for the command. + + The load may be recursive to reuse some scripts. + """ real = _map[command] script = '' if isinstance(real, list): @@ -522,9 +527,3 @@ def load(command): else: # load recursively return load(real) - - -if __name__ == '__main__': - print('capped_deque_push_back_ne', load('capped_deque_push_back_ne')) - print('queue_push', load('queue_push')) - print('queue_push_ne', load('queue_push_ne')) diff --git a/fastrq/priorityqueue.py b/fastrq/priorityqueue.py index 7e22ba0..7212405 100755 --- a/fastrq/priorityqueue.py +++ b/fastrq/priorityqueue.py @@ -1,64 +1,144 @@ from __future__ import absolute_import from .base import Base -from .loader import load class PriorityQueue(Base): + """Priority queue + + The lower the score, the higher the priority. + Usage: + pq = PriorityQueue("hello-pq") + pq.push({"google": 100, "alibaba": 101}) + pq.pop() + + """ def __len__(self): return self.connect().zcard(self._key) - def push(self, values): - script = load('priority_queue_push') - return self._run_lua_script(script, (self._key,), self._makevalues(values)) + def push(self, members_with_core): + """Push member(s) into queue + + Args: + members_with_core (dict): key as member and value as score(priority). + + Returns: + int: length of the queue + + """ + script = self.load_script('priority_queue_push') + return self._run_lua_script(script, [self._key], self._make_members(members_with_core)) - def push_ne(self, values): - script = load('priority_queue_push_ne') - rt = self._run_lua_script(script, (self._key,), self._makevalues(values)) + def push_ne(self, members_with_core): + """Push member(s) into queue only if the queue ``not already exists`` + + Args: + members_with_core (dict): key as member and value as score(priority). + + Returns: + bool/int: False if the queue already exist else length of the queue + + """ + script = self.load_script('priority_queue_push_ne') + rt = self._run_lua_script(script, [self._key], self._make_members(members_with_core)) return False if rt == 'err_ae' else rt - def push_ae(self, values): - script = load('priority_queue_push_ae') - rt = self._run_lua_script(script, (self._key,), self._makevalues(values)) + def push_ae(self, members_with_core): + """Push member(s) into queue only if the queue ``not already exists`` + + Args: + members_with_core (dict): key as member and value as score(priority). + + Returns: + bool/int: False if the queue already exist else length of the queue + + """ + script = self.load_script('priority_queue_push_ae') + rt = self._run_lua_script(script, [self._key], self._make_members(members_with_core)) return False if rt == 'err_ne' else rt def push_ni(self, member, score): - """ Push only if the member not inside the queue + """Push member only if it's not already inside the queue. + + Args: + member (str): + score (int): + + Returns: + tuple: (int, bool): the queue length and a success indicator. + """ - script = load('priority_queue_push_not_in') - rs = self._run_lua_script(script, (self._key,), (score, member)) - print('pq-push-ni', rs) - return [rs[0], bool(rs[1])] if isinstance(rs, list) else rs + script = self.load_script('priority_queue_push_not_in') + rs = self._run_lua_script(script, [self._key], [score, member]) + return (rs[0], bool(rs[1])) if isinstance(rs, list) else rs def pop(self, count=1): - script = load('priority_queue_pop') - p = self._run_lua_script(script, (self._key,), (count,)) - r = self._makereturn(p) + """Pop member(s) + + Args: + count (int): How many members to pop. Defaults to 1. + + Returns: + list/tuple/None: list if count > 1, else tuple(member, score) + when queue is not empty, else None + + """ + script = self.load_script('priority_queue_pop') + p = self._run_lua_script(script, [self._key], [count]) + r = self._make_return(p) return r if count > 1 else (r[0] if len(r) > 0 else None) def range(self, low_score='-inf', high_score='+inf'): + """Get a range of members. Wrapper of ZRANGEBYSCORE command. + + Args: + low_score (int/str): + high_score (int/str): + + Returns: + list: + + """ return self.connect().zrangebyscore(self._key, low_score, high_score, None, None, True, int) - def indexofone(self, member): - script = load('priority_queue_indexof') + def indexof_one(self, member): + """Get the first index of a member + + Args: + member (str): the member to search + + Returns: + None/int: None if not found, else int + + """ + script = self.load_script('priority_queue_indexof') r = self._run_lua_script(script, [self._key], [member]) return None if r[0] == -1 else r[0] - def indexofmany(self, members): - script = load('priority_queue_indexof') - indexes = {} + def indexof_many(self, members): + """Get the first index if each member + + Args: + members (list): members to search + + Returns: + dict: a dict whose key is the member and value is the member's index. + + """ + script = self.load_script('priority_queue_indexof') + indexes = dict() r = self._run_lua_script(script, [self._key], members) for i, m in enumerate(members): indexes[m] = None if r[i] == -1 else r[i] return indexes - def _makevalues(self, values): + def _make_members(self, members): vl = [] - for key in values: - vl += [values[key], key] + for key in members: + vl += [members[key], key] return vl - def _makereturn(self, raw): + def _make_return(self, raw): r = [] for i in range(0, len(raw)): if i % 2 == 0: @@ -69,52 +149,150 @@ def _makereturn(self, raw): class CappedPriorityQueue(PriorityQueue): + """Priority queue with fixed capacity. + + Usage: + capped_pq = CappedPriorityQueue("hello-capped-pq", 3) + + """ def __init__(self, key, cap): + """ + + Args: + key (str): + cap (int): + """ super(CappedPriorityQueue, self).__init__(key) self._cap = cap - def push(self, values): - script = load('capped_priority_queue_push') - return self._run_lua_script(script, (self._key,), [self._cap] + self._makevalues(values)) + def push(self, members_with_core): + """Push member(s) into queue + + Args: + members_with_core (dict): key as member and value as score(priority). + + Returns: + str/int: "err_qf" if queue is already full, + "err_qof" if queue if lacked of capacity, + else length of the queue + + """ + script = self.load_script('capped_priority_queue_push') + return self._run_lua_script(script, [self._key], [self._cap] + self._make_members(members_with_core)) - def push_ne(self, values): - script = load('capped_priority_queue_push_ne') - rt = self._run_lua_script(script, (self._key,), [self._cap] + self._makevalues(values)) + def push_ne(self, members_with_core): + """Push member(s) into queue only if the queue ``not already exists`` + + Args: + members_with_core (dict): key as member and value as score(priority). + + Returns: + bool/int: False if the queue already exist, + else same to `push` + + """ + script = self.load_script('capped_priority_queue_push_ne') + rt = self._run_lua_script(script, [self._key], [self._cap] + self._make_members(members_with_core)) return False if rt == 'err_ae' else rt - def push_ae(self, values): - script = load('capped_priority_queue_push_ae') - rt = self._run_lua_script(script, (self._key,), [self._cap] + self._makevalues(values)) + def push_ae(self, members_with_core): + """Push member(s) into queue only if the queue ``already exists`` + + Args: + members_with_core (dict): key as member and value as score(priority). + + Returns: + bool/int: False if the queue not already exist, + else same to `push` + + """ + script = self.load_script('capped_priority_queue_push_ae') + rt = self._run_lua_script(script, [self._key], [self._cap] + self._make_members(members_with_core)) return False if rt == 'err_ne' else rt def push_ni(self, member, score): - """ Push only if the member not inside the queue + """Push member into queue only if the member + not already inside the queue. + + Args: + member (str): + score (int): + + Returns: + str/tuple: "err_qf" if queue is already full, + "err_qof" if queue if lacked of capacity, + else (int: length of the queue, bool: success indicator) + """ - script = load('capped_priority_queue_push_not_in') - rs = self._run_lua_script(script, (self._key,), (self._cap, score, member)) - return [rs[0], bool(rs[1])] if isinstance(rs, list) else rs + script = self.load_script('capped_priority_queue_push_not_in') + rs = self._run_lua_script(script, [self._key], [self._cap, score, member]) + return (rs[0], bool(rs[1])) if isinstance(rs, list) else rs class OfCappedPriorityQueue(CappedPriorityQueue): - def push(self, values): - script = load('of_capped_priority_queue_push') - p = self._run_lua_script(script, (self._key,), [self._cap] + self._makevalues(values)) - return [p[0], self._makereturn(p[1])] + """Overflow-able Priority Queue. + + Usage: + of_capped_pq = OfCappedPriorityQueue("hello-of-pq", 3) + + """ + def push(self, members_with_core): + """Push member(s) into queue. + + Args: + members_with_core (dict): + + Returns: + tuple: (int: length of the queue, list: members been forced out) + + """ + script = self.load_script('of_capped_priority_queue_push') + p = self._run_lua_script(script, [self._key], [self._cap] + self._make_members(members_with_core)) + return p[0], self._make_return(p[1]) + + def push_ne(self, members_with_core): + """Push member(s) into queue only if the queue + not already exist. + + Args: + members_with_core (dict): - def push_ne(self, values): - script = load('of_capped_priority_queue_push_ne') - p = self._run_lua_script(script, (self._key,), [self._cap] + self._makevalues(values)) - return False if p == 'err_ae' else [p[0], self._makereturn(p[1])] + Returns: + bool/tuple: False if the queue already exist, + else same to `push`. - def push_ae(self, values): - script = load('of_capped_priority_queue_push_ae') - p = self._run_lua_script(script, (self._key,), [self._cap] + self._makevalues(values)) - return False if p == 'err_ne' else [p[0], self._makereturn(p[1])] + """ + script = self.load_script('of_capped_priority_queue_push_ne') + p = self._run_lua_script(script, [self._key], [self._cap] + self._make_members(members_with_core)) + return False if p == 'err_ae' else (p[0], self._make_return(p[1])) + + def push_ae(self, members_with_core): + """Push member(s) into queue only if the queue already exist. + + Args: + members_with_core (dict): + + Returns: + bool/tuple: False if the queue not already exist, + else same to `push`. + + """ + script = self.load_script('of_capped_priority_queue_push_ae') + p = self._run_lua_script(script, [self._key], [self._cap] + self._make_members(members_with_core)) + return False if p == 'err_ne' else (p[0], self._make_return(p[1])) def push_ni(self, member, score): - """ Push only if the member not inside the queue + """Push member only if it's not already inside the queue. + + Args: + member (str): + score (int): + + Returns: + tuple: (int: the length, list: members been forced out, bool: success indicator) + """ - script = load('of_capped_priority_queue_push_not_in') - rs = self._run_lua_script(script, (self._key,), (self._cap, score, member)) - return [rs[0], self._makereturn(rs[1]), bool(rs[2])] if isinstance(rs, list) else rs + script = self.load_script('of_capped_priority_queue_push_not_in') + rs = self._run_lua_script(script, [self._key], [self._cap, score, member]) + return (rs[0], self._make_return(rs[1]), bool(rs[2])) if isinstance(rs, list) else rs diff --git a/fastrq/queue.py b/fastrq/queue.py index 3550348..428f95d 100755 --- a/fastrq/queue.py +++ b/fastrq/queue.py @@ -1,57 +1,131 @@ from __future__ import absolute_import from .base import Base -from .loader import load class Queue(Base): + """Queue + + Usage: + q = Queue("hello-queue") + q.push("world") + q.pop() + + """ def __len__(self): return self.connect().llen(self._key) - def push(self, values): - script = load('queue_push') - return self._run_lua_script(script, [self._key], self._makevalues(values)) + def push(self, members): + """Push member(s) into the queue + + Args: + members (str/list): member(s) to be pushed + + Returns: + int: The queue length after push + + """ + script = self.load_script('queue_push') + return self._run_lua_script(script, [self._key], self._make_members(members)) def pop(self, count=1): - script = load('queue_pop') - p = self._run_lua_script(script, [self._key], (count,)) + """Pop member(s) + + Args: + count (int): How many members to pop. Defaults to 1. + + Returns: + list/str/None: list if count > 1, else str if queue is not empty, else None + + """ + script = self.load_script('queue_pop') + p = self._run_lua_script(script, [self._key], [count]) if count > 1: return [x for x in p if x is not None] else: return p[0] if len(p) > 0 else None def push_ni(self, member): - """ Push only if the member not inside the queue + """Push only if the member not already inside the queue + + Args: + member (str): the member to push + + Returns: + tuple(int, bool): the queue length, True if pushed into else False + """ - script = load('queue_push_not_in') + script = self.load_script('queue_push_not_in') rs = self._run_lua_script(script, [self._key], [member]) - return [rs[0], bool(rs[1])] if isinstance(rs, list) else rs + return (rs[0], bool(rs[1])) if isinstance(rs, list) else rs - def push_ne(self, values): + def push_ne(self, members): """ Push only if the queue not already exist + + Args: + members (str/list): member(s) to push + + Returns: + bool/int: False if the queue already exists else the queue length + """ - script = load('queue_push_ne') - rt = self._run_lua_script(script, [self._key], self._makevalues(values)) + script = self.load_script('queue_push_ne') + rt = self._run_lua_script(script, [self._key], self._make_members(members)) return False if rt == 'err_ae' else rt - def push_ae(self, values): - """ Push only if the queue already exists + def push_ae(self, members): + """ Push only if the queue not already exist + + Args: + members (str/list): member(s) to push + + Returns: + bool/int: False if the queue not already exists else the queue length + """ - script = load('queue_push_ae') - rt = self._run_lua_script(script, [self._key], self._makevalues(values)) + script = self.load_script('queue_push_ae') + rt = self._run_lua_script(script, [self._key], self._make_members(members)) return False if rt == 'err_ne' else rt def range(self, start, end): + """Get a range of members. Wrapper of the LRANGE command. + + Args: + start (int): + end (int): + + Returns: + list + + """ return self.connect().lrange(self._key, start, end) - def indexofone(self, member): - script = load('queue_indexof') + def indexof_one(self, member): + """Get the first index of a member + + Args: + member (str): the member to search + + Returns: + None/int: None if not found, else int + + """ + script = self.load_script('queue_indexof') r = self._run_lua_script(script, [self._key], [member]) return None if r[0] == -1 else r[0] - def indexofmany(self, members): - script = load('queue_indexof') - indexes = {} + def indexof_many(self, members): + """Get the first index if each member + + Args: + members (list): members to search + + Returns: + dict: a dict whose key is the member and value is the member's index. + + """ + script = self.load_script('queue_indexof') + indexes = dict() r = self._run_lua_script(script, [self._key], members) for i, m in enumerate(members): indexes[m] = None if r[i] == -1 else r[i] @@ -59,51 +133,151 @@ def indexofmany(self, members): class CappedQueue(Queue): + """Queue with a fixed capacity. + + Usage: + cq = CappedQueue("hello-cq", 3) + + """ def __init__(self, key, cap): + """ + Args: + key (str): queue's ID + cap (int): queue's capacity + + """ super(CappedQueue, self).__init__(key) self._cap = cap - def push(self, values): - script = load('capped_queue_push') - return self._run_lua_script(script, [self._key], (self._cap,) + self._makevalues(values)) + def push(self, members): + """Push member(s) into queue + + Args: + members (str/list): member(s) to push + + Returns: + str/int: "err_qf" if queue is already full, + "err_qof" if queue is lacked of capacity + else the queue length + + """ + script = self.load_script('capped_queue_push') + return self._run_lua_script(script, [self._key], [self._cap] + self._make_members(members)) - def push_ne(self, values): - script = load('capped_queue_push_ne') - rt = self._run_lua_script(script, [self._key], (self._cap,) + self._makevalues(values)) + def push_ne(self, members): + """Push member(s) into the queue only if the queue ``not already exist`` + + Args: + members (str/list): same to `Queue.push` + + Returns: + str/bool/int: "err_qf" if the queue is already full, + "err_qof" if the queue is lacked of capacity, + False if the queue already exists, + else the queue length + + """ + script = self.load_script('capped_queue_push_ne') + rt = self._run_lua_script(script, [self._key], [self._cap] + self._make_members(members)) return False if rt == 'err_ae' else rt - def push_ae(self, values): - script = load('capped_queue_push_ae') - rt = self._run_lua_script(script, [self._key], (self._cap,) + self._makevalues(values)) + def push_ae(self, members): + """Push member(s) into the queue only if the queue ``already exist`` + + Args: + members (str/list): same to `Queue.push` + + Returns: + str/bool/int: "err_qf" if the queue is already full, + "err_qof" if the queue is lacked of capacity, + False if the queue not already exists, + else the queue length + + """ + script = self.load_script('capped_queue_push_ae') + rt = self._run_lua_script(script, [self._key], [self._cap] + self._make_members(members)) return False if rt == 'err_ne' else rt def push_ni(self, member): - """ Push only if the member not inside the queue + """Push a member only if it is not already inside the queue + + Args: + member (str): same to `Queue.push_ni` + + Returns: + str/tuple: "err_qf" if queue is already full, + "err_qof" if queue is lacked of capacity, + else the queue length and a bool that indicate push into or not + """ - script = load('capped_queue_push_not_in') - rs = self._run_lua_script(script, [self._key], (self._cap, member)) - print('capped-queue-push-ni', rs) - return [rs[0], bool(rs[1])] if isinstance(rs, list) else rs + script = self.load_script('capped_queue_push_not_in') + rs = self._run_lua_script(script, [self._key], [self._cap, member]) + return (rs[0], bool(rs[1])) if isinstance(rs, list) else rs class OfCappedQueue(CappedQueue): - def push(self, values): - script = load('of_capped_queue_push') - return self._run_lua_script(script, [self._key], (self._cap,) + self._makevalues(values)) + """Overflow-able capped queue + + Usage: + of_capped_queue = OfCappedQueue("hello-of-queue", 3) + + """ + def push(self, members): + """Push member(s) into queue + + Args: + members (str/list): same to `Queue.push` - def push_ne(self, values): - script = load('of_capped_queue_push_ne') - rt = self._run_lua_script(script, [self._key], (self._cap,) + self._makevalues(values)) - return False if rt == 'err_ae' else rt + Returns: + tuple: (int, list), the queue length and the members been forced out + + """ + script = self.load_script('of_capped_queue_push') + members = self._make_members(members) + r = self._run_lua_script(script, [self._key], [self._cap] + members) + return r[0], r[1] - def push_ae(self, values): - script = load('of_capped_queue_push_ae') - rt = self._run_lua_script(script, [self._key], (self._cap,) + self._makevalues(values)) - return False if rt == 'err_ne' else rt + def push_ne(self, members): + """Push member(s) into the queue only if the queue ``not already exist`` + + Args: + members (str/list): same to `Queue.push` + + Returns: + bool/tuple: False if the queue already exists, + else same to `OfCappedQueue.push` + + """ + script = self.load_script('of_capped_queue_push_ne') + rt = self._run_lua_script(script, [self._key], [self._cap] + self._make_members(members)) + return False if rt == 'err_ae' else (rt[0], rt[1]) + + def push_ae(self, members): + """Push member(s) into the queue only if the queue ``already exist`` + + Args: + members (str/list): same to `Queue.push` + + Returns: + str/tuple: False if the queue not already exists, + else same to `OfCappedQueue.push` + + """ + script = self.load_script('of_capped_queue_push_ae') + rt = self._run_lua_script(script, [self._key], [self._cap] + self._make_members(members)) + return False if rt == 'err_ne' else (rt[0], rt[1]) def push_ni(self, member): - """ Push only if the member not inside the queue + """Push a member only if it is not already inside the queue + + Args: + member (str): same to `OfCappedQueue.push` + + Returns: + tuple: (int, list, bool) + queue length, members been forced out and an indicator + """ - script = load('of_capped_queue_push_not_in') - rs = self._run_lua_script(script, [self._key], (self._cap, member)) - return [rs[0], rs[1], bool(rs[2])] if isinstance(rs, list) else rs + script = self.load_script('of_capped_queue_push_not_in') + rs = self._run_lua_script(script, [self._key], [self._cap, member]) + return (rs[0], rs[1], bool(rs[2])) if isinstance(rs, list) else rs diff --git a/fastrq/stack.py b/fastrq/stack.py index 45c53b1..b16d2f8 100755 --- a/fastrq/stack.py +++ b/fastrq/stack.py @@ -1,50 +1,119 @@ from __future__ import absolute_import from .base import Base -from .loader import load class Stack(Base): + """Stack + + Usage: + stack = Stack("hello-stack") + stack.push("1") + stack.push("2") + stack.pop() + stack.pop(2) + """ def __len__(self): return self.connect().llen(self._key) - def push(self, values): - script = load('stack_push') - return self._run_lua_script(script, (self._key,), self._makevalues(values)) + def push(self, members): + """Push member(s) into the stack. + + Args: + members (str/list): member(s) to be pushed + + Returns: + int: The length of the stack after push + + """ + script = self.load_script('stack_push') + return self._run_lua_script(script, [self._key], self._make_members(members)) def push_ne(self, values): - script = load('stack_push_ne') - rt = self._run_lua_script(script, (self._key,), self._makevalues(values)) + """Push value(s) into the stack only if the stack not already exist + + Args: + values (str/list): same to `push` + + Returns: + bool/int: False if stack not already exist else the length of the stack + + """ + script = self.load_script('stack_push_ne') + rt = self._run_lua_script(script, [self._key], self._make_members(values)) return False if rt == 'err_ae' else rt def push_ae(self, values): - script = load('stack_push_ae') - rt = self._run_lua_script(script, (self._key,), self._makevalues(values)) + """Push value(s) into the stack only if the stack already exists + + Args: + values (str/list): same to `push` + + Returns: + bool/int: False if stack already exists else the length of the stack + + """ + script = self.load_script('stack_push_ae') + rt = self._run_lua_script(script, [self._key], self._make_members(values)) return False if rt == 'err_ne' else rt def push_ni(self, member): - """ Push only if the member not inside the stack + """Push a member only if it not already inside the stack + + Args: + member (str): member to be pushed + + Returns: + tuple(int, bool): (The stack length, True if pushed into else False) + """ - script = load('stack_push_not_in') - rs = self._run_lua_script(script, (self._key,), [member]) - return [rs[0], bool(rs[1])] if isinstance(rs, list) else rs + script = self.load_script('stack_push_not_in') + rs = self._run_lua_script(script, [self._key], [member]) + return (rs[0], bool(rs[1])) if isinstance(rs, list) else rs def pop(self, count=1): - script = load('stack_pop') - p = self._run_lua_script(script, (self._key,), (count,)) + """Pop member(s) from the stack + + Args: + count (int): how many members to pop. defaults to 1. + + Returns: + list/str/None: list if count > 1, else str if stack not empty, else None + + """ + script = self.load_script('stack_pop') + p = self._run_lua_script(script, [self._key], [count]) if count > 1: return [x for x in p if x is not None] else: return p[0] if len(p) > 0 else None - def indexofone(self, member): - script = load('stack_indexof') + def indexof_one(self, member): + """Get the first index of a member + + Args: + member (str): the member to search + + Returns: + None/int: None if not found, else int + + """ + script = self.load_script('stack_indexof') r = self._run_lua_script(script, [self._key], [member]) return None if r[0] == -1 else r[0] - def indexofmany(self, members): - script = load('stack_indexof') - indexes = {} + def indexof_many(self, members): + """Get the first index if each member + + Args: + members (list): members to search + + Returns: + dict: a dict whose key is the member and value is the member's index. + + """ + script = self.load_script('stack_indexof') + indexes = dict() r = self._run_lua_script(script, [self._key], members) for i, m in enumerate(members): indexes[m] = None if r[i] == -1 else r[i] @@ -52,27 +121,81 @@ def indexofmany(self, members): class CappedStack(Stack): + """Stack with fixed capacity. + + Usage: + capped_stack = CappedStack("hello-capped-stack", 3) + + """ def __init__(self, key, cap): + """ + Args: + key (str): the stack's ID + cap (int): the stack's capacity + + """ super(CappedStack, self).__init__(key) self._cap = cap - def push(self, values): - script = load('capped_stack_push') - return self._run_lua_script(script, (self._key,), (self._cap,) + self._makevalues(values)) + def push(self, members): + """Push member(s) into the stack + + Args: + members (str/list): same to `Stack.push` + + Returns: + str/int: "err_qf" if the stack is already full, + "err_qof" if the stack is lacked of capacity, + else the stack length + + """ + script = self.load_script('capped_stack_push') + return self._run_lua_script(script, [self._key], [self._cap] + self._make_members(members)) - def push_ne(self, values): - script = load('capped_stack_push_ne') - rt = self._run_lua_script(script, (self._key,), (self._cap,) + self._makevalues(values)) + def push_ne(self, members): + """Push member(s) into the stack only if the stack ``not already exist`` + + Args: + members (str/list): same to `Stack.push` + + Returns: + str/bool/int: "err_qf" if the stack is already full, + "err_qof" if the stack is lacked of capacity, + False if the stack already exists, + else the stack length + + """ + script = self.load_script('capped_stack_push_ne') + rt = self._run_lua_script(script, [self._key], [self._cap] + self._make_members(members)) return False if rt == 'err_ae' else rt - def push_ae(self, values): - script = load('capped_stack_push_ae') - rt = self._run_lua_script(script, (self._key,), (self._cap,) + self._makevalues(values)) + def push_ae(self, members): + """Push member(s) into the stack only if the stack ``already exist`` + + Args: + members (str/list): same to `Stack.push` + + Returns: + str/bool/int: "err_qf" if the stack is already full, + "err_qof" if the stack is lacked of capacity, + False if the stack not already exist, + else the stack length + + """ + script = self.load_script('capped_stack_push_ae') + rt = self._run_lua_script(script, [self._key], [self._cap] + self._make_members(members)) return False if rt == 'err_ne' else rt def push_ni(self, member): - """ Push only if the member not inside the stack + """Push a member only if it is not already inside the stack + + Args: + member (str): same to `Stack.push_ni` + + Returns: + tuple(int, bool): same to `Stack.push_ni` + """ - script = load('capped_stack_push_not_in') - rs = self._run_lua_script(script, (self._key,), (self._cap, member)) - return [rs[0], bool(rs[1])] if isinstance(rs, list) else rs + script = self.load_script('capped_stack_push_not_in') + rs = self._run_lua_script(script, [self._key], [self._cap, member]) + return (rs[0], bool(rs[1])) if isinstance(rs, list) else rs diff --git a/tests/test_deque.py b/tests/test_deque.py index 82eb981..4f24614 100755 --- a/tests/test_deque.py +++ b/tests/test_deque.py @@ -13,7 +13,7 @@ def tearDown(self): self.queue.destruct() def test_push_pop(self): - ql = self.queue.push_back((1, 2)) + ql = self.queue.push_back([1, 2]) self.assertEqual(ql, 2) self.assertEqual(self.queue.length(), 2) head = self.queue.pop_front() @@ -21,7 +21,7 @@ def test_push_pop(self): self.assertEqual(self.queue.length(), 1) self.assertEqual(len(self.queue), 1) - self.queue.push_front((3, 4, 5, 6, 7)) + self.queue.push_front([3, 4, 5, 6, 7]) head3 = self.queue.pop_front(3) self.assertEqual(head3, ['7', '6', '5']) self.assertEqual(self.queue.pop_back(3), ['2', '3', '4']) @@ -36,16 +36,16 @@ def test_push_e(self): self.assertEqual(self.queue.push_front_ae(1), 2) def test_push_ni(self): - self.assertEqual(self.queue.push_back_ni(1), [1, True]) - self.assertEqual(self.queue.push_back_ni(2), [2, True]) - self.assertEqual(self.queue.push_back_ni(4), [3, True]) - self.assertEqual(self.queue.push_back_ni(4), [3, False]) - self.assertEqual(self.queue.push_back_ni('apple'), [4, True]) + self.assertEqual(self.queue.push_back_ni(1), (1, True)) + self.assertEqual(self.queue.push_back_ni(2), (2, True)) + self.assertEqual(self.queue.push_back_ni(4), (3, True)) + self.assertEqual(self.queue.push_back_ni(4), (3, False)) + self.assertEqual(self.queue.push_back_ni('apple'), (4, True)) self.assertEqual(self.queue.pop_front(), '1') self.assertEqual(self.queue.pop_back(), 'apple') def test_range(self): - self.queue.push_back((1, 2, 3, 4)) + self.queue.push_back([1, 2, 3, 4]) self.assertEqual(self.queue.range(0, -1), ['1', '2', '3', '4']) self.assertEqual(self.queue.range(0, 2), ['1', '2', '3']) self.assertEqual(self.queue.range(0, 0), ['1']) @@ -53,7 +53,7 @@ def test_range(self): self.assertEqual(self.queue.range(0, -1), []) def test_expire(self): - self.queue.push_back((1, 2)) + self.queue.push_back([1, 2]) self.assertEqual(self.queue.ttl(), -1) self.queue.expire(10) self.assertEqual(self.queue.ttl(), 10) @@ -84,11 +84,11 @@ def test_push_e(self): self.assertEqual(self.queue.push_front_ae(1), 2) def test_push_ni(self): - self.assertEqual(self.queue.push_back_ni(1), [1, True]) - self.assertEqual(self.queue.push_back_ni(1), [1, False]) - self.assertEqual(self.queue.push_front_ni(2), [2, True]) - self.assertEqual(self.queue.push_front_ni(2), [2, False]) - self.assertEqual(self.queue.push_back_ni(3), [3, True]) + self.assertEqual(self.queue.push_back_ni(1), (1, True)) + self.assertEqual(self.queue.push_back_ni(1), (1, False)) + self.assertEqual(self.queue.push_front_ni(2), (2, True)) + self.assertEqual(self.queue.push_front_ni(2), (2, False)) + self.assertEqual(self.queue.push_back_ni(3), (3, True)) self.assertEqual(self.queue.push_back_ni(3), 'err_qf') self.assertEqual(self.queue.push_back_ni(4), 'err_qf') self.assertEqual(self.queue.pop_front(), '2') @@ -104,27 +104,27 @@ def tearDown(self): self.queue.destruct() def test_push(self): - self.assertEqual(self.queue.push_back([1, 2]), [2, []]) - self.assertEqual(self.queue.push_front(3), [3, []]) - self.assertEqual(self.queue.push_back(4), [3, ['3']]) + self.assertEqual(self.queue.push_back([1, 2]), (2, [])) + self.assertEqual(self.queue.push_front(3), (3, [])) + self.assertEqual(self.queue.push_back(4), (3, ['3'])) self.assertEqual(self.queue.pop_front(), '1') self.assertEqual(self.queue.pop_back(), '4') def test_push_e(self): - self.assertEqual(self.queue.push_front_ne(1), [1, []]) + self.assertEqual(self.queue.push_front_ne(1), (1, [])) self.assertFalse(self.queue.push_back_ne(1)) self.queue.destruct() self.assertFalse(self.queue.push_front_ae(1)) self.queue.push_front(1) - self.assertEqual(self.queue.push_front_ae(1), [2, []]) + self.assertEqual(self.queue.push_front_ae(1), (2, [])) def test_push_ni(self): - self.assertEqual(self.queue.push_back_ni('apple'), [1, [], True]) - self.assertEqual(self.queue.push_back_ni('banana'), [2, [], True]) - self.assertEqual(self.queue.push_back_ni('banana'), [2, [], False]) - self.assertEqual(self.queue.push_front_ni('pear'), [3, [], True]) - self.assertEqual(self.queue.push_front_ni('pear'), [3, [], False]) - self.assertEqual(self.queue.push_front_ni('grape'), [3, ['banana'], True]) + self.assertEqual(self.queue.push_back_ni('apple'), (1, [], True)) + self.assertEqual(self.queue.push_back_ni('banana'), (2, [], True)) + self.assertEqual(self.queue.push_back_ni('banana'), (2, [], False)) + self.assertEqual(self.queue.push_front_ni('pear'), (3, [], True)) + self.assertEqual(self.queue.push_front_ni('pear'), (3, [], False)) + self.assertEqual(self.queue.push_front_ni('grape'), (3, ['banana'], True)) self.assertEqual(self.queue.pop_front(), 'grape') self.assertEqual(self.queue.pop_back(), 'apple') diff --git a/tests/test_priorityqueue.py b/tests/test_priorityqueue.py index 02958ce..9fdfd9c 100755 --- a/tests/test_priorityqueue.py +++ b/tests/test_priorityqueue.py @@ -33,11 +33,11 @@ def test_push_e(self): self.assertEqual(self.queue.push_ne({'alice': 1}), 1) def test_push_ni(self): - self.assertEqual(self.queue.push_ni('alice', 1), [1, True]); - self.assertEqual(self.queue.push_ni('bob', 2), [2, True]); - self.assertEqual(self.queue.push_ni('alice', 1), [2, False]); - self.assertEqual(self.queue.push_ni('bob', 2), [2, False]); - self.assertEqual(self.queue.push_ni('cath', 3), [3, True]); + self.assertEqual(self.queue.push_ni('alice', 1), (1, True)) + self.assertEqual(self.queue.push_ni('bob', 2), (2, True)) + self.assertEqual(self.queue.push_ni('alice', 1), (2, False)) + self.assertEqual(self.queue.push_ni('bob', 2), (2, False)) + self.assertEqual(self.queue.push_ni('cath', 3), (3, True)) def test_range(self): values = { @@ -56,12 +56,11 @@ def test_indexof(self): "cath": 3, } self.queue.push(values) - self.assertEqual(self.queue.indexofone('alice'), 0) - self.assertEqual(self.queue.indexofone('bob'), 1) - self.assertEqual(self.queue.indexofone('cath'), 2) - self.assertEqual(self.queue.indexofone('dick'), None) - self.assertEqual(self.queue.indexofmany(['alice', 'bob', 'dick']), {'alice': 0, 'bob': 1, 'dick': None}) - + self.assertEqual(self.queue.indexof_one('alice'), 0) + self.assertEqual(self.queue.indexof_one('bob'), 1) + self.assertEqual(self.queue.indexof_one('cath'), 2) + self.assertEqual(self.queue.indexof_one('dick'), None) + self.assertEqual(self.queue.indexof_many(['alice', 'bob', 'dick']), {'alice': 0, 'bob': 1, 'dick': None}) class TestCappedPriorityQueue(TestPriorityQueue): @@ -87,13 +86,13 @@ def test_push_e(self): self.assertEqual(self.queue.push_ne({'alice': 1}), 1) def test_push_ni(self): - self.assertEqual(self.queue.push_ni('alice', 1), [1, True]); - self.assertEqual(self.queue.push_ni('bob', 2), [2, True]); - self.assertEqual(self.queue.push_ni('alice', 1), [2, False]); - self.assertEqual(self.queue.push_ni('bob', 2), [2, False]); - self.assertEqual(self.queue.push_ni('cath', 3), [3, True]); - self.assertEqual(self.queue.push_ni('cath', 3), 'err_qf'); - self.assertEqual(self.queue.push_ni('dick', 3), 'err_qf'); + self.assertEqual(self.queue.push_ni('alice', 1), (1, True)) + self.assertEqual(self.queue.push_ni('bob', 2), (2, True)) + self.assertEqual(self.queue.push_ni('alice', 1), (2, False)) + self.assertEqual(self.queue.push_ni('bob', 2), (2, False)) + self.assertEqual(self.queue.push_ni('cath', 3), (3, True)) + self.assertEqual(self.queue.push_ni('cath', 3), 'err_qf') + self.assertEqual(self.queue.push_ni('dick', 3), 'err_qf') class TestOfCappedPriorityQueue(TestCappedPriorityQueue): @@ -106,23 +105,23 @@ def test_push_pop(self): 'cath': 3, 'dylon': 4, }) - self.assertEqual(p, [2, []]) - self.assertEqual(self.queue.push({'alice': 1, 'bob': 2}), [3, [('dylon', 4)]]) - self.assertEqual(self.queue.push({'cathe': 0}), [3, [('cath', 3)]]) + self.assertEqual(p, (2, [])) + self.assertEqual(self.queue.push({'alice': 1, 'bob': 2}), (3, [('dylon', 4)])) + self.assertEqual(self.queue.push({'cathe': 0}), (3, [('cath', 3)])) def test_push_e(self): self.assertFalse(self.queue.push_ae({'alice': 1})) self.queue.push({'alice': 1}) - self.assertEqual(self.queue.push_ae({'bob': 2}), [2, []]) + self.assertEqual(self.queue.push_ae({'bob': 2}), (2, [])) self.assertFalse(self.queue.push_ne({'alice': 1})) def test_push_ni(self): - self.assertEqual(self.queue.push_ni('alice', 1), [1, [], True]); - self.assertEqual(self.queue.push_ni('bob', 2), [2, [], True]); - self.assertEqual(self.queue.push_ni('alice', 1), [2, [], False]); - self.assertEqual(self.queue.push_ni('bob', 2), [2, [], False]); - self.assertEqual(self.queue.push_ni('cath', 3), [3, [], True]); - self.assertEqual(self.queue.push_ni('dick', 0), [3, [('cath', 3)], True]); - self.assertEqual(self.queue.push_ni('ed', 5), [3, [], False]); - self.assertEqual(self.queue.push_ni('ed', 1), [3, [('bob', 2)], True]); + self.assertEqual(self.queue.push_ni('alice', 1), (1, [], True)) + self.assertEqual(self.queue.push_ni('bob', 2), (2, [], True)) + self.assertEqual(self.queue.push_ni('alice', 1), (2, [], False)) + self.assertEqual(self.queue.push_ni('bob', 2), (2, [], False)) + self.assertEqual(self.queue.push_ni('cath', 3), (3, [], True)) + self.assertEqual(self.queue.push_ni('dick', 0), (3, [('cath', 3)], True)) + self.assertEqual(self.queue.push_ni('ed', 5), (3, [], False)) + self.assertEqual(self.queue.push_ni('ed', 1), (3, [('bob', 2)], True)) diff --git a/tests/test_queue.py b/tests/test_queue.py index 4d4c7ef..84bcb47 100755 --- a/tests/test_queue.py +++ b/tests/test_queue.py @@ -13,7 +13,7 @@ def tearDown(self): self.queue.destruct() def test_push_pop(self): - ql = self.queue.push((1, 2)) + ql = self.queue.push([1, 2]) self.assertEqual(ql, 2) self.assertEqual(self.queue.length(), 2) head = self.queue.pop() @@ -21,17 +21,17 @@ def test_push_pop(self): self.assertEqual(self.queue.length(), 1) self.assertEqual(len(self.queue), 1) - self.queue.push((3, 4, 5)) + self.queue.push([3, 4, 5]) head3 = self.queue.pop(3) self.assertEqual(head3, ['2', '3', '4']) self.assertEqual(self.queue.pop(), '5') self.assertEqual(self.queue.pop(), None) def test_push_ni(self): - self.assertEqual(self.queue.push_ni(1), [1, True]) - self.assertEqual(self.queue.push_ni(1), [1, False]) - self.assertEqual(self.queue.push_ni('apple'), [2, True]) - self.assertEqual(self.queue.push_ni('apple'), [2, False]) + self.assertEqual(self.queue.push_ni(1), (1, True)) + self.assertEqual(self.queue.push_ni(1), (1, False)) + self.assertEqual(self.queue.push_ni('apple'), (2, True)) + self.assertEqual(self.queue.push_ni('apple'), (2, False)) def test_push_ae(self): self.assertFalse(self.queue.push_ae(1)) @@ -43,7 +43,7 @@ def test_push_ne(self): self.assertFalse(self.queue.push_ne(1)) def test_range(self): - self.queue.push((1, 2, 3, 4)) + self.queue.push([1, 2, 3, 4]) self.assertEqual(self.queue.range(0, -1), ['1', '2', '3', '4']) self.assertEqual(self.queue.range(0, 2), ['1', '2', '3']) self.assertEqual(self.queue.range(0, 0), ['1']) @@ -51,7 +51,7 @@ def test_range(self): self.assertEqual(self.queue.range(0, -1), []) def test_expire(self): - self.queue.push((1, 2)) + self.queue.push([1, 2]) self.assertEqual(self.queue.ttl(), -1) self.queue.expire(10) self.assertEqual(self.queue.ttl(), 10) @@ -59,11 +59,11 @@ def test_expire(self): self.assertEqual(self.queue.ttl(), -2) def test_indexof(self): - self.queue.push((1, 2)) - self.assertEqual(self.queue.indexofone(1), 0) - self.assertEqual(self.queue.indexofone(2), 1) - self.assertEqual(self.queue.indexofone(3), None) - self.assertEqual(self.queue.indexofmany([1,2,3]), {1: 0, 2: 1, 3: None}) + self.queue.push([1, 2]) + self.assertEqual(self.queue.indexof_one(1), 0) + self.assertEqual(self.queue.indexof_one(2), 1) + self.assertEqual(self.queue.indexof_one(3), None) + self.assertEqual(self.queue.indexof_many([1, 2, 3]), {1: 0, 2: 1, 3: None}) class TestCappedQueue(unittest.TestCase): @@ -75,7 +75,7 @@ def tearDown(self): self.queue.destruct() def test_push(self): - self.assertEqual(self.queue.push((1, 2, 3)), 3) + self.assertEqual(self.queue.push([1, 2, 3]), 3) self.assertEqual(self.queue.push(4), 'err_qf') def test_push_ae(self): @@ -88,7 +88,7 @@ def test_push_ne(self): self.assertFalse(self.queue.push_ne(1)) def test_push_ni(self): - self.assertEqual(self.queue.push((1, 2, 3)), 3) + self.assertEqual(self.queue.push([1, 2, 3]), 3) self.assertEqual(self.queue.push_ni(1), 'err_qf') self.assertEqual(self.queue.push_ni('apple'), 'err_qf') @@ -102,21 +102,21 @@ def tearDown(self): self.queue.destruct() def test_push(self): - self.assertEqual(self.queue.push((1, 2, 3)), [3, []]) - self.assertEqual(self.queue.push(4), [3, ['1']]) + self.assertEqual(self.queue.push([1, 2, 3]), (3, [])) + self.assertEqual(self.queue.push(4), (3, ['1'])) self.assertEqual(self.queue.range(0, -1), ['2', '3', '4']) def test_push_ae(self): self.assertFalse(self.queue.push_ae(1)) self.queue.push(1) - self.assertEqual(self.queue.push_ae(2), [2, []]) + self.assertEqual(self.queue.push_ae(2), (2, [])) def test_push_ne(self): - self.assertEqual(self.queue.push_ne(1), [1, []]) + self.assertEqual(self.queue.push_ne(1), (1, [])) self.assertFalse(self.queue.push_ne(1)) def test_push_ni(self): - self.assertEqual(self.queue.push((1, 2, 3)), [3, []]) - self.assertEqual(self.queue.push_ni(1), [3, [], False]) - self.assertEqual(self.queue.push_ni('apple'), [3, ['1'], True]) + self.assertEqual(self.queue.push([1, 2, 3]), (3, [])) + self.assertEqual(self.queue.push_ni(1), (3, [], False)) + self.assertEqual(self.queue.push_ni('apple'), (3, ['1'], True)) diff --git a/tests/test_stack.py b/tests/test_stack.py index dd52460..743585f 100755 --- a/tests/test_stack.py +++ b/tests/test_stack.py @@ -27,18 +27,17 @@ def test_push_e(self): self.assertEqual(self.queue.push_ae(1), 2) def test_push_ni(self): - self.assertEqual(self.queue.push_ni(1), [1, True]) - self.assertEqual(self.queue.push_ni('apple'), [2, True]) - self.assertEqual(self.queue.push_ni(1), [2, False]) - self.assertEqual(self.queue.push_ni('apple'), [2, False]) - + self.assertEqual(self.queue.push_ni(1), (1, True)) + self.assertEqual(self.queue.push_ni('apple'), (2, True)) + self.assertEqual(self.queue.push_ni(1), (2, False)) + self.assertEqual(self.queue.push_ni('apple'), (2, False)) def test_indexof(self): self.queue.push(['apple', 'banana']) - self.assertEqual(self.queue.indexofone('banana'), 0) - self.assertEqual(self.queue.indexofone('apple'), 1) - self.assertEqual(self.queue.indexofone('pear'), None) - self.assertEqual(self.queue.indexofmany(['apple', 'banana', 'pear']), {'apple': 1, 'banana': 0, 'pear': None}) + self.assertEqual(self.queue.indexof_one('banana'), 0) + self.assertEqual(self.queue.indexof_one('apple'), 1) + self.assertEqual(self.queue.indexof_one('pear'), None) + self.assertEqual(self.queue.indexof_many(['apple', 'banana', 'pear']), {'apple': 1, 'banana': 0, 'pear': None}) class TestCappedStack(TestStack): @@ -61,9 +60,9 @@ def test_push_e(self): self.assertEqual(self.queue.push_ae(1), 2) def test_push_ni(self): - self.assertEqual(self.queue.push_ni(1), [1, True]) - self.assertEqual(self.queue.push_ni(1), [1, False]) - self.assertEqual(self.queue.push_ni(2), [2, True]) - self.assertEqual(self.queue.push_ni(3), [3, True]) + self.assertEqual(self.queue.push_ni(1), (1, True)) + self.assertEqual(self.queue.push_ni(1), (1, False)) + self.assertEqual(self.queue.push_ni(2), (2, True)) + self.assertEqual(self.queue.push_ni(3), (3, True)) self.assertEqual(self.queue.push_ni(4), 'err_qf')