lmdb 0.6.7 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGES +9 -0
- data/ext/lmdb_ext/lmdb_ext.c +84 -64
- data/ext/lmdb_ext/lmdb_ext.h +6 -6
- data/lib/lmdb/database.rb +1 -2
- data/lib/lmdb/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c098384d91381d0f7c66a4794f88ea55c1c8a1e54d60480a75a379704407252d
|
|
4
|
+
data.tar.gz: 11c4e5b74f9b552ad9f89d5a189bf812340ab409b43b54361cb84f7d47dfd906
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: da3b52d345951ad527b67ce32998c749b17267b7b0d075f695e841d1b2a0891df4e0064e021e7db9ac21f41c0b81a4fb590ff88a98250675e15ad14baf185680
|
|
7
|
+
data.tar.gz: 12ae851f60db43dec61730f8497a06bf952e56242bff2e8fe64153a852c34582441556320cb1627fa65b7c29dfe417ba312c929d242511c0ab9c3888b12075b4
|
data/CHANGES
CHANGED
data/ext/lmdb_ext/lmdb_ext.c
CHANGED
|
@@ -285,69 +285,87 @@ static void stop_txn_begin(void *arg)
|
|
|
285
285
|
*/
|
|
286
286
|
|
|
287
287
|
static VALUE with_transaction(VALUE venv, VALUE(*fn)(VALUE), VALUE arg, int flags) {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
288
|
+
ENVIRONMENT(venv, environment);
|
|
289
|
+
|
|
290
|
+
MDB_txn* txn;
|
|
291
|
+
TxnArgs txn_args;
|
|
292
|
+
|
|
293
|
+
VALUE thread = rb_thread_current();
|
|
294
|
+
VALUE vparent = environment_active_txn(venv);
|
|
295
|
+
|
|
296
|
+
//
|
|
297
|
+
Transaction* tparent = NULL;
|
|
298
|
+
if (vparent && !NIL_P(vparent))
|
|
299
|
+
Data_Get_Struct(vparent, Transaction, tparent);
|
|
300
|
+
|
|
301
|
+
/*
|
|
302
|
+
* If the requested transaction is read-only and there is a parent
|
|
303
|
+
* transaction (whether read-only or not), we need to use the
|
|
304
|
+
* parent transaction.
|
|
305
|
+
*
|
|
306
|
+
* XXX except conceivably you could do a transaction (RO or RW)
|
|
307
|
+
* that spawns a thread that opens another transaction.
|
|
308
|
+
*
|
|
309
|
+
* note we do *NOT* re-begin the parent transaction, nor do we
|
|
310
|
+
* want to commit it
|
|
311
|
+
*
|
|
312
|
+
*/
|
|
313
|
+
|
|
314
|
+
if (tparent && flags & MDB_RDONLY) {
|
|
315
|
+
int exception;
|
|
316
|
+
VALUE ret = rb_protect(fn, NIL_P(arg) ? vparent : arg, &exception);
|
|
317
|
+
if (exception) {
|
|
318
|
+
if (vparent == environment_active_txn(venv))
|
|
319
|
+
transaction_abort(vparent);
|
|
320
|
+
rb_jump_tag(exception);
|
|
321
|
+
}
|
|
322
|
+
return ret;
|
|
323
|
+
}
|
|
324
|
+
else {
|
|
300
325
|
// XXX note this is a cursed goto loop that could almost certainly
|
|
301
326
|
// be rewritten as a do-while
|
|
302
|
-
|
|
327
|
+
retry:
|
|
303
328
|
txn = NULL;
|
|
304
329
|
|
|
305
330
|
txn_args.env = environment->env;
|
|
306
|
-
txn_args.parent = active_txn(venv);
|
|
331
|
+
txn_args.parent = active_txn(venv); // this returns an MDB_txn
|
|
307
332
|
txn_args.flags = flags;
|
|
308
333
|
txn_args.htxn = &txn;
|
|
309
334
|
txn_args.result = 0;
|
|
310
335
|
txn_args.stop = 0;
|
|
311
336
|
|
|
312
|
-
if (flags & MDB_RDONLY)
|
|
313
|
-
|
|
314
|
-
// this is a no-op: put the same actual transaction in a
|
|
315
|
-
// different wrapper struct
|
|
316
|
-
txn = txn_args.parent;
|
|
317
|
-
else
|
|
318
|
-
// this will return an error if the parent transaction is
|
|
319
|
-
// read-write, so we don't need to handle the case explicitly
|
|
320
|
-
call_txn_begin(&txn_args);
|
|
321
|
-
}
|
|
337
|
+
if (flags & MDB_RDONLY)
|
|
338
|
+
call_txn_begin(&txn_args);
|
|
322
339
|
else {
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
340
|
+
if (tparent) {
|
|
341
|
+
// first we have to determine if we're on the same thread
|
|
342
|
+
// as the parent, which in turn must be the same as the
|
|
343
|
+
// environment's registry for which thread has the
|
|
344
|
+
// read-write transaction
|
|
345
|
+
if (thread != tparent->thread ||
|
|
346
|
+
thread != environment->rw_txn_thread)
|
|
347
|
+
rb_raise(cError,
|
|
348
|
+
"Attempt to nest transaction on a different thread");
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// try to acquire the new transaction
|
|
352
|
+
CALL_WITHOUT_GVL(call_txn_begin, &txn_args, stop_txn_begin, &txn_args);
|
|
353
|
+
|
|
354
|
+
if (txn_args.stop || !txn) {
|
|
355
|
+
// !txn is when rb_thread_call_without_gvl2
|
|
356
|
+
// returns before calling txn_begin
|
|
357
|
+
if (txn) {
|
|
358
|
+
mdb_txn_abort(txn);
|
|
359
|
+
txn_args.result = 0;
|
|
332
360
|
}
|
|
333
361
|
|
|
334
|
-
|
|
362
|
+
//rb_warn("got here lol");
|
|
363
|
+
rb_thread_check_ints();
|
|
364
|
+
goto retry; // in what cases do we get here?
|
|
365
|
+
}
|
|
335
366
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
// returns before calling txn_begin
|
|
339
|
-
if (txn) {
|
|
340
|
-
mdb_txn_abort(txn);
|
|
341
|
-
txn_args.result = 0;
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
//rb_warn("got here lol");
|
|
345
|
-
rb_thread_check_ints();
|
|
346
|
-
goto retry; // in what cases do we get here?
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
// set the thread
|
|
350
|
-
environment->rw_txn_thread = thread;
|
|
367
|
+
// set the thread
|
|
368
|
+
environment->rw_txn_thread = thread;
|
|
351
369
|
}
|
|
352
370
|
|
|
353
371
|
// this will raise unless result is zero
|
|
@@ -373,14 +391,15 @@ static VALUE with_transaction(VALUE venv, VALUE(*fn)(VALUE), VALUE arg, int flag
|
|
|
373
391
|
VALUE ret = rb_protect(fn, NIL_P(arg) ? vtxn : arg, &exception);
|
|
374
392
|
|
|
375
393
|
if (exception) {
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
394
|
+
// rb_warn("lol got exception");
|
|
395
|
+
if (vtxn == environment_active_txn(venv))
|
|
396
|
+
transaction_abort(vtxn);
|
|
397
|
+
rb_jump_tag(exception);
|
|
380
398
|
}
|
|
381
399
|
if (vtxn == environment_active_txn(venv))
|
|
382
|
-
|
|
400
|
+
transaction_commit(vtxn);
|
|
383
401
|
return ret;
|
|
402
|
+
}
|
|
384
403
|
}
|
|
385
404
|
|
|
386
405
|
static void environment_check(Environment* environment) {
|
|
@@ -773,23 +792,24 @@ static void environment_set_active_txn(VALUE self, VALUE thread, VALUE txn) {
|
|
|
773
792
|
}
|
|
774
793
|
}
|
|
775
794
|
|
|
795
|
+
static MDB_txn* extract_txn(VALUE vtxn) {
|
|
796
|
+
if (NIL_P(vtxn)) return NULL;
|
|
797
|
+
TRANSACTION(vtxn, transaction);
|
|
798
|
+
if (!transaction->txn) rb_raise(cError, "Transaction is already terminated");
|
|
799
|
+
if (transaction->thread != rb_thread_current())
|
|
800
|
+
rb_raise(cError, "Transaction is from another thread");
|
|
801
|
+
return transaction->txn;
|
|
802
|
+
}
|
|
776
803
|
|
|
777
804
|
static MDB_txn* active_txn(VALUE self) {
|
|
778
805
|
VALUE vtxn = environment_active_txn(self);
|
|
779
|
-
|
|
780
|
-
return 0;
|
|
781
|
-
TRANSACTION(vtxn, transaction);
|
|
782
|
-
if (!transaction->txn)
|
|
783
|
-
rb_raise(cError, "Transaction is already terminated");
|
|
784
|
-
if (transaction->thread != rb_thread_current())
|
|
785
|
-
rb_raise(cError, "Wrong thread");
|
|
786
|
-
return transaction->txn;
|
|
806
|
+
return extract_txn(vtxn);
|
|
787
807
|
}
|
|
788
808
|
|
|
789
809
|
static MDB_txn* need_txn(VALUE self) {
|
|
790
810
|
MDB_txn* txn = active_txn(self);
|
|
791
|
-
|
|
792
|
-
|
|
811
|
+
|
|
812
|
+
if (!txn) rb_raise(cError, "No active transaction");
|
|
793
813
|
return txn;
|
|
794
814
|
}
|
|
795
815
|
|
data/ext/lmdb_ext/lmdb_ext.h
CHANGED
|
@@ -104,12 +104,12 @@ typedef struct {
|
|
|
104
104
|
} EnvironmentOptions;
|
|
105
105
|
|
|
106
106
|
typedef struct {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
107
|
+
MDB_env *env;
|
|
108
|
+
MDB_txn *parent;
|
|
109
|
+
unsigned int flags;
|
|
110
|
+
MDB_txn **htxn; // not sure why this is a pointer to a pointer
|
|
111
|
+
int result;
|
|
112
|
+
int stop;
|
|
113
113
|
} TxnArgs;
|
|
114
114
|
|
|
115
115
|
static VALUE cEnvironment, cDatabase, cTransaction, cCursor, cError;
|
data/lib/lmdb/database.rb
CHANGED
|
@@ -145,8 +145,7 @@ module LMDB
|
|
|
145
145
|
# @return [void]
|
|
146
146
|
#
|
|
147
147
|
def put?(key, value = nil, **options)
|
|
148
|
-
flags = {}
|
|
149
|
-
flags[dupsort? ? :nodupdata : :nooverwrite] = true
|
|
148
|
+
flags = { (dupsort? ? :nodupdata : :nooverwrite) => true }
|
|
150
149
|
begin
|
|
151
150
|
put key, value, **options.merge(flags)
|
|
152
151
|
rescue LMDB::Error::KEYEXIST
|
data/lib/lmdb/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lmdb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Daniel Mendler
|
|
8
8
|
- Dorian Taylor
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-11-
|
|
11
|
+
date: 2025-11-23 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rake
|