Class: Isomorfeus::Hamster::Environment

Inherits:
Object
  • Object
show all
Defined in:
ext/isomorfeus_hamster_ext/isomorfeus_hamster.c

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.new(path, opts) {|env| ... } ⇒ Environment

Open an LMDB database environment. The database environment is the root object for all operations on a collection of databases. It has to be opened first, before individual databases can be opened or created in the environment. The database should be closed when it is no longer needed.

The options hash on this method includes all the flags listed in #flags as well as the options documented here.

Examples:

Open environment and pass options

env = LMDB.new "dbdir", :maxdbs => 30, :mapasync => true, :writemap => true

Pass environment to block

LMDB.new "dbdir" do |env|
  # ...
end

Parameters:

  • path (String)

    the path to the files containing the database

  • opts (Hash)

    options for the database environment

Options Hash (opts):

  • :mode (Number)

    The Posix permissions to set on created files.

  • :maxreaders (Number)

    The maximum number of concurrent threads that can be executing transactions at once. Default is 126.

  • :maxdbs (Number)

    The maximum number of named databases in the environment. Not needed if only one database is being used.

  • :mapsize (Number)

    The size of the memory map to be allocated for this environment, in bytes. The memory map size is the maximum total size of the database. The size should be a multiple of the OS page size. The default size is about 10MiB.

Yields:

  • (env)

    The block to be executed with the environment. The environment is closed afterwards.

Yield Parameters:

Returns:

See Also:



482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
# File 'ext/isomorfeus_hamster_ext/isomorfeus_hamster.c', line 482

static VALUE environment_new(int argc, VALUE *argv, VALUE klass) {
        VALUE path, option_hash;
        rb_scan_args(argc, argv, "1:", &path, &option_hash);

        EnvironmentOptions options = {
                .flags = MDB_NOTLS,
                .maxreaders = -1,
                .maxdbs = 128,
                .mapsize = 0,
                .mode = 0755,
        };
        if (!NIL_P(option_hash))
                rb_hash_foreach(option_hash, environment_options, (VALUE)&options);

        MDB_env* env;
        check(mdb_env_create(&env));

        Environment* environment;
        VALUE venv = Data_Make_Struct(cEnvironment, Environment, environment_mark, environment_free, environment);
        environment->env = env;
        environment->thread_txn_hash = rb_hash_new();
        environment->txn_thread_hash = rb_hash_new();

        if (options.maxreaders > 0)
                check(mdb_env_set_maxreaders(env, options.maxreaders));
        if (options.mapsize > 0)
                check(mdb_env_set_mapsize(env, options.mapsize));

        check(mdb_env_set_maxdbs(env, options.maxdbs <= 0 ? 1 : options.maxdbs));
        VALUE expanded_path = rb_file_expand_path(path, Qnil);
        check(mdb_env_open(env, StringValueCStr(expanded_path), options.flags, options.mode));

        if (rb_block_given_p())
                return rb_ensure(rb_yield, venv, environment_close, venv);

        return venv;
}

Instance Method Details

#active_txnTransaction

Returns the current active transaction on this thread in the environment.

Examples:

env.transaction do |t|
  active = env.active_txn
  # active should equal t
end

Returns:

  • (Transaction)

    the current active transaction on this thread in the environment.



624
625
626
627
# File 'ext/isomorfeus_hamster_ext/isomorfeus_hamster.c', line 624

static VALUE environment_active_txn(VALUE self) {
        ENVIRONMENT(self, environment);
        return rb_hash_aref(environment->thread_txn_hash, rb_thread_current());
}

#clear_flags(flags) ⇒ Object

Clear one or more flags in the environment. The available flags are defined in #flags.

Examples:

env.clear_flags :nosync, :writemap

Parameters:

  • flags (Array)

    Array of flag names (symbols) to clear

Returns:

  • nil

Raises:

  • (Error)

    if an invalid flag name is specified

See Also:



610
611
612
613
# File 'ext/isomorfeus_hamster_ext/isomorfeus_hamster.c', line 610

