From 2ed952e989e7ca026b2cba66f1f68da4d3c88927 Mon Sep 17 00:00:00 2001 From: Erfan Date: Wed, 2 May 2012 03:05:55 +0430 Subject: [PATCH] add some functionlity and exceptions --- .gitignore | 3 + HashPQ.py | 357 +++++++++++++++++++++++++++++++++++++++++++++++++++++ TODO | 17 +++ hashpq.py | 51 ++++++-- 4 files changed, 421 insertions(+), 7 deletions(-) create mode 100644 .gitignore create mode 100644 HashPQ.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e961147 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.swp +*.swo + diff --git a/HashPQ.py b/HashPQ.py new file mode 100644 index 0000000..0d9c9b5 --- /dev/null +++ b/HashPQ.py @@ -0,0 +1,357 @@ +#!/usr/bin/python +from threading import Event +import time +import Queue + + +try: + from collections import OrderedDict +except: + # If could not, import it from local directory + from OrderedDict import OrderedDict + + +DEFAULT_PRIORITY = 0 +DEFAULT_QUEUE = 0 + +class HashPQueue(object): + __slots__ = [ '__capacity',\ + '__size',\ + '__dic',\ + '__lock',\ + ] + + def __new__(cls, *args, **kwargs): + return super(HashPQueue, cls).__new__(cls, *args, **kwargs) + + def __str__(self): + return self.__dic.__str__() + + def __repr__(self): + return self.__dic.__str__() + + def __iter__(self): + pass + + def __call__(self): + pass + + def __init__(self, capacity=None, *args, **kwargs): + self.__capacity = capacity + self.__size = 0 + self.__dic = {} + self.__lock = Event() + + def qsize(self): + return self.__size + + def get(self): + if not self.__dic: + self.__lock.wait() + # sort keys in list + self.__dic.keys().sort() + highestPriority = self.__dic.keys()[-1] + # get high priority list + highestPriorityList = self.__dic[highestPriority] + item = highestPriorityList.popitem(last=False) + self.__size -= 1 + if not self.__size: + self.__lock.clear() + else: + self.__lock.set() + if not highestPriorityList: + del self.__dic[highestPriority] + return item[1] + + def get_by_key(self, key, priority=None): + if not self.__dic: + self.__lock.wait() + value = None + if priority: + try: + value = self.__dic[priority].pop(key) + except: + return None + try: + for priority in self.__dic.keys(): + if key in self.__dic[priority]: + priorityList = self.__dic[priority] + value = self.__dic[priority].pop(key) + break + except: + return None + self.__size -= 1 + if not self.__size: + self.__lock.clear() + else: + self.__lock.set() + if not self.__dic[priority]: + del self.__dic[priority] + return value + + + def pick(self): + pass + + def pick_nowait(self): + pass + + def pick_as_list(self): + pass + + def get_as_list(self): + # retrun none if hashpq is empty + # FIXME + if not self.__dic: + self.__lock.wait() + queue_list = self.__dic.keys() + queue_list.sort(reverse=True) + item_list = [] + for queue in queue_list: + print queue + for item in self.__dic[queue].items(): + print item + item_list.append(item) + return item_list + + def get_as_list_nowait(self): + # retrun none if hashpq is empty + # FIXME + if not self.__dic: + raise EmptyHashPQ + queue_list = self.__dic.keys() + queue_list.sort(reverse=True) + item_list = [] + for queue in queue_list: + print queue + for item in self.__dic[queue].items(): + print item + item_list.append(item) + return item_list + + + def pick_by_key_nowait(self, key, priority=None): + if not self.__dic: + raise EmptyHashPQ + value = None + if priority: + try: + value = self.__dic[priority][key] + except: + return None + try: + for priority in self.__dic.keys(): + if key in self.__dic[priority]: + value = self.__dic[priority][key] + break + except: + return None + return value + + def get_dic(self): + return self.__dic + + def pick_by_key(self, key, priority=None): + if not self.__dic: + self.__lock.wait() + value = None + if priority: + try: + value = self.__dic[priority][key] + except: + return None + try: + for priority in self.__dic.keys(): + if key in self.__dic[priority]: + value = self.__dic[priority][key] + break + except: + return None + return value + def get_by_key_nowait(self, key, priority=None): + if not self.__dic: + raise EmptyHashPQ + value = None + if priority: + try: + value = self.__dic[priority].pop(key) + except: + return None + try: + for priority in self.__dic.keys(): + if key in self.__dic[priority]: + value = self.__dic[priority].pop(key) + break + except: + return None + self.__size -= 1 + if not self.__size: + self.__lock.clear() + else: + self.__lock.set() + if not self.__dic[priority]: + del self.__dic[priority] + return value + + def put(self, item): + if not item: + return False + if self.__size == self.__capacity: + self.__lock.clear() + self.__lock.wait() + try: + priority = item[0] + key = item[1] + value = item[2] + except IndexError: + try: + priority = DEFAULT_PRIORITY + key = item[0] + value = item[1] + except IndexError: + priority = DEFAULT_PRIORITY + key = DEFAULT_QUEUE + value = item[0] + except ValueError: + return False + except: + return False + if priority not in self.__dic.keys(): + self.__dic[priority] = OrderedDict() + if key not in self.__dic[priority]: + self.__size += 1 + self.__dic[priority][key] = value + self.__lock.set() + + def get_nowait(self): + if not self.__dic: + raise EmptyHashPQ + # sort keys in list + self.__dic.keys().sort() + highestPriority = self.__dic.keys()[-1] + # get high priority list + highestPriorityList = self.__dic[highestPriority] + item = highestPriorityList.popitem(last=False) + self.__size -= 1 + if not self.__size: + self.__lock.clear() + else: + self.__lock.set() + if not highestPriorityList: + del self.__dic[highestPriority] + return item[1] + + def put_nowait_with_kwa(self, **kwargs): + if not kwargs: + return False + if self.__size == self.__capacity: + raise FullHashPQ + if self.__size == self.__capacity: + self.__lock.clear() + self.__lock.wait() + if 'priority' in kwargs: + priority = kwargs['priority'] + else: + priority = DEFAULT_PRIORITY + + if 'key' in kwargs: + key = kwargs['key'] + else: + key = DEFAULT_QUEUE + + if 'value' in kwargs: + value = kwargs['value'] + else: + raise Exception + return False + + if priority not in self.__dic.keys(): + self.__dic[priority] = OrderedDict() + if key not in self.__dic[priority]: + self.__size += 1 + self.__dic[priority][key] = value + self.__lock.set() + + def put_nowait(self, item): + if not item: + return False + if self.__size == self.__capacity: + raise FullHashPQ + if self.__size == self.__capacity: + self.__lock.clear() + self.__lock.wait() + try: + priority = item[0] + key = item[1] + value = item[2] + except IndexError: + try: + priority = DEFAULT_PRIORITY + key = item[0] + value = item[1] + except IndexError: + priority = DEFAULT_PRIORITY + key = DEFAULT_QUEUE + value = item[0] + except: + return False + if priority not in self.__dic.keys(): + self.__dic[priority] = OrderedDict() + if key not in self.__dic[priority]: + self.__size += 1 + self.__dic[priority][key] = value + self.__lock.set() + + +class HashPQException(Exception): + pass + +class EmptyHashPQ(HashPQException): + pass + +class FullHashPQ(HashPQException): + pass + +class InvalidHashKey(HashPQException): + pass + + +if __name__ == '__main__': + pq = HashPQueue() + pq.put_nowait((1, 3, 4)) + pq.put_nowait((1, 4, 3)) + pq.put_nowait((1, 4, 6)) + pq.put_nowait((1, 4, 6)) + pq.put_nowait((4, 4, 6)) + pq.put_nowait((1, 4, 6)) + pq.put_nowait((3, 4, 6)) + pq.put_nowait((1, 4, 6)) + pq.put_nowait((5, 4, 6)) + pq.put_nowait((1, 4, 6)) + pq.put_nowait((1, 4, 6)) + pq.put_nowait((5, 4, 6)) + pq.put_nowait((8, 4, 7)) + pq.put_nowait((3, 6)) + pq.put_nowait((2,)) + pq.put_nowait_with_kwa(priority=3, value=3) + pq.get_dic() + print "get_as_list:", pq.get_as_list() + print pq.qsize() + + print pq + print pq.get_nowait() + print pq + #print pq.get_by_key(3) + #print pq + print pq.get_nowait() + print pq + print pq.get_nowait() + print pq + print pq.get_nowait() + print pq + print pq.get_nowait() + print pq + print pq.get_nowait() + print pq + + diff --git a/TODO b/TODO index e69de29..e679c71 100644 --- a/TODO +++ b/TODO @@ -0,0 +1,17 @@ + +# TODO of FIXME +# work on exceptions during get or put +# about return values list or tuples or simple variables +# use oredered dict instead of dic for all dic +# work on exception +# how to return items just values or both +# use keywordarguments instead of positional ones +# override functions by some options +# queues have tails and head to easily iterate on it all +# add thread safety to lib +# define proper Exceptions in right condition *** +# consider argument to modify return value of get_as_list +# # to return some or all of elements +# delete extra codes existed cause of redefinition of blocking and +# Nonblocking functins +# diff --git a/hashpq.py b/hashpq.py index 591cd43..0d9c9b5 100644 --- a/hashpq.py +++ b/hashpq.py @@ -9,8 +9,7 @@ except: # If could not, import it from local directory from OrderedDict import OrderedDict - - + DEFAULT_PRIORITY = 0 DEFAULT_QUEUE = 0 @@ -90,13 +89,21 @@ def get_by_key(self, key, priority=None): del self.__dic[priority] return value + def pick(self): pass def pick_nowait(self): pass + def pick_as_list(self): + pass + def get_as_list(self): + # retrun none if hashpq is empty + # FIXME + if not self.__dic: + self.__lock.wait() queue_list = self.__dic.keys() queue_list.sort(reverse=True) item_list = [] @@ -107,9 +114,25 @@ def get_as_list(self): item_list.append(item) return item_list + def get_as_list_nowait(self): + # retrun none if hashpq is empty + # FIXME + if not self.__dic: + raise EmptyHashPQ + queue_list = self.__dic.keys() + queue_list.sort(reverse=True) + item_list = [] + for queue in queue_list: + print queue + for item in self.__dic[queue].items(): + print item + item_list.append(item) + return item_list + + def pick_by_key_nowait(self, key, priority=None): if not self.__dic: - return None + raise EmptyHashPQ value = None if priority: try: @@ -147,7 +170,7 @@ def pick_by_key(self, key, priority=None): return value def get_by_key_nowait(self, key, priority=None): if not self.__dic: - return None + raise EmptyHashPQ value = None if priority: try: @@ -202,7 +225,7 @@ def put(self, item): def get_nowait(self): if not self.__dic: - return None + raise EmptyHashPQ # sort keys in list self.__dic.keys().sort() highestPriority = self.__dic.keys()[-1] @@ -222,7 +245,7 @@ def put_nowait_with_kwa(self, **kwargs): if not kwargs: return False if self.__size == self.__capacity: - return False + raise FullHashPQ if self.__size == self.__capacity: self.__lock.clear() self.__lock.wait() @@ -253,7 +276,7 @@ def put_nowait(self, item): if not item: return False if self.__size == self.__capacity: - return False + raise FullHashPQ if self.__size == self.__capacity: self.__lock.clear() self.__lock.wait() @@ -279,6 +302,20 @@ def put_nowait(self, item): self.__dic[priority][key] = value self.__lock.set() + +class HashPQException(Exception): + pass + +class EmptyHashPQ(HashPQException): + pass + +class FullHashPQ(HashPQException): + pass + +class InvalidHashKey(HashPQException): + pass + + if __name__ == '__main__': pq = HashPQueue() pq.put_nowait((1, 3, 4))