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)



249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
# File 'ext/tdb/tdb.c', line 249

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 = StringValuePtr(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



565
566
567
568
# File 'ext/tdb/tdb.c', line 565

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

#[]=(key, val) ⇒ Object



435
436
437
438
# File 'ext/tdb/tdb.c', line 435

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

#clearObject

clears out the database



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

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

#closeObject



295
296
297
298
299
300
301
302
303
304
305
# File 'ext/tdb/tdb.c', line 295

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

	DATA_PTR(self) = NULL;

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

	return Qnil;
}

#closed?Boolean

Returns:

  • (Boolean)


307
308
309
310
311
312
# File 'ext/tdb/tdb.c', line 307

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

	return tdb ? Qfalse : Qtrue;
}

#delete(*args) ⇒ Object



570
571
572
573
574
575
576
577
578
# File 'ext/tdb/tdb.c', line 570

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



530
531
532
533
534
535
536
537
538
539
540
541
# File 'ext/tdb/tdb.c', line 530

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



378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
# File 'ext/tdb/tdb.c', line 378

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 my_tbr(nogvl_parse_record, &f);
}

#has_key?(key) ⇒ Boolean

Returns:

  • (Boolean)


472
473
474
475
476
477
478
479
480
# File 'ext/tdb/tdb.c', line 472

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

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

	return my_tbr(nogvl_exists, &e);
}

#include?(key) ⇒ Boolean

Returns:

  • (Boolean)


472
473
474
475
476
477
478
479
480
# File 'ext/tdb/tdb.c', line 472

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

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

	return my_tbr(nogvl_exists, &e);
}

#insert(key, val) ⇒ Object



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

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

#insert!(key, val) ⇒ Object



440
441
442
443
# File 'ext/tdb/tdb.c', line 440

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

#key?(key) ⇒ Boolean

Returns:

  • (Boolean)


472
473
474
475
476
477
478
479
480
# File 'ext/tdb/tdb.c', line 472

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

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

	return my_tbr(nogvl_exists, &e);
}

#lockallObject



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

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

	return Qtrue;
}

#lockall_markObject



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

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

#lockall_readObject



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

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

#lockall_unmarkObject



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

static VALUE lockall_unmark(VALUE self)
{
	struct tdb_context *tdb = db(self, 1);
	if ((int)my_tbr((rb_blocking_function_t *)tdb_lockall_unmark, tdb))
		my_raise(tdb);
	return Qtrue;
}

#member?(key) ⇒ Boolean

Returns:

  • (Boolean)


472
473
474
475
476
477
478
479
480
# File 'ext/tdb/tdb.c', line 472

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

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

	return my_tbr(nogvl_exists, &e);
}

#modify(key, val) ⇒ Object



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

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

#modify!(key, val) ⇒ Object



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

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

#nuke!(key) ⇒ Object



555
556
557
558
559
560
561
562
563
# File 'ext/tdb/tdb.c', line 555

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

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

	return my_tbr(nogvl_delete, &d);
}

#repackObject

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



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

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

#store(key, val) ⇒ Object



435
436
437
438
# File 'ext/tdb/tdb.c', line 435

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



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

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

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

#trylockall_readObject



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

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

#unlockallObject



602
603
604
605
606
607
608
# File 'ext/tdb/tdb.c', line 602

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

#unlockall_readObject



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

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