-
Notifications
You must be signed in to change notification settings - Fork 0
/
transaction_state.ml
88 lines (74 loc) · 2.44 KB
/
transaction_state.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
open Shop
module TnxMap = Map.Make(Int64)
type operation_state = {
pending_status_count: int;
current_status: bool;
operation: operation;
}
type query_state = {
pending_response_count: int;
current_response: relation_value list;
query: query;
}
type tnx_state =
| PendingOperation of operation_state
| PendingQuery of query_state
type state = tnx_state TnxMap.t
let empty = TnxMap.empty
let add_query state txn_id query subqueries =
let query_state = PendingQuery {
pending_response_count = List.length subqueries;
current_response = [];
query = query;
} in
TnxMap.add txn_id query_state state
let is_check = function
| Check _ -> true
| _ -> false
let count_check requests = List.length (List.filter is_check requests)
let add_operation state txn_id requests op =
let operation_state = PendingOperation {
pending_status_count = count_check requests;
current_status = true;
operation = op;
} in
TnxMap.add txn_id operation_state state
let add_partial_read state transaction_id response =
match TnxMap.find transaction_id state with
| PendingQuery query_state -> (
let current_response = response :: query_state.current_response in
let pending_count = query_state.pending_response_count - 1 in
if pending_count = 0
then
let state = TnxMap.remove transaction_id state in
(state, Some (Response (transaction_id, make_response query_state.query current_response)))
else
let query_state = PendingQuery {
query_state with
pending_response_count = pending_count;
current_response = current_response;
} in
let state = TnxMap.add transaction_id query_state state in
(state, None)
)
| _ -> (state, None)
| exception Not_found -> (state, None)
let add_partial_check state txn_id status =
match TnxMap.find txn_id state with
| PendingOperation operation_state -> (
let pending_count = operation_state.pending_status_count - 1 in
let status = operation_state.current_status && status in
if pending_count = 0 || (not status)
then
let state = TnxMap.remove txn_id state in
(state, Some (status, operation_state.operation))
else
let operation_state = PendingOperation {
operation_state with
pending_status_count = pending_count;
} in
let state = TnxMap.add txn_id operation_state state in
(state, None)
)
| _ -> (state, None)
| exception Not_found -> (state, None)