static VALUE environment_clear_flags(int argc, VALUE* argv, VALUE self) {
        environment_change_flags(argc, argv, self, 0);
        return Qnil;
}

#closeObject

Close an environment, completing all IOs and cleaning up database state if needed.

Examples:

env = LMDB.new('abc')
# ...various operations on the environment...
env.close


301
302
303
304
305
306
# File 'ext/isomorfeus_hamster_ext/isomorfeus_hamster.c', line 301

static VALUE environment_close(VALUE self) {
        ENVIRONMENT(self, environment);
        mdb_env_close(environment->env);
        environment->env = 0;
        return Qnil;
}

#copy(path) ⇒ Object

Create a copy (snapshot) of an environment. The copy can be used as a backup. The copy internally uses a read-only transaction to ensure that the copied data is serialized with respect to database updates.

Parameters:

  • path (String)

    The directory in which the copy will reside. This directory must already exist and be writable but must otherwise be empty.

Returns:

  • nil

Raises:

  • (Error)

    when there is an error creating the copy.



394
395
396
397
398
399
# File 'ext/isomorfeus_hamster_ext/isomorfeus_hamster.c', line 394

static VALUE environment_copy(VALUE self, VALUE path) {
        ENVIRONMENT(self, environment);
        VALUE expanded_path = rb_file_expand_path(path, Qnil);
        check(mdb_env_copy(environment->env, StringValueCStr(expanded_path)));
        return Qnil;
}

#database(name, options) ⇒ Database

Opens a database within the environment.

Note that a database is opened or created within a transaction. If the open creates a new database, the database is not available for other operations in other transactions until the transaction that is creating the database commits. If the transaction creating the database aborts, the database is not created.

Parameters:

  • name (String)

    Optional name for the database to be opened.

  • options (Hash)

    Options for the database.

Options Hash (options):

  • :reversekey (Boolean)

    Keys are strings to be compared in reverse order, from the end of the strings to the beginning. By default, Keys are treated as strings and compared from beginning to end.

  • :dupsort (Boolean)

    Duplicate keys may be used in the database. (Or, from another perspective, keys may have multiple data items, stored in sorted order.) By default keys must be unique and may have only a single data item.

  • :integerkey (Boolean)

    Keys are binary integers in native byte order.

  • :dupfixed (Boolean)

    This flag may only be used in combination with :dupsort. This option tells the library that the data items for this database are all the same size, which allows further optimizations in storage and retrieval.

  • :integerdup (Boolean)

    This option specifies that duplicate data items are also integers, and should be sorted as such.

  • :reversedup (Boolean)

    This option specifies that duplicate data items should be compared as strings in reverse order.

  • :create (Boolean)

    Create the named database if it doesn’t exist. This option is not allowed in a read-only transaction or a read-only environment.

Returns:

Raises:

  • (Error)

    if there is an error opening the database



753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
# File 'ext/isomorfeus_hamster_ext/isomorfeus_hamster.c', line 753

static VALUE environment_database(int argc, VALUE *argv, VALUE self) {
        ENVIRONMENT(self, environment);
        if (!active_txn(self))
                return call_with_transaction(self, self, "database", argc, argv, 0);

        VALUE name, option_hash;
        rb_scan_args(argc, argv, "02", &name, &option_hash);

        int flags = 0;
        if (!NIL_P(option_hash))
                rb_hash_foreach(option_hash, database_flags, (VALUE)&flags);

        MDB_dbi dbi;
        check(mdb_dbi_open(need_txn(self), NIL_P(name) ? 0 : StringValueCStr(name), flags, &dbi));

        Database* database;
        VALUE vdb = Data_Make_Struct(cDatabase, Database, database_mark, free, database);
        database->dbi = dbi;
        database->env = self;

        return vdb;
}

#flagsArray

