some python3 refactor, use functools.lru_cache