%%
%% %CopyrightBegin%
%%
%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
%%
%% %CopyrightEnd%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% File : bench_trans.hrl
%%% Author : Hakan Mattsson <[email protected]>
%%% Purpose : Implement the transactions in Canadian database benchmark (LMC/UU-01:025)
%%% Created : 21 Jun 2001 by Hakan Mattsson <[email protected]>
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-module(bench_trans).
-author('[email protected]').
-include("bench.hrl").
-export([
update_current_location/5,
read_current_location/2,
read_session_details/4,
create_session_to_server/6,
delete_session_from_server/5,
number_to_suffix/1,
number_to_key/2
]).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% The transactions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% -------------------------------------------------------------------
%% T1
%% -------------------------------------------------------------------
update_current_location(Wlock, SubscrId, Location, ChangedBy, ChangedTime) ->
Suffix = number_to_suffix(SubscrId),
[Subscr] = mnesia:read({subscriber, Suffix}, SubscrId, Wlock),
Subscr2 = Subscr#subscriber{location = Location,
changed_by = ChangedBy,
changed_time = ChangedTime},
mnesia:write(subscriber, Subscr2, Wlock),
{do_commit, false, [ok]}.
%% -------------------------------------------------------------------
%% T2
%% -------------------------------------------------------------------
read_current_location(_Wlock, SubscrId) ->
Suffix = number_to_suffix(SubscrId),
[Subscr] = mnesia:read({subscriber, Suffix}, SubscrId, read),
Name = Subscr#subscriber.subscriber_name,
Location = Subscr#subscriber.location,
ChangedBy = Subscr#subscriber.changed_by,
ChangedTime = Subscr#subscriber.changed_time,
{do_commit, false, [Name, Location, ChangedBy, ChangedTime]}.
%% -------------------------------------------------------------------
%% T3
%% -------------------------------------------------------------------
read_session_details(Wlock, SubscrId, ServerBit, ServerId) ->
Suffix = number_to_suffix(SubscrId),
[Subscr] = mnesia:read({subscriber, Suffix}, SubscrId, read),
%%[Group] = mnesia:read(group, Subscr#subscriber.group_id, read),
[Group] = mnesia:dirty_read(group, Subscr#subscriber.group_id),
IsAllowed = ((Group#group.allow_read band ServerBit) == ServerBit),
IsActive = ((Subscr#subscriber.active_sessions band ServerBit) == ServerBit),
ExecuteBranch = (IsAllowed and IsActive),
case ExecuteBranch of
true ->
SessionKey = {SubscrId, ServerId},
[Session] = mnesia:read({session, Suffix}, SessionKey, read),
ServerKey = {ServerId, Suffix},
[Server] = mnesia:read({server, Suffix}, ServerKey, Wlock),
Server2 = Server#server{no_of_read = Server#server.no_of_read + 1},
mnesia:write(server, Server2, Wlock),
{do_commit, ExecuteBranch, [Session#session.session_details]};
false ->
{do_commit, ExecuteBranch, []}
end.
%% -------------------------------------------------------------------
%% T4
%% -------------------------------------------------------------------
create_session_to_server(Wlock, SubscrId, ServerBit, ServerId, Details, DoRollback) ->
Suffix = number_to_suffix(SubscrId),
[Subscr] = mnesia:read({subscriber, Suffix}, SubscrId, Wlock),
%%[Group] = mnesia:read(group, Subscr#subscriber.group_id, read),
[Group] = mnesia:dirty_read(group, Subscr#subscriber.group_id),
IsAllowed = ((Group#group.allow_insert band ServerBit) == ServerBit),
IsInactive = ((Subscr#subscriber.active_sessions band ServerBit) == 0),
ExecuteBranch = (IsAllowed and IsInactive),
case ExecuteBranch of
true ->
SessionKey = {SubscrId, ServerId},
Session = #session{session_key = SessionKey,
session_details = Details,
suffix = Suffix},
mnesia:write(session, Session, Wlock),
Active = (Subscr#subscriber.active_sessions bor ServerBit),
Subscr2 = Subscr#subscriber{active_sessions = Active},
mnesia:write(subscriber, Subscr2, Wlock),
ServerKey = {ServerId, Suffix},
[Server] = mnesia:read({server, Suffix}, ServerKey, Wlock),
Server2 = Server#server{no_of_insert = Server#server.no_of_insert + 1},
mnesia:write(server, Server2, Wlock);
false ->
ignore
end,
case DoRollback of
true ->
mnesia:abort({do_rollback, ExecuteBranch, []});
false ->
{do_commit, ExecuteBranch, []}
end.
%% -------------------------------------------------------------------
%% T5
%% -------------------------------------------------------------------
delete_session_from_server(Wlock, SubscrId, ServerBit, ServerId, DoRollback) ->
Suffix = number_to_suffix(SubscrId),
[Subscr] = mnesia:read({subscriber, Suffix}, SubscrId, Wlock),
%%[Group] = mnesia:read(group, Subscr#subscriber.group_id, read),
[Group] = mnesia:dirty_read(group, Subscr#subscriber.group_id),
IsAllowed = ((Group#group.allow_delete band ServerBit) == ServerBit),
IsActive = ((Subscr#subscriber.active_sessions band ServerBit) == ServerBit),
ExecuteBranch = (IsAllowed and IsActive),
case ExecuteBranch of
true ->
SessionKey = {SubscrId, ServerId},
mnesia:delete({session, Suffix}, SessionKey, Wlock),
Active = (Subscr#subscriber.active_sessions bxor ServerBit),
Subscr2 = Subscr#subscriber{active_sessions = Active},
mnesia:write(subscriber, Subscr2, Wlock),
ServerKey = {ServerId, Suffix},
[Server] = mnesia:read({server, Suffix}, ServerKey, Wlock),
Server2 = Server#server{no_of_delete = Server#server.no_of_delete + 1},
mnesia:write(server, Server2, Wlock);
false ->
ignore
end,
case DoRollback of
true ->
mnesia:abort({do_rollback, ExecuteBranch, []});
false ->
{do_commit, ExecuteBranch, []}
end.
number_to_suffix(SubscrId) when is_integer(SubscrId) ->
SubscrId rem 100;
number_to_suffix(<<_:8/binary, TimesTen:8/integer, TimesOne:8/integer>>) ->
((TimesTen - $0) * 10) + (TimesOne - $0).
number_to_key(Id, C) when is_integer(Id) ->
case C#config.use_binary_subscriber_key of
true ->
list_to_binary(string:right(integer_to_list(Id), 10, $0));
false ->
Id
end.