Skip to content

Instantly share code, notes, and snippets.

@bhgomes
Last active June 27, 2020 06:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bhgomes/e201670574d165d7b051d9b1ba774e75 to your computer and use it in GitHub Desktop.
Save bhgomes/e201670574d165d7b051d9b1ba774e75 to your computer and use it in GitHub Desktop.
Line Reader
class LineReader:
"""
Read a static file with smart line access.
WARNING: This implementation assumes that the file does not change between
calls of the `clear` function and never checks for valid file handlers.
"""
def __init__(self, file_handle=None, cache=None, offsets=None):
"""Initialize the LineReader."""
self.file_handle = file_handle
self.cache = cache if cache else {}
self.offsets = offsets if offsets else []
def clear(self):
"""Clear line cache and offset table."""
self.cache.clear()
self.offsets.clear()
def get(self, n):
"""
Get line as fast as possible, using the line cache and offset table.
"""
line = self.cache.get(n)
if line is not None or n < 0:
return line
offset_index = len(self.offsets) - 1
if offset_index >= n:
self.file_handle.seek(self.offsets[n])
self.cache[n] = self.file_handle.readline()[:-1]
return self.cache[n]
if not self.offsets:
self.offsets.append(0)
offset_index = 0
self.file_handle.seek(self.offsets[-1])
for index, line in enumerate(self.file_handle, start=offset_index):
self.offsets.append(self.offsets[-1] + len(line))
if index == n:
self.cache[n] = line[:-1]
return self.cache[n]
return None
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment