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