@@ -24,11 +24,20 @@ static xid_t get_global_xmin();
24
24
L2List active_transactions = {& active_transactions , & active_transactions };
25
25
L2List * free_transactions ;
26
26
27
+ Transaction * transaction_hash [MAX_TRANSACTIONS ];
28
+
27
29
// We reserve the local xids if they fit between (prev, next) range, and
28
30
// reserve something in (next, x) range otherwise, moving 'next' after 'x'.
29
31
xid_t prev_gxid , next_gxid ;
30
32
xid_t global_xmin = INVALID_XID ;
31
33
34
+ static Transaction * find_transaction (xid_t xid ) {
35
+ Transaction * t ;
36
+ for (t = transaction_hash [xid % MAX_TRANSACTIONS ]; t != NULL && t -> xid != xid ; t = t -> collision );
37
+ return t ;
38
+
39
+ }
40
+
32
41
typedef struct client_userdata_t {
33
42
int id ;
34
43
int snapshots_sent ;
@@ -55,6 +64,9 @@ static void free_client_userdata(client_userdata_t *cd) {
55
64
}
56
65
57
66
inline static void free_transaction (Transaction * t ) {
67
+ Transaction * * tpp ;
68
+ for (tpp = & transaction_hash [t -> xid % MAX_TRANSACTIONS ]; * tpp != t ; tpp = & (* tpp )-> collision );
69
+ * tpp = t -> collision ;
58
70
l2_list_unlink (& t -> elem );
59
71
t -> elem .next = free_transactions ;
60
72
free_transactions = & t -> elem ;
@@ -117,26 +129,19 @@ static void ondisconnect(client_t client) {
117
129
debug ("[%d] disconnected\n" , CLIENT_ID (client ));
118
130
119
131
if (CLIENT_XID (client ) != INVALID_XID ) {
120
- Transaction * t ;
121
-
122
- // need to abort the transaction this client is participating in
123
- for (t = (Transaction * )active_transactions .next ; t != (Transaction * )& active_transactions ; t = (Transaction * )t -> elem .next ) {
124
- if (t -> xid == CLIENT_XID (client )) {
125
- if (clog_write (clg , t -> xid , NEGATIVE )) {
126
- notify_listeners (t , NEGATIVE );
127
- free_transaction (t );
128
- } else {
129
- shout (
130
- "[%d] DISCONNECT: transaction %u"
131
- " failed to abort O_o\n" ,
132
- CLIENT_ID (client ), t -> xid
132
+ Transaction * t = find_transaction (CLIENT_XID (client ));
133
+ if (t != NULL ) {
134
+ if (clog_write (clg , t -> xid , NEGATIVE )) {
135
+ notify_listeners (t , NEGATIVE );
136
+ free_transaction (t );
137
+ } else {
138
+ shout (
139
+ "[%d] DISCONNECT: transaction %u"
140
+ " failed to abort O_o\n" ,
141
+ CLIENT_ID (client ), t -> xid
133
142
);
134
- }
135
- break ;
136
- }
137
- }
138
-
139
- if (t == (Transaction * )& active_transactions ) {
143
+ }
144
+ } else {
140
145
shout (
141
146
"[%d] DISCONNECT: transaction %u not found O_o\n" ,
142
147
CLIENT_ID (client ), CLIENT_XID (client )
@@ -283,6 +288,8 @@ static void onbegin(client_t client, int argc, xid_t *argv) {
283
288
}
284
289
transaction_clear (t );
285
290
l2_list_link (& active_transactions , & t -> elem );
291
+ t -> collision = transaction_hash [t -> xid % MAX_TRANSACTIONS ];
292
+ transaction_hash [t -> xid % MAX_TRANSACTIONS ] = t ;
286
293
287
294
prev_gxid = t -> xid = next_gxid ++ ;
288
295
t -> snapshots_count = 0 ;
@@ -320,16 +327,6 @@ static void onbegin(client_t client, int argc, xid_t *argv) {
320
327
} client_message_finish (client );
321
328
}
322
329
323
- static Transaction * find_transaction (xid_t xid ) {
324
- Transaction * t ;
325
-
326
- for (t = (Transaction * )active_transactions .next ; t != (Transaction * )& active_transactions ; t = (Transaction * )t -> elem .next ) {
327
- if (t -> xid == xid ) {
328
- return t ;
329
- }
330
- }
331
- return NULL ;
332
- }
333
330
334
331
static bool queue_for_transaction_finish (client_t client , xid_t xid , char cmd ) {
335
332
assert ((cmd >= 'a' ) && (cmd <= 'z' ));
@@ -695,7 +692,7 @@ int main(int argc, char **argv) {
695
692
initGraph (& graph );
696
693
697
694
int opt ;
698
- while ((opt = getopt (argc , argv , "hd:a:p:l:k:m: " )) != -1 ) {
695
+ while ((opt = getopt (argc , argv , "hd:a:p:l:k:" )) != -1 ) {
699
696
switch (opt ) {
700
697
case 'd' :
701
698
datadir = optarg ;
0 commit comments