tasksqueue.py 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. # copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
  2. # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
  3. #
  4. # This file is part of logilab-common.
  5. #
  6. # logilab-common is free software: you can redistribute it and/or modify it under
  7. # the terms of the GNU Lesser General Public License as published by the Free
  8. # Software Foundation, either version 2.1 of the License, or (at your option) any
  9. # later version.
  10. #
  11. # logilab-common is distributed in the hope that it will be useful, but WITHOUT
  12. # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  13. # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  14. # details.
  15. #
  16. # You should have received a copy of the GNU Lesser General Public License along
  17. # with logilab-common. If not, see <http://www.gnu.org/licenses/>.
  18. """Prioritized tasks queue"""
  19. __docformat__ = "restructuredtext en"
  20. from bisect import insort_left
  21. from Queue import Queue
  22. LOW = 0
  23. MEDIUM = 10
  24. HIGH = 100
  25. PRIORITY = {
  26. 'LOW': LOW,
  27. 'MEDIUM': MEDIUM,
  28. 'HIGH': HIGH,
  29. }
  30. REVERSE_PRIORITY = dict((values, key) for key, values in PRIORITY.iteritems())
  31. class PrioritizedTasksQueue(Queue):
  32. def _init(self, maxsize):
  33. """Initialize the queue representation"""
  34. self.maxsize = maxsize
  35. # ordered list of task, from the lowest to the highest priority
  36. self.queue = []
  37. def _put(self, item):
  38. """Put a new item in the queue"""
  39. for i, task in enumerate(self.queue):
  40. # equivalent task
  41. if task == item:
  42. # if new task has a higher priority, remove the one already
  43. # queued so the new priority will be considered
  44. if task < item:
  45. item.merge(task)
  46. del self.queue[i]
  47. break
  48. # else keep it so current order is kept
  49. task.merge(item)
  50. return
  51. insort_left(self.queue, item)
  52. def _get(self):
  53. """Get an item from the queue"""
  54. return self.queue.pop()
  55. def __iter__(self):
  56. return iter(self.queue)
  57. def remove(self, tid):
  58. """remove a specific task from the queue"""
  59. # XXX acquire lock
  60. for i, task in enumerate(self):
  61. if task.id == tid:
  62. self.queue.pop(i)
  63. return
  64. raise ValueError('not task of id %s in queue' % tid)
  65. class Task(object):
  66. def __init__(self, tid, priority=LOW):
  67. # task id
  68. self.id = tid
  69. # task priority
  70. self.priority = priority
  71. def __repr__(self):
  72. return '<Task %s @%#x>' % (self.id, id(self))
  73. def __cmp__(self, other):
  74. return cmp(self.priority, other.priority)
  75. def __lt__(self, other):
  76. return self.priority < other.priority
  77. def __eq__(self, other):
  78. return self.id == other.id
  79. def merge(self, other):
  80. pass