I want to build a circular file buffer, in python, to hold file names (strings). The buffer should have the following properties.
Is it possible to extend deque for such a purpose?
Or should I write it from scratch? Is there any design ideas that I can use for this purpose?
thanks
suresh
OK, I believe that Raymond Hettinger's interpretation of your question is correct, and your comment has clarified that you're not concerned with the length of the queue, but rather with the sum of all the filesizes. That makes a lot more sense, and I'm glad I finally understand what you mean. With that in mind, here's a simple implementation based on heapq
that I believe satisfies all your stated requirements. Use it by put
ting (timestamp, filename, filesize)
tuples on the queue, and note that when you get
an item from the queue, it will be the oldest file (i.e. the file with the smallest timestamp.)
import heapq
class FilenameQueue(object):
def __init__(self, times_sizes_names, maxsize):
self.maxsize = maxsize
self.size = sum(s for t, s, n in times_sizes_names)
self.files = list(times_sizes_names)
heapq.heapify(self.files)
while self.size > self.maxsize:
self.get()
def __len__(self):
return len(self.files)
def put(self, time_size_name):
self.size += time_size_name[1]
if self.size < self.maxsize:
heapq.heappush(self.files, time_size_name)
else:
time_size_name = heapq.heappushpop(self.files, time_size_name)
self.size -= time_size_name[1]
def get(self):
time_size_name = heapq.heappop(self.files)
self.size -= time_size_name[1]
return time_size_name
I added a __len__
method so that you can test the queue before getting from it. Here's a usage example:
>>> f = FilenameQueue(((22, 33, 'f1'), (44, 55, 'f2'), (33, 22, 'f3')), 150)
>>> while f:
... f.get()
...
(22, 33, 'f1')
(33, 22, 'f3')
(44, 55, 'f2')
>>> f = FilenameQueue(((22, 33, 'f1'), (44, 55, 'f2'), (33, 22, 'f3')), 150)
>>> f.put((55, 66, 'f4'))
>>> while f:
... f.get()
...
(33, 22, 'f3')
(44, 55, 'f2')
(55, 66, 'f4')
See my edit history for a completely different solution involving Queue.PriorityQueue
that is suboptimal. I forgot that maxsize
enforces the limit by blocking, not by discarding elements. That's not so useful!