fewd/src/fd_sfc_cache.erl

82 lines
2.1 KiB
Erlang

% @doc
% cache data management
-module(fd_sfc_cache).
-export_type([
cache/0
]).
-export([
query/2,
new/0, new/1
]).
-include("$zx_include/zx_logger.hrl").
-type cache() :: #{HttpPath :: binary() := Entry :: fd_sfc_entry:entry()}.
-spec query(HttpPath, Cache) -> Result
when HttpPath :: binary(),
Cache :: cache(),
Result :: {found, Entry}
| not_found,
Entry :: fd_sfc_entry:entry().
query(HttpPath, Cache) ->
case maps:find(HttpPath, Cache) of
{ok, Entry} -> {found, Entry};
error -> not_found
end.
-spec new() -> cache().
new() -> #{}.
-spec new(BasePath) -> cache()
when BasePath :: file:filename().
% @doc
% if you give a file path it just takes the parent dir
%
% recursively crawls through file tree and picks
%
% IO errors will be logged but will result in cache misses
new(BasePath) ->
case filelib:is_file(BasePath) of
true -> new2(BasePath);
false ->
tell("~p:new(~p): no such file or directory, returning empty cache", [?MODULE, BasePath]),
#{}
end.
new2(BasePath) ->
BaseDir =
case filelib:is_dir(BasePath) of
true -> filename:absname(BasePath);
false -> filename:absname(filename:dirname(BasePath))
end,
BBaseDir = unicode:characters_to_binary(BaseDir),
HandlePath =
fun(AbsPath, AccCache) ->
BAbsPath = unicode:characters_to_binary(AbsPath),
HttpPath = remove_prefix(BBaseDir, BAbsPath),
NewCache =
case fd_sfc_entry:new(AbsPath) of
{found, Entry} -> maps:put(HttpPath, Entry, AccCache);
not_found -> AccCache
end,
NewCache
end,
filelib:fold_files(_dir = BaseDir,
_match = ".+",
_recursive = true,
_fun = HandlePath,
_init_acc = #{}).
remove_prefix(Prefix, From) ->
Size = byte_size(Prefix),
<<Prefix:Size/bytes, Rest/bytes>> = From,
Rest.