コード例 #1
0
        private void Dispose(bool disposing)
        {
            var isReadOnly = IsReadOnly;

            if (_state == TransactionState.Disposed)
            {
                if (disposing)
                {
                    ThrowlAlreadyDisposed();
                }
                else
                {
                    return;
                }
            }

            _state = TransactionState.Disposed;

            if (isReadOnly)
            {
                if (disposing)
                {
                    NativeMethods.mdb_txn_reset(_handle);
                    _state = TransactionState.Reset;

                    var pooled = _lmdbEnvironment.ReadTxnPool.Return(this);
                    if (pooled)
                    {
                        Debug.Assert(_state == TransactionState.Reset); // set above
                        return;
                    }
                }
                else
                {
#if DEBUG
                    Trace.TraceWarning("Finalizing read transaction. Dispose it explicitly. " + StackTrace);
#endif
                }

                _state = TransactionState.Disposed;
                NativeMethods.mdb_txn_abort(_handle);
                _handle = IntPtr.Zero;
            }
            else
            {
                if (disposing)
                {
                    if (_state == TransactionState.Active)
                    {
                        NativeMethods.mdb_txn_abort(_handle);

                        if (!LmdbEnvironment.AutoAbort)
                        {
                            ThrowDisposingActiveTransaction();
                        }
                    }
                }
                else
                {
                    if (_state == TransactionState.Active)
                    {
                        NativeMethods.mdb_txn_abort(_handle);
                        FailFinalizingActiveTransaction();
                    }
                    else
                    {
#if DEBUG
                        Trace.TraceWarning("Finalizing finished write transaction. Dispose it explicitly. " + StackTrace);
#endif
                    }
                }
                _handle = IntPtr.Zero;
            }

            _lmdbEnvironment = null;

#if DEBUG
            StackTrace = null;
#endif

            if (disposing)
            {
                TxPool.Return(this);
            }
        }
コード例 #2
0
ファイル: Database.cs プロジェクト: Spreads/Spreads.LMDB
        internal Database(string name, TransactionImpl txn, DatabaseConfig config)
        {
            if (txn.IsReadOnly)
            {
                throw new InvalidOperationException("Cannot create a DB with RO transaction");
            }
            if (txn == null)
            {
                throw new ArgumentNullException(nameof(txn));
            }
            _config              = config ?? throw new ArgumentNullException(nameof(config));
            _name                = name;
            _environment         = txn.LmdbEnvironment;
            _environmentGcHandle = GCHandle.Alloc(_environment, GCHandleType.Normal);

            NativeMethods.AssertExecute(NativeMethods.mdb_dbi_open(txn.Handle, name, _config.OpenFlags, out var handle));
            if (_config.CompareFunction != null)
            {
                NativeMethods.AssertExecute(NativeMethods.mdb_set_compare(txn.Handle, handle, _config.CompareFunction));
            }
            if (_config.DupSortFunction != null)
            {
                NativeMethods.AssertExecute(NativeMethods.mdb_set_dupsort(txn.Handle, handle, _config.DupSortFunction));
            }
            if (_config.DupSortPrefix > 0)
            {
                if (_config.DupSortPrefix == 64 * 64)
                {
                    NativeMethods.AssertExecute(NativeMethods.sdb_set_dupsort_as_uint64x64(txn.Handle, handle));
                }
                else if (_config.DupSortPrefix == 128)
                {
                    NativeMethods.AssertExecute(NativeMethods.sdb_set_dupsort_as_uint128(txn.Handle, handle));
                }
                else if (_config.DupSortPrefix == 96)
                {
                    NativeMethods.AssertExecute(NativeMethods.sdb_set_dupsort_as_uint96(txn.Handle, handle));
                }
                else if (_config.DupSortPrefix == 80)
                {
                    NativeMethods.AssertExecute(NativeMethods.sdb_set_dupsort_as_uint80(txn.Handle, handle));
                }
                else if (_config.DupSortPrefix == 64)
                {
                    NativeMethods.AssertExecute(NativeMethods.sdb_set_dupsort_as_uint64(txn.Handle, handle));
                }
                else if (_config.DupSortPrefix == 48)
                {
                    NativeMethods.AssertExecute(NativeMethods.sdb_set_dupsort_as_uint48(txn.Handle, handle));
                }
                else if (_config.DupSortPrefix == 32)
                {
                    NativeMethods.AssertExecute(NativeMethods.sdb_set_dupsort_as_uint32(txn.Handle, handle));
                }
                else if (_config.DupSortPrefix == 16)
                {
                    NativeMethods.AssertExecute(NativeMethods.sdb_set_dupsort_as_uint16(txn.Handle, handle));
                }
                else
                {
                    throw new NotSupportedException("Rethink your design if you need this!");
                }
            }

            _handle = handle;

            var poolSize = System.Environment.ProcessorCount * 2;

            ReadCursorPool = new LockedObjectPool <CursorImpl>(() => null, poolSize, false);
        }
コード例 #3
0
        internal static TransactionImpl Create(LMDBEnvironment lmdbEnvironment, TransactionBeginFlags beginFlags)
        {
            lmdbEnvironment.EnsureOpen();

            TransactionImpl tx;

            // ReSharper disable once BitwiseOperatorOnEnumWithoutFlags
            var isReadOnly = (beginFlags & TransactionBeginFlags.ReadOnly) == TransactionBeginFlags.ReadOnly;

            if (isReadOnly)
            {
                if ((tx = lmdbEnvironment.ReadTxnPool.Rent()) == null)
                {
                    tx             = TxPool.Rent();
                    tx._isReadOnly = true;
                    if (tx._state != TransactionState.Disposed)
                    {
                        ThrowShoudBeDisposed();
                    }
                }
                else
                {
                    Debug.Assert(tx._isReadOnly);
                    Debug.Assert(tx._state == TransactionState.Reset);
                }

                if (tx.IsInvalid)
                {
                    // create new handle
                    NativeMethods.AssertExecute(NativeMethods.mdb_txn_begin(
                                                    lmdbEnvironment._handle.Handle,
                                                    IntPtr.Zero, beginFlags, out var handle));
                    tx.SetNewHandle(handle);
                }
                else
                {
                    tx.Renew();
                }
            }
            else
            {
                tx             = TxPool.Rent();
                tx._isReadOnly = false;
                NativeMethods.AssertExecute(NativeMethods.mdb_txn_begin(
                                                lmdbEnvironment._handle.Handle,
                                                IntPtr.Zero, beginFlags, out IntPtr handle));
                tx._handle = handle;
                if (tx._state != TransactionState.Disposed)
                {
                    ThrowShoudBeDisposed();
                }
            }

            tx._lmdbEnvironment = lmdbEnvironment;
            tx._state           = TransactionState.Active;

#if DEBUG
            tx.StackTrace = Environment.StackTrace;
#endif
            return(tx);
        }