Class: TDB

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
ext/tdb/tdb.c,
lib/tdb.rb,
ext/tdb/tdb.c

Overview

<code>

tdb = TDB.new("/path/to/file", flags => IO::RDWR|IO::CREAT)
tdb.store("HELLO", "world")
tdb.fetch("HELLO")  -> "world"
tdb.delete("HELLO") -> "world"

</code>

Defined Under Namespace

Modules: MT Classes: ERR

Constant Summary collapse

HASHES =

Available hash functions, the key is the name of the hash and the value is a pointer for internal for usage.

hashes
DEFAULT =

just a readability place holder

UINT2NUM(TDB_DEFAULT)
CLEAR_IF_FIRST =

clear database if we are the only one with it open

UINT2NUM(TDB_CLEAR_IF_FIRST)
INTERNAL =

don’t store on disk, use in-memory database

UINT2NUM(TDB_INTERNAL)
NOLOCK =

don’t do any locking

UINT2NUM(TDB_NOLOCK)
NOMMAP =

don’t use mmap

UINT2NUM(TDB_NOMMAP)
CONVERT =

convert endian (internal use)

UINT2NUM(TDB_CONVERT)
BIGENDIAN =

header is big-endian (internal use)

UINT2NUM(TDB_BIGENDIAN)
NOSYNC =

don’t use synchronous transactions

UINT2NUM(TDB_NOSYNC)
SEQNUM =

maintain a sequence number

UINT2NUM(TDB_SEQNUM)
VOLATILE =

Activate the per-hashchain freelist, default 5

UINT2NUM(TDB_VOLATILE)
ALLOW_NESTING =

Allow transactions to nest

UINT2NUM(TDB_ALLOW_NESTING)
DISALLOW_NESTING =

Disallow transactions to nest

UINT2NUM(TDB_DISALLOW_NESTING)
INCOMPATIBLE_HASH =

Better hashing, but can’t be opened by tdb < 1.2.6.

UINT2NUM(TDB_INCOMPATIBLE_HASH)

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ Object

:call-seq:

TDB.new(“/path/to/file”) -> TDB TDB.new(“/path/to/file”, :hash_size => 666) -> TDB TDB.new(“/path/to/file”, :hash => :murmur2) -> TDB TDB.new(“/path/to/file”, :open_flags => IO::RDONLY) -> TDB TDB.new(“/path/to/file”, :tdb_flags => TDB::NOSYNC) -> TDB

Initializes a TDB context. It takes several options.

:hash_size - the number of buckets, this is the most important tuning parameter when creating large databases. This parameter only affects the creation of new databases.

:open_flags - a bit mask of IO flags passed directly to open(2), File.open-compatible flags are accepted.

:hash - any of the hashes described in Hash_Functions. This must remain the same for all clients.

:tdb_flags - a bitmask of any combination of TDB::CLEAR_IF_FIRST, TDB::INTERNAL, TDB::NOLOCK, TDB::NOMMAP, TDB::CONVERT, TDB::BIGENDIAN, TDB::NOSYNC, TDB::SEQNUM, TDB::VOLATILE, TDB::ALLOW_NESTING, TDB::DISALLOW_NESTING, TDB::INCOMPATIBLE_HASH

:mode - octal mode mask passed to open(2)



257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
# File 'ext/tdb/tdb.c', line 257

static VALUE init(int argc, VALUE *argv, VALUE self)
{
	struct tdb_context *tdb = db(self, 0);
	VALUE path, opts;
	struct open_args o;

	if (tdb)
		rb_raise(rb_eRuntimeError, "TDB already initialized");
	rb_scan_args(argc, argv, "11", &path, &opts);
	set_args(self, &o, opts);

	if (NIL_P(path))
		o.tdb_flags |= TDB_INTERNAL;
	else
		o.name = StringValueCStr(path);

	tdb = (struct tdb_context *)my_tbr(nogvl_open, &o);
	if (!tdb) {
		switch (errno) {
		case ENOMEM:
		case EMFILE:
		case ENFILE:
			rb_gc();
			tdb = (struct tdb_context *)my_tbr(nogvl_open, &o);
		}
		if (!tdb)
			rb_sys_fail("tdb_open_ex");
	}
	DATA_PTR(self) = tdb;

	return self;
}

Instance Method Details

#[](key) ⇒ Object



574
575
576
577
# File 'ext/tdb/tdb.c', line 574

static VALUE aref(VALUE self, VALUE key)
{
	return fetch(1, &key, self);
}

#[]=(key, val) ⇒ Object



444
445
446
447
# File 'ext/tdb/tdb.c', line 444

static VALUE store(VALUE self, VALUE key, VALUE val)
{
	return rbtdb_store(self, key, val, 0, 0);
}

#clearObject

clears out the database



