Last active
June 27, 2020 06:09
-
-
Save bhgomes/e201670574d165d7b051d9b1ba774e75 to your computer and use it in GitHub Desktop.
Line Reader
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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