Return the flags that are set in this environment. The environment flags are:

  • :fixedmap Use a fixed address for the mmap region.

  • :nosubdir By default, MDB creates its environment in a directory whose pathname is given in path, and creates its data and lock files under that directory. With this option, path is used as-is for the database main data file. The database lock file is the path with “-lock” appended.

  • :nosync Don’t flush system buffers to disk when committing a transaction. This optimization means a system crash can corrupt the database or lose the last transactions if buffers are not yet flushed to disk. The risk is governed by how often the system flushes dirty buffers to disk and how often #sync is called. However, if the filesystem preserves write order and the :writemap flag is not used, transactions exhibit ACI (atomicity, consistency, isolation) properties and only lose D (durability). That is, database integrity is maintained, but a system crash may undo the final transactions. Note that :nosync :writemap+ leaves the system with no hint for when to write transactions to disk, unless #sync is called. :mapasync :writemap+ may be preferable.

  • :rdonly Open the environment in read-only mode. No write operations will be allowed. MDB will still modify the lock file - except on read-only filesystems, where MDB does not use locks.

  • :nometasync Flush system buffers to disk only once per transaction, omit the metadata flush. Defer that until the system flushes files to disk, or next non-MDB_RDONLY commit or #sync. This optimization maintains database integrity, but a system crash may undo the last committed transaction. That is, it preserves the ACI (atomicity, consistency, isolation) but not D (durability) database property.

  • :writemap Use a writeable memory map unless :rdonly is set. This is faster and uses fewer mallocs, but loses protection from application bugs like wild pointer writes and other bad updates into the database. Incompatible with nested transactions.

  • :mapasync When using :writemap, use asynchronous flushes to disk. As with :nosync, a system crash can then corrupt the database or lose the last transactions. Calling #sync ensures on-disk database integrity until next commit.

  • :notls Don’t use thread-local storage.

Examples:

env = LMDB.new "abc", :writemap => true, :nometasync => true
env.flags           #=> [:writemap, :nometasync]

Returns:

  • (Array)

    Array of flag symbols



537
538
539
540
541
542
543
544
545
546
547
548
# File 'ext/isomorfeus_hamster_ext/isomorfeus_hamster.c', line 537

static VALUE environment_flags(VALUE self) {
        unsigned int flags;
        ENVIRONMENT(self, environment);
        check(mdb_env_get_flags(environment->env, &flags));

        VALUE ret = rb_ary_new();
#define FLAG(const, name) if (flags & MDB_##const) rb_ary_push(ret, ID2SYM(rb_intern(#name)));
#include "env_flags.h"
#undef FLAG

        return ret;
}

#infoHash

Return useful information about an environment.

  • :mapaddr The memory address at which the database is mapped, if fixed

  • :mapsize The size of the data memory map

  • :last_pgno ID of the last used page

  • :last_txnid ID of the last committed transaction

  • :maxreaders Max reader slots in the environment

  • :numreaders Max readers slots in the environment

Returns:

  • (Hash)


362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
# File 'ext/isomorfeus_hamster_ext/isomorfeus_hamster.c', line 362

static VALUE environment_info(VALUE self) {
        MDB_envinfo info;

        ENVIRONMENT(self, environment);
        check(mdb_env_info(environment->env, &info));

        VALUE ret = rb_hash_new();

#define INFO_SET(name) rb_hash_aset(ret, ID2SYM(rb_intern(#name)), SIZET2NUM((size_t)info.me_##name));
        INFO_SET(mapaddr);
        INFO_SET(mapsize);
        INFO_SET(last_pgno);
        INFO_SET(last_txnid);
        INFO_SET(maxreaders);
        INFO_SET(numreaders);
#undef INFO_SET

        return ret;
}

#mapsize=(size) ⇒ Object



562
563
564
565
566
# File 'ext/isomorfeus_hamster_ext/isomorfeus_hamster.c', line 562

static VALUE environment_set_mapsize(VALUE self, VALUE size) {
        ENVIRONMENT(self, environment);
        check(mdb_env_set_mapsize(environment->env, NUM2LONG(size)));
        return Qnil;
}

