82 lines
2.1 KiB
Erlang
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.
|