Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 44 additions & 35 deletions src/filezcache_entry_manager.erl
Original file line number Diff line number Diff line change
Expand Up @@ -539,22 +539,27 @@ scan_files(Dir, [F|Fs]) ->

%% @doc Delete an entry by key.
delete_key(Key, #state{ lru = LRU } = State) ->
{_, LRU1} = filezcache_lru:take(Key, LRU),
Delta = case ets:lookup(?FILE_ENTRY_TAB, Key) of
LRU2 = case filezcache_lru:take(Key, LRU) of
{_, LRU1} -> LRU1;
error -> LRU
end,
case ets:lookup(?FILE_ENTRY_TAB, Key) of
[] ->
0;
State#state{
lru = LRU2
};
[ #filezcache_entry{ filename = Filename, size = Size } ] ->
ok = delete_file(Key, Filename),
case Size of
Delta = case Size of
undefined -> 0;
_ -> Size
end
end,
State#state{
bytes = State#state.bytes - Delta,
lru = LRU1,
delete_count = State#state.delete_count + 1
}.
end,
State#state{
lru = LRU2,
bytes = State#state.bytes - Delta,
delete_count = State#state.delete_count + 1
}
end.

%% @doc Delete an entry and its associated cache file.
delete_file(Key, Filename) ->
Expand Down Expand Up @@ -599,32 +604,36 @@ do_gc(#state{ bytes = Bytes, lru = LRU } = State, N) ->
end.

drop_oldest_key(#state{ lru = LRU } = State) ->
{Key, _Value, LRU1} = filezcache_lru:pop(LRU),
case filezcache_store:lookup(Key) of
{ok, _Pid} ->
LRU2 = filezcache_lru:push(Key, State#state.tick, LRU1),
State#state{ lru = LRU2 };
{error, enoent} ->
case is_referred(Key, State) of
true ->
case filezcache_lru:pop(LRU) of
error ->
State;
{Key, _Value, LRU1} ->
case filezcache_store:lookup(Key) of
{ok, _Pid} ->
LRU2 = filezcache_lru:push(Key, State#state.tick, LRU1),
State#state{ lru = LRU2 };
false ->
Delta = case ets:lookup(?FILE_ENTRY_TAB, Key) of
[] ->
0;
[ #filezcache_entry{ filename = Filename, size = Size } ] ->
ok = delete_file(Key, Filename),
case Size of
undefined -> 0;
_ -> Size
end
end,
State#state{
bytes = State#state.bytes - Delta,
lru = LRU1,
evict_count = State#state.evict_count + 1
}
{error, enoent} ->
case is_referred(Key, State) of
true ->
LRU2 = filezcache_lru:push(Key, State#state.tick, LRU1),
State#state{ lru = LRU2 };
false ->
Delta = case ets:lookup(?FILE_ENTRY_TAB, Key) of
[] ->
0;
[ #filezcache_entry{ filename = Filename, size = Size } ] ->
ok = delete_file(Key, Filename),
case Size of
undefined -> 0;
_ -> Size
end
end,
State#state{
bytes = State#state.bytes - Delta,
lru = LRU1,
evict_count = State#state.evict_count + 1
}
end
end
end.

Expand Down
41 changes: 24 additions & 17 deletions src/filezcache_lru.erl
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ push(Key, Value, LRU) ->
%% @doc Pop element from head.
%%
%% Complexity: O(log(N))
-spec pop(lru()) -> {key(), value(), lru()}.
-spec pop(lru()) -> {key(), value(), lru()} | error.
pop(LRU) ->
pop_oldest(LRU).

Expand Down Expand Up @@ -175,28 +175,35 @@ update_key(Key, Value, LRU) ->
last = NewIndex
}.

-spec pop_oldest(lru()) -> {key(), value(), lru()}.
-spec pop_oldest(lru()) -> {key(), value(), lru()} | error.
pop_oldest(LRU) ->
#lru{current_size = CurrentSize, usage = Usage, lookup_cache = LookupCache, last = Last } = LRU,
{_, OldestKey, NewUsage} = gb_trees:take_smallest(Usage),
{{_, OldestValue}, NewLookupCache} = maps:take(OldestKey, LookupCache),
NewLast =
case CurrentSize of
1 -> 0;
_ -> Last
end,
NewLRU = LRU#lru{current_size = CurrentSize - 1,
lookup_cache = NewLookupCache,
usage = NewUsage,
last = NewLast
},
{OldestKey, OldestValue, NewLRU}.
case gb_trees:is_empty(Usage) of
true ->
error;
false ->
{_, OldestKey, NewUsage} = gb_trees:take_smallest(Usage),
{{_, OldestValue}, NewLookupCache} = maps:take(OldestKey, LookupCache),
NewLast =
case CurrentSize of
1 -> 0;
_ -> Last
end,
NewLRU = LRU#lru{current_size = CurrentSize - 1,
lookup_cache = NewLookupCache,
usage = NewUsage,
last = NewLast
},
{OldestKey, OldestValue, NewLRU}
end.

-spec apply_limits(lru()) -> lru().
apply_limits(#lru{max_size = unlimited} = LRU) ->
LRU;
apply_limits(#lru{current_size = CS, max_size = MaxSize} = LRU) when CS =< MaxSize ->
LRU;
apply_limits(LRU) ->
{_, _, NewLRU} = pop_oldest(LRU),
apply_limits(NewLRU).
case pop_oldest(LRU) of
error -> LRU;
{_, _, NewLRU} -> apply_limits(NewLRU)
end.
5 changes: 5 additions & 0 deletions test/filezcache_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ end_per_testcase(_TestCase, _Config) ->

all() ->
[
remove_unknown_key_test,
cache_binary_test,
cache_delete_test,
cache_tmpfile_test,
Expand All @@ -37,6 +38,10 @@ all() ->
%% TEST CASES
%%--------------------------------------------------------------------

remove_unknown_key_test(_Config) ->
ok = filezcache:delete(unknown_key),
ok.

cache_binary_test(_Config) ->
#{
insert_count := 0,
Expand Down