#pathString

Return the path to the database environment files

Returns:

  • (String)

    the path that was used to open the environment.



555
556
557
558
559
560
# File 'ext/isomorfeus_hamster_ext/isomorfeus_hamster.c', line 555

static VALUE environment_path(VALUE self) {
        const char* path;
        ENVIRONMENT(self, environment);
        check(mdb_env_get_path(environment->env, &path));
        return rb_str_new2(path);
}

#set_flags(flags) ⇒ Object

Set one or more flags in the environment. The available flags are defined in #flags.

Examples:

env.set_flags :nosync, :writemap

Parameters:

  • flags (Array)

    Array of flag names (symbols) to set

Returns:

  • nil

Raises:

  • (Error)

    if an invalid flag name is specified

See Also:



595
596
597
598
# File 'ext/isomorfeus_hamster_ext/isomorfeus_hamster.c', line 595

static VALUE environment_set_flags(int argc, VALUE* argv, VALUE self) {
        environment_change_flags(argc, argv, self, 1);
        return Qnil;
}

#statHash

Return useful statistics about an environment.

  • :psize Size of a database page

  • :depth Depth (height) of the B-tree

  • :branch_pages Number of internal (non-leaf) pages

  • :leaf_pages Number of leaf pages

  • :overflow_pages Number of overflow pages

  • :entries Number of data items

Returns:

  • (Hash)

    the statistics



344
345
346
347
348
349
# File 'ext/isomorfeus_hamster_ext/isomorfeus_hamster.c', line 344

static VALUE environment_stat(VALUE self) {
        ENVIRONMENT(self, environment);
        MDB_stat stat;
        check(mdb_env_stat(environment->env, &stat));
        return stat2hash(&stat);
}

#sync(force) ⇒ Object

Flush the data buffers to disk.

Data is always written to disk when Transaction#commit is called, but the operating system may keep it buffered. MDB always flushes the OS buffers upon commit as well, unless the environment was opened with :nosync or in part :nometasync.

Parameters:

  • force (Boolean)

    If true, force a synchronous flush. Otherwise if the environment has the :nosync flag set the flushes will be omitted, and with :mapasync they will be asynchronous.



414
415
416
417
418
419
420
421
422
# File 'ext/isomorfeus_hamster_ext/isomorfeus_hamster.c', line 414

static VALUE environment_sync(int argc, VALUE *argv, VALUE self) {
        ENVIRONMENT(self, environment);

        VALUE force;
        rb_scan_args(argc, argv, "01", &force);

        check(mdb_env_sync(environment->env, RTEST(force)));
        return Qnil;
}

#transaction(readonly) {|txn| ... } ⇒ Object

Note:

Transactions can be nested.

Begin a transaction. Takes a block to run the body of the transaction. A transaction commits when it exits the block successfully. A transaction aborts when it raises an exception or calls Transaction#abort.

Examples:

db = env.database "mydata"
env.transaction do |txn1|
  db['a'] = 1
  env.transaction do |txn2|
    # txn2 is nested in txn1
    db['a'] = 2
    db['a']                    #=> 2
    txn2.abort
  end
  db['a']                      #=> 1
  env.transaction do
    db['a'] = 3
  end
end
db['a']                        #=> 3

Parameters:

  • readonly (Boolean)

    This transaction will not perform any write operations

Yields:

  • (txn)

    The block to be executed with the body of the transaction.

Yield Parameters:

  • txn (Transaction)

    An optional transaction argument



696
697
698
699
700
701
702
703
704
# File 'ext/isomorfeus_hamster_ext/isomorfeus_hamster.c', line 696

static VALUE environment_transaction(int argc, VALUE *argv, VALUE self) {
        rb_need_block();

        VALUE readonly;
        rb_scan_args(argc, argv, "01", &readonly);
        unsigned int flags = RTEST(readonly) ? MDB_RDONLY : 0;

        return with_transaction(self, rb_yield, Qnil, flags);
}