From 5864e3efbacaafaaa76f7410d5d4ab2ab6e0e57b Mon Sep 17 00:00:00 2001 From: Akanksha Gupta Date: Sat, 12 Sep 2015 02:15:31 +0530 Subject: [PATCH 1/4] chanin delete cache function Summary: Deletes te cache based on partial key match. Test Plan: Delete should work on partial key match. Reviewers: srijan Reviewed By: srijan Differential Revision: http://phab.greyorange.sg/D8 --- src/simple_cache.erl | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/simple_cache.erl b/src/simple_cache.erl index b9d3145..45ecc2f 100644 --- a/src/simple_cache.erl +++ b/src/simple_cache.erl @@ -32,7 +32,7 @@ %%% Public API. -export([init/1]). -export([get/4]). --export([flush/1, flush/2]). +-export([flush/1, flush/2, clear/2]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Public API. @@ -52,6 +52,12 @@ flush(CacheName, Key) -> RealName = ?NAME(CacheName), ets:delete(RealName, Key). +%% @doc Deletes the keys that match the given pattern from the cache. +-spec clear(string(), term()) -> true. +clear(CacheName, Pattern) -> + RealName = ?NAME(CacheName), + ets:match_delete(RealName, Pattern). + %% @doc Deletes all keys in the given cache. -spec flush(string()) -> true. flush(CacheName) -> @@ -92,4 +98,4 @@ create_value(RealName, LifeTime, Key, FunResult) -> -spec now_usecs() -> pos_integer(). now_usecs() -> {MegaSecs, Secs, MicroSecs} = os:timestamp(), - MegaSecs * 1000000000000 + Secs * 1000000 + MicroSecs. \ No newline at end of file + MegaSecs * 1000000000000 + Secs * 1000000 + MicroSecs. From c8b04fff92f3782a44e4f1c1b0e5560aa67c4d01 Mon Sep 17 00:00:00 2001 From: Amber Mittal Date: Thu, 23 Apr 2020 00:24:07 +0530 Subject: [PATCH 2/4] Removed Name Building for cache name --- src/simple_cache.erl | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/src/simple_cache.erl b/src/simple_cache.erl index 45ecc2f..a472594 100644 --- a/src/simple_cache.erl +++ b/src/simple_cache.erl @@ -23,8 +23,6 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Types. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --define(ETS_TID, atom_to_list(?MODULE)). --define(NAME(N), list_to_atom(?ETS_TID ++ "_" ++ atom_to_list(N))). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Exports. @@ -40,8 +38,7 @@ %% @doc Initializes a cache. -spec init(string()) -> ok. init(CacheName) -> - RealName = ?NAME(CacheName), - RealName = ets:new(RealName, [ + CacheName = ets:new(CacheName, [ named_table, {read_concurrency, true}, public, {write_concurrency, true} ]), ok. @@ -49,37 +46,33 @@ init(CacheName) -> %% @doc Deletes the keys that match the given ets:matchspec() from the cache. -spec flush(string(), term()) -> true. flush(CacheName, Key) -> - RealName = ?NAME(CacheName), - ets:delete(RealName, Key). + ets:delete(CacheName, Key). %% @doc Deletes the keys that match the given pattern from the cache. -spec clear(string(), term()) -> true. clear(CacheName, Pattern) -> - RealName = ?NAME(CacheName), - ets:match_delete(RealName, Pattern). + ets:match_delete(CacheName, Pattern). %% @doc Deletes all keys in the given cache. -spec flush(string()) -> true. flush(CacheName) -> - RealName = ?NAME(CacheName), - true = ets:delete_all_objects(RealName). + true = ets:delete_all_objects(CacheName). %% @doc Tries to lookup Key in the cache, and execute the given FunResult %% on a miss. -spec get(string(), infinity|pos_integer(), term(), function()) -> term(). get(CacheName, LifeTime, Key, FunResult) -> - RealName = ?NAME(CacheName), - case ets:lookup(RealName, Key) of + case ets:lookup(CacheName, Key) of [] -> % Not found, create it. - create_value(RealName, LifeTime, Key, FunResult); + create_value(CacheName, LifeTime, Key, FunResult); [{Key, R, _CreatedTime, infinity}] -> R; % Found, wont expire, return the value. [{Key, R, CreatedTime, LifeTime}] -> TimeElapsed = now_usecs() - CreatedTime, if TimeElapsed > (LifeTime * 1000) -> % expired? create a new value - create_value(RealName, LifeTime, Key, FunResult); + create_value(CacheName, LifeTime, Key, FunResult); true -> R % Not expired, return it. end end. @@ -89,9 +82,9 @@ get(CacheName, LifeTime, Key, FunResult) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% @doc Creates a cache entry. -spec create_value(string(), pos_integer(), term(), function()) -> term(). -create_value(RealName, LifeTime, Key, FunResult) -> +create_value(CacheName, LifeTime, Key, FunResult) -> R = FunResult(), - ets:insert(RealName, {Key, R, now_usecs(), LifeTime}), + ets:insert(CacheName, {Key, R, now_usecs(), LifeTime}), R. %% @doc Returns total amount of microseconds since 1/1/1. From 55a23b8a9c768a3d566ad4eef5eb6e96f6a3f0eb Mon Sep 17 00:00:00 2001 From: Hritik Soni Date: Sat, 23 May 2020 14:21:06 +0530 Subject: [PATCH 3/4] expose create_value to support inserting in cache --- src/simple_cache.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/simple_cache.erl b/src/simple_cache.erl index a472594..5b5bb7e 100644 --- a/src/simple_cache.erl +++ b/src/simple_cache.erl @@ -30,7 +30,7 @@ %%% Public API. -export([init/1]). -export([get/4]). --export([flush/1, flush/2, clear/2]). +-export([flush/1, flush/2, clear/2, create_value/4]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Public API. From a3bf43303fc5818171c2012b00c383475662df34 Mon Sep 17 00:00:00 2001 From: Hritik Soni Date: Mon, 20 Jul 2020 16:50:55 +0530 Subject: [PATCH 4/4] adding prometheus counters for cache hits and misses --- src/simple_cache.erl | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/simple_cache.erl b/src/simple_cache.erl index 5b5bb7e..766034b 100644 --- a/src/simple_cache.erl +++ b/src/simple_cache.erl @@ -29,7 +29,7 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Public API. -export([init/1]). --export([get/4]). +-export([get/4, get/5]). -export([flush/1, flush/2, clear/2, create_value/4]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -62,18 +62,41 @@ flush(CacheName) -> %% on a miss. -spec get(string(), infinity|pos_integer(), term(), function()) -> term(). get(CacheName, LifeTime, Key, FunResult) -> + get(CacheName, LifeTime, Key, FunResult, #{}). + +-spec get(string(), infinity|pos_integer(), term(), function(), map()) -> term(). +get(CacheName, LifeTime, Key, FunResult, Options) -> + CollectMetric = maps:get(collect_metric, Options, false), case ets:lookup(CacheName, Key) of [] -> % Not found, create it. + case CollectMetric of + true -> prometheus_summary:observe(simple_cache_hit_boolean, [CacheName], 0); + false -> ok + end, create_value(CacheName, LifeTime, Key, FunResult); - [{Key, R, _CreatedTime, infinity}] -> R; % Found, wont expire, return the value. + [{Key, R, _CreatedTime, infinity}] -> + case CollectMetric of + true -> prometheus_summary:observe(simple_cache_hit_boolean, [CacheName], 1); + false -> ok + end, + R; % Found, wont expire, return the value. [{Key, R, CreatedTime, LifeTime}] -> TimeElapsed = now_usecs() - CreatedTime, if TimeElapsed > (LifeTime * 1000) -> % expired? create a new value + case CollectMetric of + true -> prometheus_summary:observe(simple_cache_hit_boolean, [CacheName], 0); + false -> ok + end, create_value(CacheName, LifeTime, Key, FunResult); - true -> R % Not expired, return it. + true -> + case CollectMetric of + true -> prometheus_summary:observe(simple_cache_hit_boolean, [CacheName], 1); + false -> ok + end, + R % Not expired, return it. end end.