implement cache functionality