667
668
669
670
671
672
673
# File 'ext/tdb/tdb.c', line 667

static VALUE clear(VALUE self)
{
	struct tdb_context *tdb = db(self, 1);
	if (my_tbr(tdb_wipe_all, tdb))
		my_raise(tdb);
	return self;
}

#closeObject



303
304
305
306
307
308
309
310
311
312
313
# File 'ext/tdb/tdb.c', line 303

static VALUE tdbclose(VALUE self)
{
	struct tdb_context *tdb = db(self, 1);

	DATA_PTR(self) = NULL;

	if ((long)my_tbr(nogvl_close, tdb) == -1)
		rb_sys_fail("tdb_close");

	return Qnil;
}

#closed?Boolean

Returns:

  • (Boolean)


315
316
317
318
319
320
# File 'ext/tdb/tdb.c', line 315

static VALUE closed(VALUE self)
{
	struct tdb_context *tdb = db(self, 0);

	return tdb ? Qfalse : Qtrue;
}

#delete(*args) ⇒ Object



579
580
581
582
583
584
585
586
587
# File 'ext/tdb/tdb.c', line 579

static VALUE delete(int argc, VALUE *argv, VALUE self)
{
	VALUE rc = fetch(argc, argv, self);

	if (! NIL_P(rc))
		if (nuke(self, argv[0]) == Qfalse)
			return Qnil;
	return rc;
}

#eachObject



539
540
541
542
543
544
545
546
547
548
549
550
# File 'ext/tdb/tdb.c', line 539

static VALUE each(VALUE self)
{
	struct traverse_args t;

	t.tdb = db(self, 1);
	t.state = 0;

	my_tbr(nogvl_traverse, &t);
	if (t.state)
		rb_jump_tag(t.state);
	return self;
}

#fetch(*args) ⇒ Object



386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
# File 'ext/tdb/tdb.c', line 386

static VALUE fetch(int argc, VALUE *argv, VALUE self)
{
	struct fetch_parse_args f;
	VALUE key;

	rb_scan_args(argc, argv, "11", &key, &f.value);
	if (NIL_P(f.value)) {
		f.value = rb_str_new(0, 0);
	} else {
		StringValue(f.value);
		rb_str_set_len(f.value, 0);
	}

	f.tdb = db(self, 1);
	TO_TDB_DATA(f.as.key, key);

	return (VALUE)my_tbr(nogvl_parse_record, &f);
}

#has_key?(key) ⇒ Boolean

Returns:

  • (Boolean)


481
482
483
484
485
486
487
488
489
# File 'ext/tdb/tdb.c', line 481

static VALUE has_key(VALUE self, VALUE key)
{
	struct exists_args e;

	e.tdb = db(self, 1);
	TO_TDB_DATA(e.key, key);

	return (VALUE)my_tbr(nogvl_exists, &e);
}

#include?(key) ⇒ Boolean

Returns:

  • (Boolean)


481
482
483
484
485
486
487
488
489
# File 'ext/tdb/tdb.c', line 481

static VALUE has_key(VALUE self, VALUE key)
{
	struct exists_args e;

	e.tdb = db(self, 1);
	TO_TDB_DATA(e.key, key);

	return (VALUE)my_tbr(nogvl_exists, &e);
}

#insert(key, val) ⇒ Object



454
455
456
457
# File 'ext/tdb/tdb.c', line 454

static VALUE insert(VALUE self, VALUE key, VALUE val)
{
	return rbtdb_store(self, key, val, TDB_INSERT, 1);
}

#insert!(key, val) ⇒ Object



449
450
451
452
# File 'ext/tdb/tdb.c', line 449

static VALUE insert_bang(VALUE self, VALUE key, VALUE val)
{
	return rbtdb_store(self, key, val, TDB_INSERT, 0);
}

#key?(key) ⇒ Boolean

Returns:

  • (Boolean)


481
482
483
484
485
486
487
488
489
# File 'ext/tdb/tdb.c', line 481

static VALUE has_key(VALUE self, VALUE key)
{
	struct exists_args e;

	e.tdb = db(self, 1);
	TO_TDB_DATA(e.key, key);

	return (VALUE)my_tbr(nogvl_exists, &e);
}

#lockallObject



589
590
591
592
593
594
595
596
# File 'ext/tdb/tdb.c', line 589

static VALUE lockall(VALUE self)
{
	struct tdb_context *tdb = db(self, 1);
	if (my_tbr(tdb_lockall, tdb))
		my_raise(tdb);

	return Qtrue;
}

#lockall_markObject



647
648
649
650
651
652
653
# File 'ext/tdb/tdb.c', line 647

static VALUE lockall_mark(VALUE self)
{
	struct tdb_context *tdb = db(self, 1);
	if (my_tbr(tdb_lockall_mark, tdb))
		my_raise(tdb);
	return Qtrue;
}

