/home/runner/work/mcd/mcd/_site/ct/ct_run.ct_mcd@fv-az773-648.2023-11-24_16.44.07/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 33 [];
55
56 decode(Encoded) ->
57 60 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 60 lists:join(
69 " ",
70 lists:map(fun marshal/1, Decoded)).
71
72
73 whitespace() ->
74 60 " ".
75
76
77 6 demarshal(<<"C", Token/bytes>>) -> ?FUNCTION_NAME(cas_expected, Token);
78 4 demarshal(<<"D", Token/bytes>>) -> ?FUNCTION_NAME(delta, Token);
79
:-(
demarshal(<<"F", Token/bytes>>) -> ?FUNCTION_NAME(flags, Token);
80
:-(
demarshal(<<"I">>) -> invalidate;
81 5 demarshal(<<"J", Token/bytes>>) -> ?FUNCTION_NAME(initial, Token);
82 9 demarshal(<<"M", Token/bytes>>) -> {mode, Token};
83 9 demarshal(<<"N", Token/bytes>>) -> ?FUNCTION_NAME(vivify, Token);
84 2 demarshal(<<"O", Token/bytes>>) -> {opaque, Token};
85
:-(
demarshal(<<"R", Token/bytes>>) -> ?FUNCTION_NAME(remaining, Token);
86 12 demarshal(<<"T", Token/bytes>>) -> ?FUNCTION_NAME(set_ttl, Token);
87
:-(
demarshal(<<"W">>) -> won;
88
:-(
demarshal(<<"X">>) -> stale;
89
:-(
demarshal(<<"Z">>) -> already_winning;
90
:-(
demarshal(<<"b">>) -> base64;
91 6 demarshal(<<"c">>) -> cas;
92 6 demarshal(<<"c", Token/bytes>>) -> ?FUNCTION_NAME(cas, Token);
93
:-(
demarshal(<<"f">>) -> flags;
94
:-(
demarshal(<<"h">>) -> hit;
95
:-(
demarshal(<<"h", Token/bytes>>) -> ?FUNCTION_NAME(hit, Token);
96 1 demarshal(<<"k", Token/bytes>>) -> {key, Token};
97
:-(
demarshal(<<"k">>) -> key;
98
:-(
demarshal(<<"l">>) -> last_accessed;
99
:-(
demarshal(<<"l", Token/bytes>>) -> ?FUNCTION_NAME(last_accessed, Token);
100 1 demarshal(<<"q">>) -> noreply;
101 9 demarshal(<<"s">>) -> size;
102 9 demarshal(<<"s", Size/bytes>>) -> {size, binary_to_integer(Size)};
103 7 demarshal(<<"t">>) -> ttl;
104 7 demarshal(<<"t", Token/bytes>>) -> ?FUNCTION_NAME(ttl, Token);
105
:-(
demarshal(<<"u">>) -> dont_bump_lru;
106 19 demarshal(<<"v">>) -> value.
107
108
109 49 demarshal(Flag, Token) -> {Flag, binary_to_integer(Token)}.
110
111
112
:-(
marshal(base64) -> "b";
113 6 marshal(cas) -> "c";
114
:-(
marshal(dont_bump_lru) -> "u";
115
:-(
marshal(flags) -> "f";
116
:-(
marshal(hit) -> "h";
117
:-(
marshal(invalidate) -> "I";
118 1 marshal(key) -> "k";
119
:-(
marshal(last_accessed) -> "l";
120 1 marshal(noreply) -> "q";
121 9 marshal(size) -> "s";
122 7 marshal(ttl) -> "t";
123 19 marshal(value) -> "v";
124 6 marshal({cas, Token}) -> ?FUNCTION_NAME("c", Token);
125 6 marshal({cas_expected, Token}) -> ?FUNCTION_NAME("C", Token);
126 4 marshal({delta, Token}) -> ?FUNCTION_NAME("D", Token);
127
:-(
marshal({flags, Token}) -> ?FUNCTION_NAME("F", Token);
128
:-(
marshal({hit, Token}) -> ?FUNCTION_NAME("h", Token);
129 5 marshal({initial, Token}) -> ?FUNCTION_NAME("J", Token);
130
:-(
marshal({key, Token}) -> ["k", Token];
131
:-(
marshal({last_accessed, Token}) -> ?FUNCTION_NAME("l", Token);
132 9 marshal({mode, Token}) -> ["M", Token];
133 2 marshal({opaque, Token}) -> ["O", Token];
134
:-(
marshal({remaining, Token}) -> ?FUNCTION_NAME("R", Token);
135 9 marshal({size, Token}) -> ?FUNCTION_NAME("s", Token);
136 12 marshal({set_ttl, Token}) -> ?FUNCTION_NAME("T", Token);
137 7 marshal({ttl, Token}) -> ?FUNCTION_NAME("t", Token);
138 9 marshal({vivify, Token}) -> ?FUNCTION_NAME("N", Token).
139
140
141 58 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