Repository navigation
Expand file tree
/
Copy pathPseudoCode.java
More file actions
242 lines (203 loc) · 4.91 KB
/
Copy pathPseudoCode.java
File metadata and controls
242 lines (203 loc) · 4.91 KB
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
enum TransactionType {
Transaction1,
Transaction2,
Transaction3,
Transaction4,
Transaction5,
Transaction6,
Transaction7,
}
enum MessageType {
TwoPhaseLockPrepare,
TwoPhaseLockReady,
UserChain,
SystemChain,
}
Class Message {
MessageType mMessageType;
String mSqlCommand;
Message(MessageType aMessageType, String aSqlCommand){
mMessageType = aMessageType;
mSqlCommand = aSqlCommand;
}
}
Class Transaction {
int mChainId;
int mCurrentHop;
String mCoordinatorId;
HistoryTable mHistoryTable;
TransactionType mTransactionType;
List<Hop> mHop;
Transaction(TransactionType aTransactionType) {
mTransactionType = aTransactionType;
switch (mTransactionType) {
case TransactionType.Transaction1:
Hop hop1 = new Hop();
Hop hop2 = new Hop();
...
mHop.insert(hop1);
mHop.insert(hop2);
break;
...
default:
break;
}
}
function peek() {
return mHop.get(mCurrentHop);
}
function pop() {
mCurrentHop += 1;
}
function signCoordinator(String aServerSignature) {
this.mCoordinatorId = aServerSignature;
}
function getCoordinator() {
return mCoordinatorId;
}
function getCurrentHop() {
return mHop.get(mCurrentHop);
}
}
Class Hop {
boolean mCompleted;
String mMySqlInstructions;
String mServerSignature; // Not sure if we need this. Just to memorize which server completed the hop.
function markCompleted(String aServerSignature) {
mCompleted = true;
mServerSignature = aServerSignature;
}
}
Class HistoryTable {
}
Class TransactionQueue {
Queue mTransactionQueue;
}
Class Server() {
final String S_SERVER_SIGNATURE = "123456";
HistoryTable mHistoryTable;
TransactionQueue mTransactionQueue;
function provideInterface() {
/**
* ToDo:
* Interface to trigger function such as command line
* This function differs from server to server
*/
Transaction transaction = new Transaction(TransactionType);
processFirstHop(transaction);
forward(transaction);
}
function processFirstHop(Transaction aTransaction) {
aTransaction.signCoordinator(S_SERVER_SIGNATURE);
executeHop(aTransaction.peek());
aTransaction.pop();
}
function executeHop(Hop aHop) {
// ToDo: Complete hop job. This function differs from servers to servers, transactions to transactions, hop to hop.
hop.markCompleted(S_SERVER_SIGNATURE);
}
function listen() {
Message message = socket.listen();
switch (message.getType()) {
case MessageType.SystemChain:
// update local data
break;
}
}
function extractQueue() {
Transaction t = TransactionQueue.peek();
Hop hop = t.getCurrentHop();
if (executale(hop)) {
executeHop(hop);
}
forward(t);
}
function executable(Hop hop) {
// ToDo: check if executable
return true;
}
function forward(Transaction t) {
// Check which server to send the transaction
if (t.getCoordinator().equals(S_SERVER_SIGNATURE)) {
// This server is the coordinator
} else {
new Message = Message(MessageType.UserChain);
sendToCoordinator(t);
}
}
function createSystemChain(Hop aHop) {
String sqlCommand = ""; // some update command
Message message = new Message(MessageType.SystemChain, sqlCommand);
socket.send(message);
}
function main() {
new Thread(provideInterface);
new Thread(listen);
new Thread(extractQueue);
}
}
Maintain a transaction queue
Maintain a history tables list containing ids to history tables
LOOP{
Insert all user requests as transactions to the transaction_queue;
Check message from other programs;
If backward message{
If failed -> send message again;
If successful ->
Go to the history table of this completed hop;
Current_hop = Find the next hop in the history table;
Handle_hop();
}
Else if forward message{
Current_hop = hop to do in the forward message;
process this hop;
Send backward message with completion information;
}
Else{
current_transaction = transaction_queue.pop
If new transaction -> history_tables.append = create history tables for current_transaction
If new transaction -> Acquire_all_locks();
Lock failed -> append the transaction to queue
Lock success -> Loop through the hops{
Handle_hop();
If forward to other servers -> break the loop and append it to queue
}
}
}
Handle_hop:
check if this hop can be done in this node;
If can{
process this hop;
If it is the first hop, return to the user;
}
Else{
Forward the hop to the corresponding server with history table;
}
Acquire_all_locks:
For all hops in transactions
If transaction 1-6{
If read{
Check if lockBI;
If lockBI -> fail;
If not lockBI -> success;
}
If insert{
Check if lockBR;
If lockBR -> fail;
If not lockBR -> success;
}
}
If transaction 7{
If read{
Check if lockAI;
If lockAI -> fail;
If not lockAI -> success;
}
If insert{
Check if lockAR;
If lockAR -> fail;
If not lockAR -> success;
}
}
If any fail -> acquire lock failed;
If all success -> acquire lock success and acquire all the locks; (T1-6 as A, T7 as B, read as R, insert as I)