Are there Python code for a FIFO-like structure?

Huaiyu Zhu hzhu at users.sourceforge.net
Mon Oct 9 18:39:35 EDT 2000


On Fri, 06 Oct 2000 22:07:24 +0100, Grant Griffin <g2 at seebelow.org> wrote:
>
>If I understand what you're after, here is a description of generic FIFO
>logic (caveat emptor: from memory):

Thanks.  I've got it working the way I indended, as enclosed below.  The
tricky part is to use negative indexing to simplify wrapping around, which
produced an off-by-one bug that took me quite some time to trace. Otherwise
it is quite straightforward.


#!/usr/bin/env python
# (C) 2000 Huaiyu Zhu <hzhu at users.sourceforge.net>.  Licence: GPL
# $Id: fiforing.py,v 1.1.1.1 2000/10/09 22:26:18 hzhu Exp $
"""
FifoRing - a Fifo implemented as a list that wraps around.
Supports: append at tail.  pop at head.  setitem.  getitem.
Generates warning when prespecified buffer is used up.
Implementation trick: use negative index for wrapping around.
"""


class FifoFullWarning(IndexError): pass

class FifoRing:
	"A Fifo implemented as ring of length n, with at warning zone of size m"
	def __init__(self, n, m):
		"Initialize list with elements that should never be accessed"
		self.data = ['N']*n
		self.head = self.tail = 0
		self.space = m

	def __repr__(self):
		return "Fifo: (%s, %s) %s" % (self.head, self.tail, self.data)

	def __str__(self):
		if self.head < 0:
			return str(self.data[self.head:] + self.data[0: self.tail])
		else:
			return str(self.data[self.head : self.tail])

	def __getitem__(self, i):
		if i < 0:
			return self.data[self.tail+i]
		else:
			return self.data[self.head+i]

	def __setitem__(self, i, value):
		if i < 0:
			i += self.tail
			if i < self.head: raise IndexError, "Address before FiFo head"
		else:
			i += self.head
			if i > self.tail: raise IndexError, "Address after FiFo tail"
		self.data[i] = value

	def __len__(self): return self.tail - self.head

	def append(self, item):
		"""Append a new item at tail.
		Raise FifoFullWarning for using up buffer space (used, total).
		Raise Index error for Fifo overflow"""
		n = len(self.data)
		if not len(self) < n:
			raise IndexError, "Fifo overflow"
		self.tail += 1
		if self.tail > n:	self.head -= n; self.tail -= n
		self[-1] = item
		if n < len(self) + self.space:
			raise FifoFullWarning, (n - len(self),  self.space)

	def pop(self):
		"""Pop the head element.
		Raise IndexError if self is empty
		"""
		if len(self) < 1:
			raise IndexError, "poping empty Fifo"
		else:
			a = self[0]
			self[0] = 'N'
			self.head += 1
			return a
		
if __name__ == "__main__":
	a = FifoRing(10,2)
	print "appending 6 elements"
	for i in range(6):
		print a, i
		a.append(i)

	print "pop off 4 elements"
	for i in range(4):
		print a.pop(), a

	print "append another 6, wrap around"
	for i in range(6):
		print a, i
		a.append(i)

	print "Changing elements (the real ones are wrap around)"
	for i in range(7):
		a[i] = a[i]*2
		print a

	print "Calling each element"
	for i in range(len(a)):
		print a[i]

	print "And backwards"
	for i in range(len(a)):
		print a[-1-i]

	print "Pop off 6 elements. 2 left"
	for i in range(6):
		print a.pop(), a
	
	print "Append more til it overflows"
	for i in range(20):
		print a, i
		try:
			a.append(i)
		except FifoFullWarning:
			print "Warning: using buffer area", a	
		except:
			print "Fatal: overflow", a
			break
			



More information about the Python-list mailing list