DRY cache key generation