#lockall_readObject



619
620
621
622
623
624
625
# File 'ext/tdb/tdb.c', line 619

static VALUE lockall_read(VALUE self)
{
	struct tdb_context *tdb = db(self, 1);
	if (my_tbr(tdb_lockall_read, tdb))
		my_raise(tdb);
	return Qtrue;
}

#lockall_unmarkObject



655
656
657
658
659
660
661
662
# File 'ext/tdb/tdb.c', line 655

static VALUE lockall_unmark(VALUE self)
{
	struct tdb_context *tdb = db(self, 1);

	if (my_tbr(tdb_lockall_unmark, tdb))
		my_raise(tdb);
	return Qtrue;
}

#member?(key) ⇒ Boolean

Returns:

  • (Boolean)


481
482
483
484
485
486
487
488
489
# File 'ext/tdb/tdb.c', line 481

static VALUE has_key(VALUE self, VALUE key)
{
	struct exists_args e;

	e.tdb = db(self, 1);
	TO_TDB_DATA(e.key, key);

	return (VALUE)my_tbr(nogvl_exists, &e);
}

#modify(key, val) ⇒ Object



464
465
466
467
# File 'ext/tdb/tdb.c', line 464

static VALUE modify(VALUE self, VALUE key, VALUE val)
{
	return rbtdb_store(self, key, val, TDB_MODIFY, 1);
}

#modify!(key, val) ⇒ Object



459
460
461
462
# File 'ext/tdb/tdb.c', line 459

static VALUE modify_bang(VALUE self, VALUE key, VALUE val)
{
	return rbtdb_store(self, key, val, TDB_MODIFY, 0);
}

#nuke!(key) ⇒ Object



564
565
566
567
568
569
570
571
572
# File 'ext/tdb/tdb.c', line 564

static VALUE nuke(VALUE self, VALUE key)
{
	struct delete_args d;

	d.tdb = db(self, 1);
	TO_TDB_DATA(d.key, key);

	return (VALUE)my_tbr(nogvl_delete, &d);
}

#repackObject

repacks a database to reduce fragmentation, available with tdb 1.2.x+



677
678
679
680
681
682
683
# File 'ext/tdb/tdb.c', line 677

static VALUE repack(VALUE self)
{
	struct tdb_context *tdb = db(self, 1);
	if (my_tbr(tdb_repack, tdb))
		my_raise(tdb);
	return self;
}

#store(key, val) ⇒ Object



444
445
446
447
# File 'ext/tdb/tdb.c', line 444

static VALUE store(VALUE self, VALUE key, VALUE val)
{
	return rbtdb_store(self, key, val, 0, 0);
}

#threadsafe!Object

makes the current TDB object thread-safe (DANGEROUS) Do not use this method yet, it has problems



8
9
10
# File 'lib/tdb.rb', line 8

def threadsafe!
  extend MT
end

#threadsafe?Boolean

will return true when TDB::MT is included in TDB or the TDB object is extended by TDB

Returns:

  • (Boolean)


14
15
16
# File 'lib/tdb.rb', line 14

def threadsafe?
  false
end

#trylockallObject



598
599
600
601
602
603
604
605
606
607
608
609
# File 'ext/tdb/tdb.c', line 598

static VALUE trylockall(VALUE self)
{
	struct tdb_context *tdb = db(self, 1);
	void *fn = tdb_lockall_nonblock;

	if (my_tbr(fn, tdb)) {
		if (tdb_error(tdb) == TDB_ERR_LOCK)
			return Qfalse;
		my_raise(tdb);
	}
	return Qtrue;
}

#trylockall_readObject



627
628
629
630
631
632
633
634
635
636
637
# File 'ext/tdb/tdb.c', line 627

static VALUE trylockall_read(VALUE self)
{
	struct tdb_context *tdb = db(self, 1);
	void *fn = tdb_lockall_read_nonblock;
	if (my_tbr(fn, tdb)) {
		if (tdb_error(tdb) == TDB_ERR_LOCK)
			return Qfalse;
		my_raise(tdb);
	}
	return Qtrue;
}

#unlockallObject



611
612
613
614
615
616
617
# File 'ext/tdb/tdb.c', line 611

static VALUE unlockall(VALUE self)
{
	struct tdb_context *tdb = db(self, 1);
	if (my_tbr(tdb_unlockall, tdb))
		my_raise(tdb);
	return Qtrue;
}

#unlockall_readObject



639
640
641
642
643
644
645
# File 'ext/tdb/tdb.c', line 639

static VALUE unlockall_read(VALUE self)
{
	struct tdb_context *tdb = db(self, 1);
	if (my_tbr(tdb_unlockall_read, tdb))
		my_raise(tdb);
	return Qtrue;
}