<commit_before>% @copyright 2009-2012 Zuse Institute Berlin,
%            2009 onScale solutions GmbH

%   Licensed under the Apache License, Version 2.0 (the "License");
%   you may not use this file except in compliance with the License.
%   You may obtain a copy of the License at
%
%       http://www.apache.org/licenses/LICENSE-2.0
%
%   Unless required by applicable law or agreed to in writing, software
%   distributed under the License is distributed on an "AS IS" BASIS,
%   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%   See the License for the specific language governing permissions and
%   limitations under the License.

%% @author <NAME> <<EMAIL>>
%% @author <NAME> <<EMAIL>>
%% @doc    API for transactions on replicated DHT items.
%% @version $Id$
-module(rdht_tx).
-author('<EMAIL>').
-author('<EMAIL>').
-vsn('$Id$').

%-define(TRACE(X,Y), io:format(X,Y)).
-define(TRACE(X,Y), ok).

-export([req_list/3]).
-export([check_config/0]).
-export([encode_value/1, decode_value/1]).

%% export to silence dialyzer
-export([decode_result/1]).

-include("scalaris.hrl").
-include("client_types.hrl").

-ifdef(with_export_type_support).
-export_type([req_id/0]).
-endif.

-type req_id() :: uid:global_uid().
-type request_on_key() :: api_tx:request_on_key().
-type results() :: [ api_tx:result() ].

%% @doc Perform several requests inside a transaction.
-spec req_list(tx_tlog:tlog(), [api_tx:request()], EnDecode::boolean()) -> {tx_tlog:tlog(), results()}.
req_list([], [{commit}], _EnDecode) -> {[], [{ok}]};
req_list(TLog, ReqList, EnDecode) ->
    %% PRE: TLog is sorted by key, implicitly given, as
    %%      we only generate sorted TLogs.
    ?TRACE("rdht_tx:req_list(~p, ~p, ~p)~n", [TLog, ReqList, EnDecode]),

    %% (0) Check TLog? Consts performance, may save some requests

    %% (1) Ensure commit is only at end of req_list (otherwise abort),
    %% (2) encode write values to ?DB:value format
    %% (3) drop {commit} request at end &and remember whether to
    %%     commit or not
    {ReqList1, OKorAbort, FoundCommitAtEnd} =
        rl_chk_and_encode(ReqList, [], ok),

    case OKorAbort of
        abort -> tlog_and_results_to_abort(TLog, ReqList);
        ok ->
            TLog2 = upd_tlog_via_rdht(TLog, ReqList1),

            %% perform all requests based on TLog to compute result
            %% entries
            {NewClientTLog, Results} = do_reqs_on_tlog(TLog2, ReqList1, EnDecode),

            %% do commit (if requested) and append the commit result
            %% to result list
            case FoundCommitAtEnd of
                true ->
                    CommitRes = commit(NewClientTLog),
                    {tx_tlog:empty(), Results ++ [CommitRes]};
                false ->
                    {NewClientTLog, Results}
            end
    end.

%% @doc Check whether commit is only at end (OKorAbort).
%%      Encode all values of write requests.
%%      Cut commit at end and inform caller via boolean (CommitAtEnd).
-spec rl_chk_and_encode(
        InTodo::[api_tx:request()], Acc::[api_tx:request()], ok|abort)
                       -> {Acc::[request_on_key()], ok|abort, CommitAtEnd::boolean()}.
rl_chk_and_encode([], Acc, OKorAbort) ->
    {lists:reverse(Acc), OKorAbort, false};
rl_chk_and_encode([{commit}], Acc, OKorAbort) ->
    {lists:reverse(Acc), OKorAbort, true};
rl_chk_and_encode([Req | RL], Acc, OKorAbort) ->
    case Req of
        {write, Key, Value} ->
            rl_chk_and_encode(RL, [{write, Key, Value} | Acc],
                              OKorAbort);
        {commit} = Commit ->
            log:log(info, "Commit not at end of a req_list. Deciding abort."),
            rl_chk_and_encode(RL, [Commit | Acc], abort);
        Op ->
            rl_chk_and_encode(RL, [Op | Acc], OKorAbort)
    end.

%% @doc Fill all fields with {fail, abort} information.
-spec tlog_and_results_to_abort(tx_tlog:tlog(), [api_tx:request()]) ->
                                       {tx_tlog:tlog(), results()}.
tlog_and_results_to_abort(TLog, ReqList) ->
    NewTLog = lists:foldl(fun(Req, AccTLog) ->
                                  case Req of
                                      {commit} -> AccTLog;
                                      _ ->
                                          tx_tlog:add_or_update_status_by_key(
                                            AccTLog,
                                            req_get_key(Req),
                                            {fail, abort})
                                  end end, TLog, ReqList),
    {NewTLog, [ case element(1, X) of
                    read -> {fail, not_found};
                    write -> {ok};
                    add_del_on_list -> {ok};
                    add_on_nr -> {ok};
                    test_and_set -> {ok};
                    commit -> {fail, abort, []}
                end || X <- ReqList ]}.
<commit_msg>- don't re-create the write-tuple in rdht_tx:rl_chk_and_encode/3<commit_after>% @copyright 2009-2012 Zuse Institute Berlin,
%            2009 onScale solutions GmbH

