Created
April 3, 2017 15:57
-
-
Save hishnash/093b82dd8d7c840aef58d1b526c28020 to your computer and use it in GitHub Desktop.
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
from collections import deque | |
import psutil | |
from settings import settings | |
from collections import AsyncIterable | |
class AsyncIteratorWrapper(AsyncIterable): | |
def __init__(self, obj): | |
self._it = iter(obj) | |
def __aiter__(self): | |
return self | |
async def __anext__(self): | |
try: | |
value = next(self._it) | |
except StopIteration: | |
raise StopAsyncIteration | |
return value | |
class Cache: | |
def __init__(self, items_per_page=100000, max_pages=5): | |
self.items_per_page = items_per_page | |
self.max_pages = max_pages | |
self._pages = deque() | |
async def clean(self): | |
while len(self._pages) > self.max_pages: | |
self._pages.popleft() | |
if (len(self._pages) > 1 and | |
self._free_space() <= settings.MIN_FREE_MEMORY_SPACE_IN_BYTES): | |
self._pages.popleft() | |
while (len(self._pages) > 1 and | |
self._free_space_percent() <= | |
settings.MIN_FREE_MEMORY_SPACE_PERCENT): | |
self._pages.popleft() | |
def _free_space(self) -> float: | |
mem = psutil.virtual_memory() | |
return mem.available | |
def _free_space_percent(self) -> float: | |
mem = psutil.virtual_memory() | |
return 1 - (mem.percent / 100) | |
async def add(self, key: str, value: dict) -> dict: | |
if (len(self._pages) == 0 or | |
len(self._pages[-1]) >= self.items_per_page): | |
self._new_page({key: value}) | |
await self.clean() | |
return value | |
self._pages[-1][key] = value | |
return value | |
def _new_page(self, page: dict): | |
self._pages.append(page) | |
async def get(self, key) -> dict: | |
async for page in AsyncIteratorWrapper(self._pages): | |
try: | |
return page[key] | |
except KeyError: | |
pass | |
raise KeyError() | |
def __len__(self): | |
return sum(len(page) for page in self._pages) | |
def _number_of_pages(self): | |
return len(self._pages) | |
def reset(self): | |
self._pages = deque() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment