Lightning database.
Inheritance: IDisposable
        public static void Delete <TKey, TValue>(this LightningTransaction txn, LightningDatabase db, TKey key, TValue value)
        {
            var keyBytes   = db.ToBytes(key);
            var valueBytes = db.ToBytes(value);

            txn.Delete(db, keyBytes, valueBytes);
        }
        public static TValue Get <TKey, TValue>(this LightningTransaction txn, LightningDatabase db, TKey key)
        {
            var keyBytes   = db.ToBytes(key);
            var valueBytes = txn.Get(db, keyBytes);

            return(db.FromBytes <TValue>(valueBytes));
        }
        public static void Put <TKey, TValue>(this LightningTransaction txn, LightningDatabase db, TKey key, TValue value, PutOptions options = PutOptions.None)
        {
            var keyBytes   = db.ToBytes(key);
            var valueBytes = db.ToBytes(value);

            txn.Put(db, keyBytes, valueBytes, options);
        }
 public MerkleTreePruningCursor(UInt256 blockHash, LightningTransaction txn, LightningDatabase db, LightningCursor cursor)
 {
     this.blockHash = blockHash;
     this.db = db;
     this.txn = txn;
     this.cursor = cursor;
 }
        public LmdbChainStateManager(string baseDirectory, long chainStateSize)
        {
            this.baseDirectory = baseDirectory;
            this.jetDirectory = Path.Combine(baseDirectory, "ChainState");
            this.jetDatabase = Path.Combine(this.jetDirectory, "ChainState.edb");

            LmdbStorageManager.PrepareSparseDatabase(this.jetDirectory);
            this.jetInstance = new LightningEnvironment(this.jetDirectory, EnvironmentOpenFlags.NoThreadLocalStorage | EnvironmentOpenFlags.NoSync)
            {
                MaxDatabases = 10,
                MapSize = chainStateSize
            };
            this.jetInstance.Open();

            using (var txn = this.jetInstance.BeginTransaction())
            {
                globalsTableId = txn.OpenDatabase("Globals", new DatabaseOptions { Flags = DatabaseOpenFlags.Create });
                headersTableId = txn.OpenDatabase("Headers", new DatabaseOptions { Flags = DatabaseOpenFlags.Create });
                unspentTxTableId = txn.OpenDatabase("UnspentTx", new DatabaseOptions { Flags = DatabaseOpenFlags.Create });
                blockSpentTxesTableId = txn.OpenDatabase("BlockSpentTxes", new DatabaseOptions { Flags = DatabaseOpenFlags.Create });
                blockUnmintedTxesTableId = txn.OpenDatabase("BlockUnmintedTxes", new DatabaseOptions { Flags = DatabaseOpenFlags.Create });

                txn.Commit();
            }

            this.cursorCache = new DisposableCache<IChainStateCursor>(1024,
                createFunc: () => new LmdbChainStateCursor(this.jetDatabase, this.jetInstance, globalsTableId, headersTableId, unspentTxTableId, blockSpentTxesTableId, blockUnmintedTxesTableId),
                prepareAction: cursor =>
                {
                    // rollback any open transaction before returning the cursor to the cache
                    if (cursor.InTransaction)
                        cursor.RollbackTransaction();
                });
        }
Example #6
0
        /// <summary>
        /// Opens a database in context of this transaction.
        /// </summary>
        /// <param name="name">Database name (optional). If null then the default name is used.</param>
        /// <param name="configuration">Database open options.</param>
        /// <returns>Created database wrapper.</returns>
        public LightningDatabase OpenDatabase(string name = null, DatabaseConfiguration configuration = null)
        {
            configuration = configuration ?? new DatabaseConfiguration();
            var db = new LightningDatabase(name, this, configuration);

            return(db);
        }
        public LmdbBlockTxesStorage(string baseDirectory, long blockTxesSize, int? index = null)
        {
            this.jetDirectory = Path.Combine(baseDirectory, "BlockTxes");
            if (index.HasValue)
                this.jetDirectory = Path.Combine(jetDirectory, index.Value.ToString());

            LmdbStorageManager.PrepareSparseDatabase(this.jetDirectory);
            this.jetInstance = new LightningEnvironment(this.jetDirectory, EnvironmentOpenFlags.NoThreadLocalStorage | EnvironmentOpenFlags.NoSync)
            {
                MaxDatabases = 10,
                MapSize = blockTxesSize
            };
            this.jetInstance.Open();

            using (var txn = this.jetInstance.BeginTransaction())
            {
                globalsTableId = txn.OpenDatabase("Globals", new DatabaseOptions { Flags = DatabaseOpenFlags.Create });
                blocksTableId = txn.OpenDatabase("Blocks", new DatabaseOptions { Flags = DatabaseOpenFlags.Create });

                if (!txn.ContainsKey(globalsTableId, blockCountKey))
                    txn.Put(globalsTableId, blockCountKey, Bits.GetBytes(0));

                txn.Commit();
            }
        }
Example #8
0
        /// <summary>
        /// Get value from a database.
        /// </summary>
        /// <param name="db">Database </param>
        /// <param name="key">Key byte array.</param>
        /// <returns>Requested value's byte array if exists, or null if not.</returns>
        public byte[] Get(LightningDatabase db, byte[] key)
        {
            byte[] value = null;
            this.TryGet(db, key, out value);

            return(value);
        }
        public LightningCursor(LightningDatabase db, LightningTransaction txn)
        {
            if (db == null)
                throw new ArgumentNullException("db");

            if (txn == null)
                throw new ArgumentNullException("txn");

            if (db.Environment != txn.Environment)
                throw new ArgumentException("db and txn belong to different environments");

            IntPtr handle = default(IntPtr);
            Native.Execute(lib => lib.mdb_cursor_open(txn._handle, db._handle, out handle));

            _handle = handle;

            this.Database = db;
            this.Transaction = txn;

            _shouldDispose = true;

            if (txn.IsReadOnly)
                this.Environment.Closing += EnvironmentOrTransactionClosing;
            else
                this.Transaction.Closing += EnvironmentOrTransactionClosing;
        }
Example #10
0
        /// <summary>
        /// Creates new instance of LightningCursor
        /// </summary>
        /// <param name="db">Database</param>
        /// <param name="txn">Transaction</param>
        internal LightningCursor(LightningDatabase db, LightningTransaction txn)
        {
            if (db == null)
            {
                throw new ArgumentNullException(nameof(db));
            }

            if (txn == null)
            {
                throw new ArgumentNullException(nameof(txn));
            }

            _currentWithOptimizedPair = () => _currentPair;
            _currentDefault           = () =>
            {
                if (_currentKeyStructure.size == IntPtr.Zero)
                {
                    return(default(KeyValuePair <byte[], byte[]>));
                }

                return(new KeyValuePair <byte[], byte[]>(_currentKeyStructure.GetBytes(),
                                                         _currentValueStructure.GetBytes()));
            };

            _getCurrent = _currentDefault;

            mdb_cursor_open(txn.Handle(), db.Handle(), out _handle);

            Database               = db;
            Transaction            = txn;
            Transaction.Disposing += Dispose;
        }
        /// <summary>
        /// Opens a database in context of this transaction.
        /// </summary>
        /// <param name="name">Database name (optional). If null then the default name is used.</param>
        /// <param name="configuration">Database open options.</param>
        /// <param name="closeOnDispose">Close database handle on dispose</param>
        /// <returns>Created database wrapper.</returns>
        public LightningDatabase OpenDatabase(string name = null, DatabaseConfiguration configuration = null, bool closeOnDispose = true)
        {
            configuration = configuration ?? new DatabaseConfiguration();
            var db = new LightningDatabase(name, this, configuration, closeOnDispose);

            return(db);
        }
Example #12
0
 internal void SetComparer(LightningTransaction tran, LightningDatabase db)
 {
     SetNativeCompareFunction(
         tran,
         db,
         Compare,
         (lib, func) => lib.mdb_set_compare(tran._handle, db._handle, func));
 }
Example #13
0
        /// <summary>
        /// The number of items in the database.
        /// </summary>
        /// <param name="db">The database we are counting items in.</param>
        /// <returns>The number of items.</returns>
        public long GetEntriesCount(LightningDatabase db)
        {
            MDBStat stat;

            mdb_stat(_handle, db.Handle(), out stat);

            return(stat.ms_entries.ToInt64());
        }
Example #14
0
        /// <summary>
        /// Tries to get a value by its key.
        /// </summary>
        /// <param name="db">Database.</param>
        /// <param name="key">Key byte array.</param>
        /// <param name="value">Value byte array if exists.</param>
        /// <returns>True if key exists, false if not.</returns>
        public bool TryGet(LightningDatabase db, byte[] key, out byte[] value)
        {
            if (db == null)
            {
                throw new ArgumentNullException(nameof(db));
            }

            return(mdb_get(_handle, db.Handle(), key, out value) != MDB_NOTFOUND);
        }
Example #15
0
        /// <summary>
        /// Put data into a database.
        /// </summary>
        /// <param name="db">Database.</param>
        /// <param name="key">Key byte array.</param>
        /// <param name="value">Value byte array.</param>
        /// <param name="options">Operation options (optional).</param>
        public void Put(LightningDatabase db, byte[] key, byte[] value, PutOptions options = PutOptions.None)
        {
            if (db == null)
            {
                throw new ArgumentNullException(nameof(db));
            }

            mdb_put(_handle, db.Handle(), key, value, options);
        }
Example #16
0
        /// <summary>
        /// Delete items from a database.
        /// This function removes key/data pairs from the database.
        /// If the database does not support sorted duplicate data items (MDB_DUPSORT) the data parameter is ignored.
        /// If the database supports sorted duplicates and the data parameter is NULL, all of the duplicate data items for the key will be deleted.
        /// Otherwise, if the data parameter is non-NULL only the matching data item will be deleted.
        /// This function will return MDB_NOTFOUND if the specified key/data pair is not in the database.
        /// </summary>
        /// <param name="db">A database handle returned by mdb_dbi_open()</param>
        /// <param name="key">The key to delete from the database</param>
        /// <param name="value">The data to delete (optional)</param>
        public void Delete(LightningDatabase db, byte[] key, byte[] value)
        {
            if (db == null)
            {
                throw new ArgumentNullException(nameof(db));
            }

            mdb_del(_handle, db.Handle(), key, value);
        }
        /// <summary>
        /// Delete items from a database.
        /// This function removes key/data pairs from the database.
        /// If the database does not support sorted duplicate data items (MDB_DUPSORT) the data parameter is ignored.
        /// If the database supports sorted duplicates and the data parameter is NULL, all of the duplicate data items for the key will be deleted.
        /// Otherwise, if the data parameter is non-NULL only the matching data item will be deleted.
        /// This function will return MDB_NOTFOUND if the specified key/data pair is not in the database.
        /// </summary>
        /// <param name="db">A database handle returned by mdb_dbi_open()</param>
        /// <param name="key">The key to delete from the database</param>
        public unsafe MDBResultCode Delete(LightningDatabase db, ReadOnlySpan <byte> key)
        {
            fixed(byte *ptr = key)
            {
                var mdbKey = new MDBValue(key.Length, ptr);

                return(mdb_del(_handle, db.Handle(), mdbKey));
            }
        }
Example #18
0
        /// <summary>
        /// Check whether data exists in database.
        /// </summary>
        /// <param name="db">Database.</param>
        /// <param name="key">Key.</param>
        /// <returns>True if key exists, false if not.</returns>
        public bool ContainsKey(LightningDatabase db, byte[] key)
        {
            if (db == null)
            {
                throw new ArgumentNullException(nameof(db));
            }

            byte[] value;
            return(TryGet(db, key, out value));
        }
 public LmdbChainStateCursor(string jetDatabase, LightningEnvironment jetInstance, LightningDatabase globalsTableId, LightningDatabase headersTableId, LightningDatabase unspentTxTableId, LightningDatabase blockSpentTxesTableId, LightningDatabase blockUnmintedTxesTableId)
 {
     this.jetDatabase = jetDatabase;
     this.jetInstance = jetInstance;
     this.globalsTableId = globalsTableId;
     this.headersTableId = headersTableId;
     this.unspentTxTableId = unspentTxTableId;
     this.blockSpentTxesTableId = blockSpentTxesTableId;
     this.blockUnmintedTxesTableId = blockUnmintedTxesTableId;
 }
 internal void ConfigureDatabase(LightningTransaction tx, LightningDatabase db)
 {
     if (_comparer != null)
     {
         mdb_set_compare(tx.Handle(), db.Handle(), Compare);
     }
     if (_duplicatesComparer != null)
     {
         mdb_set_dupsort(tx.Handle(), db.Handle(), IsDuplicate);
     }
 }
 public static bool TryGet(this LightningTransaction tx, LightningDatabase db, ReadOnlySpan <byte> key, out byte[] value)
 {
     var(resultCode, _, mdbValue) = tx.Get(db, key);
     if (resultCode == MDBResultCode.Success)
     {
         value = mdbValue.CopyToNewArray();
         return(true);
     }
     value = default;
     return(false);
 }
Example #22
0
        /// <summary>
        /// Check whether data exists in database.
        /// </summary>
        /// <param name="db">Database.</param>
        /// <param name="key">Key.</param>
        /// <returns>True if key exists, false if not.</returns>
        public bool ContainsKey(LightningDatabase db, byte[] key)
        {
            if (db == null)
            {
                throw new ArgumentNullException("db");
            }

            Func <byte[]> factory;

            return(this.TryGetInternal(db._handle, key, out factory));
        }