%   Licensed under the Apache License, Version 2.0 (the "License");
%   you may not use this file except in compliance with the License.
%   You may obtain a copy of the License at
%
%       http://www.apache.org/licenses/LICENSE-2.0
%
%   Unless required by applicable law or agreed to in writing, software
%   distributed under the License is distributed on an "AS IS" BASIS,
%   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%   See the License for the specific language governing permissions and
%   limitations under the License.

%% @author <NAME> <<EMAIL>>
%% @author <NAME> <<EMAIL>>
%% @doc    API for transactions on replicated DHT items.
%% @version $Id$
-module(rdht_tx).
-author('<EMAIL>').
-author('<EMAIL>').
-vsn('$Id$').

%-define(TRACE(X,Y), io:format(X,Y)).
-define(TRACE(X,Y), ok).

-export([req_list/3]).
-export([check_config/0]).
-export([encode_value/1, decode_value/1]).

%% export to silence dialyzer
-export([decode_result/1]).

-include("scalaris.hrl").
-include("client_types.hrl").

-ifdef(with_export_type_support).
-export_type([req_id/0]).
-endif.

-type req_id() :: uid:global_uid().
-type request_on_key() :: api_tx:request_on_key().
-type results() :: [ api_tx:result() ].

%% @doc Perform several requests inside a transaction.
-spec req_list(tx_tlog:tlog(), [api_tx:request()], EnDecode::boolean()) -> {tx_tlog:tlog(), results()}.
req_list([], [{commit}], _EnDecode) -> {[], [{ok}]};
req_list(TLog, ReqList, EnDecode) ->
    %% PRE: TLog is sorted by key, implicitly given, as
    %%      we only generate sorted TLogs.
    ?TRACE("rdht_tx:req_list(~p, ~p, ~p)~n", [TLog, ReqList, EnDecode]),

    %% (0) Check TLog? Consts performance, may save some requests

    %% (1) Ensure commit is only at end of req_list (otherwise abort),
    %% (2) encode write values to ?DB:value format
    %% (3) drop {commit} request at end &and remember whether to
    %%     commit or not
    {ReqList1, OKorAbort, FoundCommitAtEnd} =
        rl_chk_and_encode(ReqList, [], ok),

    case OKorAbort of
        abort -> tlog_and_results_to_abort(TLog, ReqList);
        ok ->
            TLog2 = upd_tlog_via_rdht(TLog, ReqList1),

            %% perform all requests based on TLog to compute result
            %% entries
            {NewClientTLog, Results} = do_reqs_on_tlog(TLog2, ReqList1, EnDecode),

            %% do commit (if requested) and append the commit result
            %% to result list
            case FoundCommitAtEnd of
                true ->
                    CommitRes = commit(NewClientTLog),
                    {tx_tlog:empty(), Results ++ [CommitRes]};
                false ->
                    {NewClientTLog, Results}
            end
    end.

%% @doc Check whether commit is only at end (OKorAbort).
%%      Encode all values of write requests.
%%      Cut commit at end and inform caller via boolean (CommitAtEnd).
-spec rl_chk_and_encode(
        InTodo::[api_tx:request()], Acc::[api_tx:request()], ok|abort)
                       -> {Acc::[request_on_key()], ok|abort, CommitAtEnd::boolean()}.
rl_chk_and_encode([], Acc, OKorAbort) ->
    {lists:reverse(Acc), OKorAbort, false};
rl_chk_and_encode([{commit}], Acc, OKorAbort) ->
    {lists:reverse(Acc), OKorAbort, true};
rl_chk_and_encode([Req | RL], Acc, OKorAbort) ->
    case Req of
        {write, _Key, _Value} = Write ->
            rl_chk_and_encode(RL, [Write | Acc], OKorAbort);
        {commit} = Commit ->
            log:log(info, "Commit not at end of a req_list. Deciding abort."),
            rl_chk_and_encode(RL, [Commit | Acc], abort);
        Op ->
            rl_chk_and_encode(RL, [Op | Acc], OKorAbort)
    end.

%% @doc Fill all fields with {fail, abort} information.
-spec tlog_and_results_to_abort(tx_tlog:tlog(), [api_tx:request()]) ->
                                       {tx_tlog:tlog(), results()}.
tlog_and_results_to_abort(TLog, ReqList) ->
    NewTLog = lists:foldl(fun(Req, AccTLog) ->
                                  case Req of
                                      {commit} -> AccTLog;
                                      _ ->
                                          tx_tlog:add_or_update_status_by_key(
                                            AccTLog,
                                            req_get_key(Req),
                                            {fail, abort})
                                  end end, TLog, ReqList),
    {NewTLog, [ case element(1, X) of
                    read -> {fail, not_found};
                    write -> {ok};
                    add_del_on_list -> {ok};
                    add_on_nr -> {ok};
                    test_and_set -> {ok};
                    commit -> {fail, abort, []}
                end || X <- ReqList ]}.

{'fraction_non_alphanumeric': 0.13177979037346088, 'fraction_numerical': 0.006614429632644754, 'mean_word_length': 2.153031761308951, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 69, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 28, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '898688', 'n_tokens_mistral': 3113, 'n_tokens_neox': 3042, 'n_words': 821}