_site/cover/mcd_meta_flags.COVER.html

1 %% Copyright (c) 2022 Peter Morgan <peter.james.morgan@gmail.com>
2 %%
3 %% Licensed under the Apache License, Version 2.0 (the "License");
4 %% you may not use this file except in compliance with the License.
5 %% You may obtain a copy of the License at
6 %%
7 %% http://www.apache.org/licenses/LICENSE-2.0
8 %%
9 %% Unless required by applicable law or agreed to in writing, software
10 %% distributed under the License is distributed on an "AS IS" BASIS,
11 %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 %% See the License for the specific language governing permissions and
13 %% limitations under the License.
14
15
16 -module(mcd_meta_flags).
17
18
19 -export([as_map/2]).
20 -export([decode/1]).
21 -export([encode/1]).
22 -export_type([flag/0]).
23
24
25 -type flag() :: base64
26 | cas
27 | {cas_expected, mcd:uint32()}
28 | flags
29 | {flags, mcd:uint32()}
30 | hit
31 | invalidate
32 | key_as_token
33 | last_accessed
34 | {mode, binary()}
35 | {vivify, mcd:uint32()}
36 | {opaque, binary()}
37 | noreply
38 | {remaining, mcd:uint32()}
39 | size
40 | ttl
41 | {ttl, mcd:uint32()}
42 | {set_ttl, mcd:uint32()}
43 | stale
44 | dont_bump_lru
45 | value
46 | already_winning
47 | won.
48
49
50 -spec decode(binary()) -> [flag()].
51
52
53 decode(<<>>) ->
54 37 [];
55
56 decode(Encoded) ->
57 100 lists:map(
58 fun demarshal/1,
59 string:split(
60 string:trim(Encoded),
61 whitespace(),
62 all)).
63
64
65 -spec encode([flag()]) -> iolist().
66
67 encode(Decoded) ->
68 93 lists:join(
69 " ",
70 lists:map(fun marshal/1, Decoded)).
71
72
73 whitespace() ->
74 100 " ".
75
76
77 7 demarshal(<<"C", Token/bytes>>) -> ?FUNCTION_NAME(cas_expected, Token);
78 4 demarshal(<<"D", Token/bytes>>) -> ?FUNCTION_NAME(delta, Token);
79 3 demarshal(<<"F", Token/bytes>>) -> ?FUNCTION_NAME(flags, Token);
80 3 demarshal(<<"I">>) -> invalidate;
81 5 demarshal(<<"J", Token/bytes>>) -> ?FUNCTION_NAME(initial, Token);
82 12 demarshal(<<"M", Token/bytes>>) -> {mode, Token};
83 10 demarshal(<<"N", Token/bytes>>) -> ?FUNCTION_NAME(vivify, Token);
84 5 demarshal(<<"O", Token/bytes>>) -> {opaque, Token};
85 1 demarshal(<<"R", Token/bytes>>) -> ?FUNCTION_NAME(remaining, Token);
86 19 demarshal(<<"T", Token/bytes>>) -> ?FUNCTION_NAME(set_ttl, Token);
87
:-(
demarshal(<<"W">>) -> won;
88
:-(
demarshal(<<"X">>) -> stale;
89
:-(
demarshal(<<"Z">>) -> already_winning;
90 3 demarshal(<<"b">>) -> base64;
91 7 demarshal(<<"c">>) -> cas;
92 6 demarshal(<<"c", Token/bytes>>) -> ?FUNCTION_NAME(cas, Token);
93 3 demarshal(<<"f">>) -> flags;
94 1 demarshal(<<"h">>) -> hit;
95 5 demarshal(<<"h", Token/bytes>>) -> ?FUNCTION_NAME(hit, Token);
96 4 demarshal(<<"k", Token/bytes>>) -> {key, Token};
97
:-(
demarshal(<<"k">>) -> key;
98 1 demarshal(<<"l">>) -> last_accessed;
99 3 demarshal(<<"l", Token/bytes>>) -> ?FUNCTION_NAME(last_accessed, Token);
100 2 demarshal(<<"q">>) -> noreply;
101 12 demarshal(<<"s">>) -> size;
102 10 demarshal(<<"s", Size/bytes>>) -> {size, binary_to_integer(Size)};
103 14 demarshal(<<"t">>) -> ttl;
104 7 demarshal(<<"t", Token/bytes>>) -> ?FUNCTION_NAME(ttl, Token);
105 1 demarshal(<<"u">>) -> dont_bump_lru;
106 26 demarshal(<<"v">>) -> value.
107
108
109 70 demarshal(Flag, Token) -> {Flag, binary_to_integer(Token)}.
110
111
112 2 marshal(base64) -> "b";
113 7 marshal(cas) -> "c";
114 1 marshal(dont_bump_lru) -> "u";
115 2 marshal(flags) -> "f";
116 1 marshal(hit) -> "h";
117 2 marshal(invalidate) -> "I";
118 1 marshal(key) -> "k";
119 1 marshal(last_accessed) -> "l";
120 2 marshal(noreply) -> "q";
121 11 marshal(size) -> "s";
122 11 marshal(ttl) -> "t";
123 23 marshal(value) -> "v";
124 6 marshal({cas, Token}) -> ?FUNCTION_NAME("c", Token);
125 7 marshal({cas_expected, Token}) -> ?FUNCTION_NAME("C", Token);
126 4 marshal({delta, Token}) -> ?FUNCTION_NAME("D", Token);
127 2 marshal({flags, Token}) -> ?FUNCTION_NAME("F", Token);
128 5 marshal({hit, Token}) -> ?FUNCTION_NAME("h", Token);
129 5 marshal({initial, Token}) -> ?FUNCTION_NAME("J", Token);
130 2 marshal({key, Token}) -> ["k", Token];
131 3 marshal({last_accessed, Token}) -> ?FUNCTION_NAME("l", Token);
132 11 marshal({mode, Token}) -> ["M", Token];
133 4 marshal({opaque, Token}) -> ["O", Token];
134 1 marshal({remaining, Token}) -> ?FUNCTION_NAME("R", Token);
135 10 marshal({size, Token}) -> ?FUNCTION_NAME("s", Token);
136 16 marshal({set_ttl, Token}) -> ?FUNCTION_NAME("T", Token);
137 7 marshal({ttl, Token}) -> ?FUNCTION_NAME("t", Token);
138 10 marshal({vivify, Token}) -> ?FUNCTION_NAME("N", Token).
139
140
141 76 marshal(Flag, Token) -> [Flag, integer_to_binary(Token)].
142
143
144 as_map(Meta, Flags) ->
145 48 maps:merge(
146 defaults(Meta),
147 lists:foldl(
148 fold(Meta),
149 #{},
150 Flags)).
151
152
153 defaults(set) ->
154 19 #{mode => set};
155
156 defaults(arithmetic) ->
157 16 #{initial => 0, delta => 1, mode => increment};
158
159 defaults(_) ->
160 13 #{}.
161
162
163 fold(set) ->
164 19 fun
165 ({mode = K, <<"E">>}, A) ->
166 1 A#{K => add};
167
168 ({mode = K, <<"A">>}, A) ->
169 1 A#{K => append};
170
171 ({mode = K, <<"P">>}, A) ->
172 1 A#{K => prepend};
173
174 ({mode = K, <<"R">>}, A) ->
175 2 A#{K => replace};
176
177 ({mode = K, <<"S">>}, A) ->
178 1 A#{K => set};
179
180 ({mode, _} = Arg, _) ->
181 1 error(badarg, [Arg]);
182
183 ({K, V}, A) ->
184 13 A#{K => V};
185
186 (K, A) ->
187 2 A#{K => true}
188 end;
189
190 fold(arithmetic) ->
191 16 fun
192 ({mode = K, V}, A) when V == <<"I">>; V == <<"+">> ->
193
:-(
A#{K => increment};
194
195 ({mode = K, V}, A) when V == <<"D">>; V == <<"-">> ->
196 2 A#{K => decrement};
197
198 ({K, V}, A) ->
199 21 A#{K => V};
200
201 (K, A) ->
202 19 A#{K => true}
203 end;
204
205 fold(_) ->
206 13 fun
207 ({K, V}, A) ->
208 4 A#{K => V};
209
210 (K, A) ->
211 21 A#{K => true}
212 end.
Line Hits Source