Example #23
0
        internal void SetDuplicatesSort(LightningTransaction tran, LightningDatabase db)
        {
            if (!db.OpenFlags.HasFlag(DatabaseOpenFlags.DuplicatesSort))
                return;

            SetNativeCompareFunction(
                tran,
                db,
                DuplicatesSort,
                (lib, func) => lib.mdb_set_dupsort(tran._handle, db._handle, func));
        }
        public static bool TryGet <TKey, TValue>(this LightningTransaction txn, LightningDatabase db, TKey key, out TValue value)
        {
            GetByOperation operation;
            var            result = txn.TryGetBy(db, key, out operation);

            value = result
                ? operation.Value <TValue>()
                : default(TValue);

            return(result);
        }
        /// <summary>
        /// Get value from a database.
        /// </summary>
        /// <param name="db">The database to query.</param>
        /// <param name="key">A span containing the key to look up.</param>
        /// <returns>Requested value's byte array if exists, or null if not.</returns>
        public unsafe (MDBResultCode resultCode, MDBValue key, MDBValue value) Get(LightningDatabase db, ReadOnlySpan <byte> key)
        {
            if (db == null)
            {
                throw new ArgumentNullException(nameof(db));

                fixed(byte *keyBuffer = key)
                {
                    var mdbKey = new MDBValue(key.Length, keyBuffer);

                    return(mdb_get(_handle, db.Handle(), ref mdbKey, out var mdbValue), mdbKey, mdbValue);
                }
        }
        public static bool TryGetBy <TKey>(this LightningTransaction txn, LightningDatabase db, TKey key, out GetByOperation value)
        {
            byte[] valueBytes;

            var keyBytes = db.ToBytes(key);
            var result   = txn.TryGet(db, keyBytes, out valueBytes);

            value = result
                ? new GetByOperation(db, valueBytes)
                : null;

            return(result);
        }
        /// <summary>
        /// Put data into a database.
        /// </summary>
        /// <param name="db">Database.</param>
        /// <param name="key">Key byte array.</param>
        /// <param name="value">Value byte array.</param>
        /// <param name="options">Operation options (optional).</param>
        public unsafe MDBResultCode Put(LightningDatabase db, ReadOnlySpan <byte> key, ReadOnlySpan <byte> value, PutOptions options = PutOptions.None)
        {
            if (db == null)
            {
                throw new ArgumentNullException(nameof(db));

                fixed(byte *keyPtr = key)
                fixed(byte *valuePtr = value)
                {
                    var mdbKey   = new MDBValue(key.Length, keyPtr);
                    var mdbValue = new MDBValue(value.Length, valuePtr);

                    return(mdb_put(_handle, db.Handle(), mdbKey, mdbValue, options));
                }
        }
Example #28
0
        /// <summary>
        /// Tries to get a value by its key.
        /// </summary>
        /// <param name="db">Database.</param>
        /// <param name="key">Key byte array.</param>
        /// <param name="value">Value byte array if exists.</param>
        /// <returns>True if key exists, false if not.</returns>
        public bool TryGet(LightningDatabase db, byte[] key, out byte[] value)
        {
            if (db == null)
            {
                throw new ArgumentNullException("db");
            }

            Func <byte[]> factory;
            var           result = this.TryGetInternal(db._handle, key, out factory);

            value = result
                ? factory.Invoke()
                : null;

            return(result);
        }
Example #29
0
        /// <summary>
        /// Put data into a database.
        /// </summary>
        /// <param name="db">Database.</param>
        /// <param name="key">Key byte array.</param>
        /// <param name="value">Value byte array.</param>
        /// <param name="options">Operation options (optional).</param>
        public void Put(LightningDatabase db, byte[] key, byte[] value, PutOptions options = PutOptions.None)
        {
            if (db == null)
            {
                throw new ArgumentNullException("db");
            }

            using (var keyStructureMarshal = new MarshalValueStructure(key))
                using (var valueStructureMarshal = new MarshalValueStructure(value))
                {
                    var keyStruct   = keyStructureMarshal.ValueStructure;
                    var valueStruct = valueStructureMarshal.ValueStructure;

                    NativeMethods.Execute(lib => lib.mdb_put(_handle, db._handle, ref keyStruct, ref valueStruct, options));
                }
        }
        //TODO: Upgrade db flags?
        internal LightningDatabase OpenDatabase(string name, DatabaseOpenFlags flags, LightningTransaction tran)
        {
            var internalName = name ?? LightningDatabase.DefaultDatabaseName;
            var db = _openedDatabases.GetOrAdd(internalName, n => 
            {
                var ldb = new LightningDatabase(name, flags, tran);
                _databasesForReuse.Add(ldb._handle);

                return ldb;
            });

            if (db.OpenFlags != flags)
                throw new InvalidOperationException("Database " + internalName + " already opened with different flags");

            return db;
        }
        public static bool TryGet(this LightningTransaction tx, LightningDatabase db, ReadOnlySpan <byte> key, byte[] destinationValueBuffer)
        {
            var(resultCode, _, mdbValue) = tx.Get(db, key);
            if (resultCode != MDBResultCode.Success)
            {
                return(false);
            }

            var valueSpan = mdbValue.AsSpan();

            if (valueSpan.TryCopyTo(destinationValueBuffer))
            {
                return(true);
            }
            throw new LightningException("Incorrect buffer size given in destinationValueBuffer", (int)MDBResultCode.BadValSize);
        }
 internal IDisposable ConfigureDatabase(LightningTransaction tx, LightningDatabase db)
 {
     var pinnedComparer = new ComparerKeepAlive();
     if (_comparer != null)
     {
         CompareFunction compare = Compare;
         pinnedComparer.AddComparer(compare);
         mdb_set_compare(tx.Handle(), db.Handle(), compare);
     }
     if (_duplicatesComparer != null)
     {
         CompareFunction dupCompare = IsDuplicate;
         pinnedComparer.AddComparer(dupCompare);
         mdb_set_dupsort(tx.Handle(), db.Handle(), dupCompare);
     }
     return pinnedComparer;
 }
        /// <summary>
        /// Creates new instance of LightningCursor
        /// </summary>
        /// <param name="db">Database</param>
        /// <param name="txn">Transaction</param>
        internal LightningCursor(LightningDatabase db, LightningTransaction txn)
        {
            if (db == null)
            {
                throw new ArgumentNullException(nameof(db));
            }

            if (txn == null)
            {
                throw new ArgumentNullException(nameof(txn));
            }

            mdb_cursor_open(txn.Handle(), db.Handle(), out _handle).ThrowOnError();

            Transaction            = txn;
            Transaction.Disposing += Dispose;
        }
        internal IDisposable ConfigureDatabase(LightningTransaction tx, LightningDatabase db)
        {
            var pinnedComparer = new ComparerKeepAlive();

            if (_comparer != null)
            {
                CompareFunction compare = Compare;
                pinnedComparer.AddComparer(compare);
                mdb_set_compare(tx.Handle(), db.Handle(), compare);
            }
            if (_duplicatesComparer != null)
            {
                CompareFunction dupCompare = IsDuplicate;
                pinnedComparer.AddComparer(dupCompare);
                mdb_set_dupsort(tx.Handle(), db.Handle(), dupCompare);
            }
            return(pinnedComparer);
        }
Example #35
0
        private static void SetNativeCompareFunction(
            LightningTransaction tran, 
            LightningDatabase db,
            Func<CompareFunctionBuilder, LightningCompareDelegate> delegateFactory,
            Func<INativeLibraryFacade, CompareFunction, int> setter)
        {
            if (delegateFactory == null)
                return;

            var comparer = delegateFactory.Invoke(new CompareFunctionBuilder());
            if (comparer == null)
                return;

            var compareFunction = CreateNativeCompareFunction(db, comparer);

            NativeMethods.Execute(lib => setter.Invoke(lib, compareFunction));
            tran.SubTransactionsManager.StoreCompareFunction(compareFunction);
        }
Example #36
0
        private LightningEnvironment NewEnvironment(out LightningDatabase db, bool delete = true)
        {
            if (delete && Directory.Exists(_path))
                Directory.Delete(_path, true);

            if (!Directory.Exists(_path))
                Directory.CreateDirectory(_path);

            var env = new LightningEnvironment(_path, EnvironmentOpenFlags.None)
                          {
                              MapSize = 1024 * 1024 * 1024 * (long)10
                          };
            env.Open();
            var tx = env.BeginTransaction();
            db = tx.OpenDatabase();
			tx.Commit();

            return env;
        }
Example #37
0
        /// <summary>
        /// Opens a database in context of this transaction.
        /// </summary>
        /// <param name="name">Database name (optional). If null then the default name is used.</param>
        /// <param name="flags">Database open options (optionsl).</param>
        /// <param name="encoding">Database keys encoding.</param>
        /// <returns>Created database wrapper.</returns>
        public LightningDatabase OpenDatabase(string name = null, DatabaseOpenFlags?flags = null, Encoding encoding = null)
        {
            if (name == null && (!flags.HasValue || flags.Value == LightningConfig.Database.DefaultOpenFlags))
            {
                if (_defaultDatabase == null || _defaultDatabase.IsReleased)
                {
                    _defaultDatabase = this.Environment.OpenDatabase(name, this, flags, encoding);
                }

                if (_defaultDatabase.Encoding != (encoding ?? LightningConfig.Database.DefaultEncoding))
                {
                    throw new InvalidOperationException("Can not change encoding of already opened database");
                }

                return(_defaultDatabase);
            }

            return(this.Environment.OpenDatabase(name, this, flags, encoding));
        }
        /// <summary>
        /// Delete items from a database.
        /// This function removes key/data pairs from the database.
        /// If the database does not support sorted duplicate data items (MDB_DUPSORT) the data parameter is ignored.
        /// If the database supports sorted duplicates and the data parameter is NULL, all of the duplicate data items for the key will be deleted.
        /// Otherwise, if the data parameter is non-NULL only the matching data item will be deleted.
        /// This function will return MDB_NOTFOUND if the specified key/data pair is not in the database.
        /// </summary>
        /// <param name="db">A database handle returned by mdb_dbi_open()</param>
        /// <param name="key">The key to delete from the database</param>
        /// <param name="value">The data to delete (optional)</param>
        public unsafe MDBResultCode Delete(LightningDatabase db, ReadOnlySpan <byte> key, ReadOnlySpan <byte> value)
        {
            if (db == null)
            {
                throw new ArgumentNullException(nameof(db));

                fixed(byte *keyPtr = key)
                fixed(byte *valuePtr = value)
                {
                    var mdbKey = new MDBValue(key.Length, keyPtr);

                    if (value == null)
                    {
                        return(mdb_del(_handle, db.Handle(), mdbKey));
                    }
                    var mdbValue = new MDBValue(value.Length, valuePtr);

                    return(mdb_del(_handle, db.Handle(), mdbKey, mdbValue));
                }
        }
        public LmdbBlockStorage(string baseDirectory, long blocksSize)
        {
            this.jetDirectory = Path.Combine(baseDirectory, "Blocks");

            LmdbStorageManager.PrepareSparseDatabase(this.jetDirectory);
            this.jetInstance = new LightningEnvironment(this.jetDirectory, EnvironmentOpenFlags.NoThreadLocalStorage | EnvironmentOpenFlags.NoSync)
            {
                MaxDatabases = 10,
                MapSize = blocksSize,
            };
            this.jetInstance.Open();

            using (var txn = this.jetInstance.BeginTransaction())
            {
                globalsTableId = txn.OpenDatabase("Globals", new DatabaseOptions { Flags = DatabaseOpenFlags.Create });
                blockHeadersTableId = txn.OpenDatabase("BlockHeaders", new DatabaseOptions { Flags = DatabaseOpenFlags.Create });
                invalidBlocksTableId = txn.OpenDatabase("InvalidBlocks", new DatabaseOptions { Flags = DatabaseOpenFlags.Create });

                txn.Commit();
            }
        }
Example #40
0
        /// <summary>
        /// Delete items from a database.
        /// This function removes key/data pairs from the database.
        /// If the database does not support sorted duplicate data items (MDB_DUPSORT) the data parameter is ignored.
        /// If the database supports sorted duplicates and the data parameter is NULL, all of the duplicate data items for the key will be deleted.
        /// Otherwise, if the data parameter is non-NULL only the matching data item will be deleted.
        /// This function will return MDB_NOTFOUND if the specified key/data pair is not in the database.
        /// </summary>
        /// <param name="db">A database handle returned by mdb_dbi_open()</param>
        /// <param name="key">The key to delete from the database</param>
        /// <param name="value">The data to delete (optional)</param>
        public void Delete(LightningDatabase db, byte[] key, byte[] value = null)
        {
            if (db == null)
            {
                throw new ArgumentNullException("db");
            }

            using (var keyMarshalStruct = new MarshalValueStructure(key))
            {
                var keyStructure = keyMarshalStruct.ValueStructure;
                if (value != null)
                {
                    using (var valueMarshalStruct = new MarshalValueStructure(value))
                    {
                        var valueStructure = valueMarshalStruct.ValueStructure;
                        NativeMethods.Execute(lib => lib.mdb_del(_handle, db._handle, ref keyStructure, ref valueStructure));
                        return;
                    }
                }
                NativeMethods.Execute(lib => lib.mdb_del(_handle, db._handle, ref keyStructure, IntPtr.Zero));
            }
        }
Example #41
0
        //TODO: Upgrade db flags?
        internal LightningDatabase OpenDatabase(string name, LightningTransaction tran, DatabaseOpenFlags?flags, Encoding encoding)
        {
            var internalName = name ?? LightningDatabase.DefaultDatabaseName;
            var db           = _openedDatabases.GetOrAdd(internalName, n =>
            {
                var ldb = new LightningDatabase(name, tran, flags, encoding);
                _databasesForReuse.Add(ldb._handle);

                return(ldb);
            });

            if (db.OpenFlags != flags.GetValueOrDefault())
            {
                throw new InvalidOperationException("Database " + internalName + " already opened with different flags");
            }

            if (db.Encoding != (encoding ?? LightningConfig.Database.DefaultEncoding))
            {
                throw new InvalidOperationException("Can not change encoding of already opened database");
            }

            return(db);
        }
Example #42
0
        private List<PerformanceRecord> WriteInternal(
            string operation,
            IEnumerator<TestData> enumerator,
            long itemsPerTransaction,
            long numberOfTransactions,
            PerfTracker perfTracker,
			rndseq Rflag,
            LightningEnvironment env,
			LightningDatabase db)
        {
            byte[] valueToWrite = null;
            var records = new List<PerformanceRecord>();
            var sw = new Stopwatch();
			LightningDB.PutOptions putflags = LightningDB.PutOptions.None;

			if (Rflag == rndseq.SEQ)
				putflags = LightningDB.PutOptions.AppendData;

            for (var transactions = 0; transactions < numberOfTransactions; transactions++)
            {
                sw.Restart();

                using (var tx = env.BeginTransaction())
                {
                    for (var i = 0; i < itemsPerTransaction; i++)
                    {
                        enumerator.MoveNext();

                        valueToWrite = GetValueToWrite(valueToWrite, enumerator.Current.ValueSize);

                        tx.Put(db, Encoding.UTF8.GetBytes(enumerator.Current.Id.ToString("0000000000000000")), valueToWrite, putflags);
                    }

                    tx.Commit();
                }

                sw.Stop();
                perfTracker.Record(sw.ElapsedMilliseconds);

                records.Add(new PerformanceRecord
                                {
                                    Operation = operation, 
                                    Time = DateTime.Now, 
                                    Duration = sw.ElapsedMilliseconds, 
                                    ProcessedItems = itemsPerTransaction
                                });
            }

            sw.Stop();

            return records;
        }
Example #43
0
        private static long ReadInternal(IEnumerable<uint> ids, PerfTracker perfTracker, LightningEnvironment env,
			LightningDatabase db)
        {
            using (var tx = env.BeginTransaction(LightningDB.TransactionBeginFlags.ReadOnly))
			using (var cursor = new LightningCursor(db, tx))
            {
                long v = 0;
                foreach (var id in ids)
                {
                    var value = cursor.MoveTo(Encoding.UTF8.GetBytes(id.ToString("0000000000000000")));
                    v += value.Value.Length;
                    //Debug.Assert(value != null);
                }
                return v;
            }
        }
        /// <summary>
        /// Delete items from a database.
        /// This function removes key/data pairs from the database. 
        /// If the database does not support sorted duplicate data items (MDB_DUPSORT) the data parameter is ignored. 
        /// If the database supports sorted duplicates and the data parameter is NULL, all of the duplicate data items for the key will be deleted. 
        /// Otherwise, if the data parameter is non-NULL only the matching data item will be deleted. 
        /// This function will return MDB_NOTFOUND if the specified key/data pair is not in the database.
        /// </summary>
        /// <param name="db">A database handle returned by mdb_dbi_open()</param>
        /// <param name="key">The key to delete from the database</param>
        /// <param name="value">The data to delete (optional)</param>
        public void Delete(LightningDatabase db, byte[] key, byte[] value)
        {
            if (db == null)
                throw new ArgumentNullException(nameof(db));

            mdb_del(_handle, db.Handle(), key, value);
        }
        /// <summary>
        /// Tries to get a value by its key.
        /// </summary>
        /// <param name="db">Database.</param>
        /// <param name="key">Key byte array.</param>
        /// <param name="value">Value byte array if exists.</param>
        /// <returns>True if key exists, false if not.</returns>
        public bool TryGet(LightningDatabase db, byte[] key, out byte[] value)
        {
            if (db == null)
                throw new ArgumentNullException(nameof(db));

            return mdb_get(_handle, db.Handle(), key, out value) != MDB_NOTFOUND;
        }
 /// <summary>
 /// Create a cursor.
 /// Cursors are associated with a specific transaction and database and may not span threads.
 /// </summary>
 /// <param name="db">A database.</param>
 public LightningCursor CreateCursor(LightningDatabase db)
 {
     return new LightningCursor(db, this);
 }
        public void Delete(LightningDatabase db, byte[] key, byte[] value = null)
        {
            if (db == null)
                throw new ArgumentNullException("db");

            using (var keyMarshalStruct = new MarshalValueStructure(key))
            {
                var keyStructure = keyMarshalStruct.ValueStructure;
                if (value != null)
                {
                    using (var valueMarshalStruct = new MarshalValueStructure(value))
                    {
                        var valueStructure = valueMarshalStruct.ValueStructure;
                        Native.Execute(() => Native.mdb_del(_handle, db._handle, ref keyStructure, ref valueStructure));
                        return;
                    }
                }
                Native.Execute(() => Native.mdb_del(_handle, db._handle, ref keyStructure, IntPtr.Zero));
            }
        }
        public void DropDatabase(LightningDatabase db, bool delete)
        {
            Native.Execute(() => Native.mdb_drop(_handle, db._handle, delete));

            db.Close(false);
        }
 /// <summary>
 /// Get value from a database.
 /// </summary>
 /// <param name="db">Database </param>
 /// <param name="key">Key byte array.</param>
 /// <returns>Requested value's byte array if exists, or null if not.</returns>
 public byte[] Get(LightningDatabase db, byte[] key)
 {
     byte[] value;
     TryGet(db, key, out value);
     return value;
 }
 /// <summary>
 /// Drops the database.
 /// </summary>
 public void DropDatabase(LightningDatabase database)
 {
     database.Drop(this);
 }
        /// <summary>
        /// Put data into a database.
        /// </summary>
        /// <param name="db">Database.</param>
        /// <param name="key">Key byte array.</param>
        /// <param name="value">Value byte array.</param>
        /// <param name="options">Operation options (optional).</param>
        public void Put(LightningDatabase db, byte[] key, byte[] value, PutOptions options = PutOptions.None)
        {
            if (db == null)
                throw new ArgumentNullException(nameof(db));

            mdb_put(_handle, db.Handle(), key, value, options);
        }
 internal void ReleaseDatabase(LightningDatabase db)
 {
     _databasesForReuse.Remove(db._handle);
 }
Example #53
0
 private static CompareFunction CreateNativeCompareFunction(
     LightningDatabase db, LightningCompareDelegate compare)
 {
     return (IntPtr left, IntPtr right) =>
         compare.Invoke(db, NativeMethods.ValueByteArrayFromPtr(left), NativeMethods.ValueByteArrayFromPtr(right));
 }
 /// <summary>
 /// Truncates all data from the database.
 /// </summary>
 public void TruncateDatabase(LightningDatabase database)
 {
     database.Truncate(this);
 }
 /// <summary>
 /// Delete items from a database.
 /// This function removes key/data pairs from the database. 
 /// If the database does not support sorted duplicate data items (MDB_DUPSORT) the data parameter is ignored. 
 /// If the database supports sorted duplicates and the data parameter is NULL, all of the duplicate data items for the key will be deleted. 
 /// Otherwise, if the data parameter is non-NULL only the matching data item will be deleted. 
 /// This function will return MDB_NOTFOUND if the specified key/data pair is not in the database.
 /// </summary>
 /// <param name="db">A database handle returned by mdb_dbi_open()</param>
 /// <param name="key">The key to delete from the database</param>
 public void Delete(LightningDatabase db, byte[] key)
 {
     mdb_del(_handle, db.Handle(), key);
 }
        /// <summary>
        /// Check whether data exists in database.
        /// </summary>
        /// <param name="db">Database.</param>
        /// <param name="key">Key.</param>
        /// <returns>True if key exists, false if not.</returns>
        public bool ContainsKey(LightningDatabase db, byte[] key)
        {
            if (db == null)
                throw new ArgumentNullException(nameof(db));

            byte[] value;
            return TryGet(db, key, out value);
        }
 internal void ReuseDatabase(LightningDatabase db)
 {
     _openedDatabases.TryRemove(db.Name, out db);
 }
        /// <summary>
        /// The number of items in the database.
        /// </summary>
        /// <param name="db">The database we are counting items in.</param>
        /// <returns>The number of items.</returns>
        public long GetEntriesCount(LightningDatabase db)
        {
            MDBStat stat;
            mdb_stat(_handle, db.Handle(), out stat);

            return stat.ms_entries.ToInt64();
        }
        //TODO: Upgrade db flags?
        internal LightningDatabase OpenDatabase(string name, DatabaseOpenFlags flags, LightningTransaction tran)
        {
            var internalName = name ?? LightningDatabase.DefaultDatabaseName;
            var db = _openedDatabases.GetOrAdd(internalName, n => 
            {
                var ldb = new LightningDatabase(name, flags, tran);
                _databasesForReuse.Add(ldb._handle);

                return ldb;
            });

            if (db.OpenFlags != flags)
                throw new InvalidOperationException("Database " + internalName + " already opened with different flags");

            return db;
        }
 /// <summary>
 /// Opens a database in context of this transaction.
 /// </summary>
 /// <param name="name">Database name (optional). If null then the default name is used.</param>
 /// <param name="configuration">Database open options.</param>
 /// <returns>Created database wrapper.</returns>
 public LightningDatabase OpenDatabase(string name = null, DatabaseConfiguration configuration = null)
 {
     configuration = configuration ?? new DatabaseConfiguration();
     var db = new LightningDatabase(name, this, configuration);
     return db;
 }