18
18
#define DEFAULT_LISTENHOST "0.0.0.0"
19
19
#define DEFAULT_LISTENPORT 5431
20
20
21
- Transaction transactions [ MAX_TRANSACTIONS ] ;
22
- int transactions_count ;
21
+ L2List active_transactions = { & active_transactions , & active_transactions } ;
22
+ L2List * free_transactions ;
23
23
24
24
// We reserve the local xids if they fit between (prev, next) range, and
25
25
// reserve something in (next, x) range otherwise, moving 'next' after 'x'.
@@ -50,6 +50,14 @@ static void free_client_userdata(client_userdata_t *cd) {
50
50
free (cd );
51
51
}
52
52
53
+ inline static void free_transaction (Transaction * t )
54
+ {
55
+ l2_list_unlink (& t -> elem );
56
+ t -> elem .next = free_transactions ;
57
+ free_transactions = & t -> elem ;
58
+ }
59
+
60
+
53
61
static int next_client_id = 0 ;
54
62
static void onconnect (client_t client ) {
55
63
client_userdata_t * cd = create_client_userdata (next_client_id ++ );
@@ -103,18 +111,15 @@ static void ondisconnect(client_t client) {
103
111
debug ("[%d] disconnected\n" , CLIENT_ID (client ));
104
112
105
113
if (CLIENT_XID (client ) != INVALID_XID ) {
106
- int i ;
114
+ Transaction * t ;
107
115
108
116
// need to abort the transaction this client is participating in
109
- for (i = transactions_count - 1 ; i >= 0 ; i -- ) {
110
- Transaction * t = transactions + i ;
111
-
117
+ for (t = (Transaction * )active_transactions .next ; t != (Transaction * )& active_transactions ; t = (Transaction * )t -> elem .next )
118
+ {
112
119
if (t -> xid == CLIENT_XID (client )) {
113
120
if (clog_write (clg , t -> xid , NEGATIVE )) {
114
121
notify_listeners (t , NEGATIVE );
115
-
116
- * t = transactions [transactions_count - 1 ];
117
- transactions_count -- ;
122
+ free_transaction (t );
118
123
} else {
119
124
shout (
120
125
"[%d] DISCONNECT: transaction %u"
@@ -126,7 +131,7 @@ static void ondisconnect(client_t client) {
126
131
}
127
132
}
128
133
129
- if (i < 0 ) {
134
+ if (t == ( Transaction * ) & active_transactions ) {
130
135
shout (
131
136
"[%d] DISCONNECT: transaction %u not found O_o\n" ,
132
137
CLIENT_ID (client ), CLIENT_XID (client )
@@ -176,13 +181,13 @@ static xid_t max(xid_t a, xid_t b) {
176
181
}
177
182
178
183
static void gen_snapshot (Snapshot * s ) {
184
+ Transaction * t ;
179
185
s -> times_sent = 0 ;
180
186
s -> nactive = 0 ;
181
187
s -> xmin = MAX_XID ;
182
188
s -> xmax = MIN_XID ;
183
- int i ;
184
- for (i = 0 ; i < transactions_count ; i ++ ) {
185
- Transaction * t = transactions + i ;
189
+ for (t = (Transaction * )active_transactions .next ; t != (Transaction * )& active_transactions ; t = (Transaction * )t -> elem .next )
190
+ {
186
191
if (t -> xid < s -> xmin ) {
187
192
s -> xmin = t -> xid ;
188
193
}
@@ -241,11 +246,10 @@ static void onreserve(client_t client, int argc, xid_t *argv) {
241
246
}
242
247
243
248
static xid_t get_global_xmin () {
244
- int i , j ;
249
+ int j ;
245
250
xid_t xmin = next_gxid ;
246
251
Transaction * t ;
247
- for (i = 0 ; i < transactions_count ; i ++ ) {
248
- t = transactions + i ;
252
+ for (t = (Transaction * )active_transactions .next ; t != (Transaction * )& active_transactions ; t = (Transaction * )t -> elem .next ) {
249
253
j = t -> snapshots_count > MAX_SNAPSHOTS_PER_TRANS ? MAX_SNAPSHOTS_PER_TRANS : t -> snapshots_count ;
250
254
while (-- j >= 0 ) {
251
255
Snapshot * s = transaction_snapshot (t , j );
@@ -259,12 +263,7 @@ static xid_t get_global_xmin() {
259
263
}
260
264
261
265
static void onbegin (client_t client , int argc , xid_t * argv ) {
262
- CHECK (
263
- transactions_count < MAX_TRANSACTIONS ,
264
- client ,
265
- "BEGIN: transaction limit hit"
266
- );
267
-
266
+ Transaction * t ;
268
267
CHECK (
269
268
argc == 1 ,
270
269
client ,
@@ -277,8 +276,14 @@ static void onbegin(client_t client, int argc, xid_t *argv) {
277
276
"BEGIN: already participating in another transaction"
278
277
);
279
278
280
- Transaction * t = transactions + transactions_count ;
281
- transaction_clear (t );
279
+ t = (Transaction * )free_transactions ;
280
+ if (t == NULL ) {
281
+ t = (Transaction * )malloc (sizeof (Transaction ));
282
+ } else {
283
+ free_transactions = t -> elem .next ;
284
+ }
285
+
286
+ transaction_clear (t );
282
287
283
288
prev_gxid = t -> xid = next_gxid ++ ;
284
289
t -> snapshots_count = 0 ;
@@ -299,8 +304,6 @@ static void onbegin(client_t client, int argc, xid_t *argv) {
299
304
300
305
xid_t gxmin = get_global_xmin ();
301
306
302
- transactions_count ++ ;
303
-
304
307
gen_snapshot (transaction_next_snapshot (t ));
305
308
// will wrap around if exceeded max snapshots
306
309
Snapshot * snap = transaction_latest_snapshot (t );
@@ -318,10 +321,9 @@ static void onbegin(client_t client, int argc, xid_t *argv) {
318
321
}
319
322
320
323
static Transaction * find_transaction (xid_t xid ) {
321
- int i ;
322
324
Transaction * t ;
323
- for ( i = 0 ; i < transactions_count ; i ++ ) {
324
- t = transactions + i ;
325
+
326
+ for ( t = ( Transaction * ) active_transactions . next ; t != ( Transaction * ) & active_transactions ; t = ( Transaction * ) t -> elem . next ) {
325
327
if (t -> xid == xid ) {
326
328
return t ;
327
329
}
@@ -393,9 +395,7 @@ static void onvote(client_t client, int argc, xid_t *argv, int vote) {
393
395
);
394
396
395
397
notify_listeners (t , NEGATIVE );
396
-
397
- * t = transactions [transactions_count - 1 ];
398
- transactions_count -- ;
398
+ free_transaction (t );
399
399
client_message_shortcut (client , RES_TRANSACTION_ABORTED );
400
400
return ;
401
401
case DOUBT :
@@ -418,9 +418,7 @@ static void onvote(client_t client, int argc, xid_t *argv, int vote) {
418
418
);
419
419
420
420
notify_listeners (t , POSITIVE );
421
-
422
- * t = transactions [transactions_count - 1 ];
423
- transactions_count -- ;
421
+ free_transaction (t );
424
422
client_message_shortcut (client , RES_TRANSACTION_COMMITTED );
425
423
return ;
426
424
}
@@ -734,7 +732,6 @@ int main(int argc, char **argv) {
734
732
735
733
prev_gxid = MIN_XID ;
736
734
next_gxid = MIN_XID ;
737
- transactions_count = 0 ;
738
735
739
736
server_t server = server_init (
740
737
listenhost , listenport ,
0 commit comments