@@ -24,11 +24,20 @@ static xid_t get_global_xmin();
2424L2List active_transactions = {& active_transactions , & active_transactions };
2525L2List * free_transactions ;
2626
27+ Transaction * transaction_hash [MAX_TRANSACTIONS ];
28+
2729// We reserve the local xids if they fit between (prev, next) range, and
2830// reserve something in (next, x) range otherwise, moving 'next' after 'x'.
2931xid_t prev_gxid , next_gxid ;
3032xid_t global_xmin = INVALID_XID ;
3133
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+
3241typedef struct client_userdata_t {
3342 int id ;
3443 int snapshots_sent ;
@@ -55,6 +64,9 @@ static void free_client_userdata(client_userdata_t *cd) {
5564}
5665
5766inline 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 ;
5870 l2_list_unlink (& t -> elem );
5971 t -> elem .next = free_transactions ;
6072 free_transactions = & t -> elem ;
@@ -117,26 +129,19 @@ static void ondisconnect(client_t client) {
117129 debug ("[%d] disconnected\n" , CLIENT_ID (client ));
118130
119131 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
133142 );
134- }
135- break ;
136- }
137- }
138-
139- if (t == (Transaction * )& active_transactions ) {
143+ }
144+ } else {
140145 shout (
141146 "[%d] DISCONNECT: transaction %u not found O_o\n" ,
142147 CLIENT_ID (client ), CLIENT_XID (client )
@@ -283,6 +288,8 @@ static void onbegin(client_t client, int argc, xid_t *argv) {
283288 }
284289 transaction_clear (t );
285290 l2_list_link (& active_transactions , & t -> elem );
291+ t -> collision = transaction_hash [t -> xid % MAX_TRANSACTIONS ];
292+ transaction_hash [t -> xid % MAX_TRANSACTIONS ] = t ;
286293
287294 prev_gxid = t -> xid = next_gxid ++ ;
288295 t -> snapshots_count = 0 ;
@@ -320,16 +327,6 @@ static void onbegin(client_t client, int argc, xid_t *argv) {
320327 } client_message_finish (client );
321328}
322329
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- }
333330
334331static bool queue_for_transaction_finish (client_t client , xid_t xid , char cmd ) {
335332 assert ((cmd >= 'a' ) && (cmd <= 'z' ));
@@ -695,7 +692,7 @@ int main(int argc, char **argv) {
695692 initGraph (& graph );
696693
697694 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 ) {
699696 switch (opt ) {
700697 case 'd' :
701698 datadir = optarg ;
0 commit comments