/home/runner/work/mcd/mcd/_site/ct/ct_run.ct_mcd@fv-az773-648.2023-11-24_16.44.07/mcd_emulator_binary.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_emulator_binary).
17
18
19 -export([recv/1]).
20 -include_lib("kernel/include/logger.hrl").
21 -include_lib("stdlib/include/ms_transform.hrl").
22 -include("mcd_emulator.hrl").
23
24
25 recv(#{message := #{extra := #{expiration := Expiry,
26 flags := Flags},
27 header := #{magic := request,
28 cas := 0,
29 opcode := set} = Header,
30 key := Key,
31 value := Value},
32 data := #{table := Table}}) ->
33
34 4 case mcd_config:maximum(value_size) of
35 Maximum when byte_size(Value) > Maximum ->
36
:-(
ets:delete(Table, Key),
37
:-(
{continue,
38 {encode, #{header => response_header(Header, server_error)}}};
39
40 _SmallerThanMaximum ->
41 4 ets:insert(Table,
42 #entry{key = Key,
43 flags = Flags,
44 expiry = Expiry,
45 data = Value}),
46 4 {continue,
47 [{encode,
48 #{header => response_header(Header, no_error)}},
49 {expire, #{key => Key, seconds => Expiry}}]}
50 end;
51
52 recv(#{message := #{header := #{magic := request,
53 cas := 0,
54 opcode := get} = Header,
55 key := Key},
56 data := #{table := Table}}) ->
57 6 case ets:lookup(Table, Key) of
58 [#entry{data = Data, flags = Flags}] ->
59 3 {continue,
60 {encode,
61 #{header => response_header(Header, no_error),
62 extra => #{flags => Flags},
63 value => Data}}};
64
65 [] ->
66 3 {continue,
67 {encode,
68 #{header => response_header(Header, key_not_found)}}}
69 end;
70
71 recv(#{message := #{header := #{magic := request,
72 cas := 0,
73 opcode := delete} = Header,
74 key := Key},
75 data := #{table := Table}}) ->
76 2 ets:delete(Table, Key),
77 2 {continue, {encode, #{header => response_header(Header, no_error)}}};
78
79 recv(#{message := #{header := #{magic := request,
80 opcode := no_op} = Header}}) ->
81 1 {continue, {encode, #{header => response_header(Header)}}};
82
83 recv(#{message := #{header := #{magic := request,
84 opcode := stat} = Header}}) ->
85
:-(
{continue,
86 lists:foldl(
87 fun
88 ({Key, Value}, A) when is_integer(Value) ->
89
:-(
[{encode, #{header => response_header(Header),
90 key => atom_to_binary(Key),
91 value => integer_to_binary(Value)}} | A]
92 end,
93 [{encode, #{header => response_header(Header)}}],
94 mcd_stat:all())};
95
96 recv(#{message := #{header := #{magic := request,
97 opcode := flush} = Header},
98 data := #{table := Table}}) ->
99 2 ets:delete_all_objects(Table),
100 2 {continue, {encode, #{header => response_header(Header)}}};
101
102 recv(#{message := #{header := #{magic := request,
103 opcode := version} = Header}}) ->
104
:-(
{continue,
105 {encode,
106 #{header => response_header(Header), value => <<"1.3.1">>}}}.
107
108
109 response_header(RequestHeader) ->
110 3 ?FUNCTION_NAME(RequestHeader, no_error).
111
112
113 response_header(RequestHeader, Status) ->
114 15 maps:without(
115 [vbucket_id],
116 RequestHeader#{magic := response,
117 status => Status}).
Line Hits Source