fully functional layered cache, except get where generalization would be harder to understand