refactor lib/cache.js into smaller pieces

Breaks the helper functions out into smaller pieces, adds a few tests, uses some helper modules, and ensures that all helper functions are always called with a consistent number of parameters.