示例#1
0
 public ReadOnlyTransaction(Spreads.LMDB.ReadOnlyTransaction tx, DatabasesHolder databasesHolder, IndexesHolder indexesHolder)
     : base(databasesHolder, indexesHolder)
 {
     this.tx = tx;
     this.databasesHolder = databasesHolder;
     this.indexesHolder   = indexesHolder;
 }
示例#2
0
        private IEnumerable <DirectBuffer> AsEnumerable(ReadOnlyTransaction txn, RetainedMemory <byte> key)
        {
            if (((int)OpenFlags & (int)DbFlags.DuplicatesSort) == 0)
            {
                throw new InvalidOperationException("AsEnumerable overload with key parameter should only be provided for dupsorted dbs");
            }

            try
            {
                var          key1  = new DirectBuffer(key.GetSpan());
                DirectBuffer value = default;
                using (var c = OpenReadOnlyCursor(txn))
                {
                    if (c.TryGet(ref key1, ref value, CursorGetOption.SetKey) &&
                        c.TryGet(ref key1, ref value, CursorGetOption.FirstDuplicate))
                    {
                        yield return(value);

                        while (c.TryGet(ref key1, ref value, CursorGetOption.NextDuplicate))
                        {
                            yield return(value);
                        }
                    }
                }
            }
            finally
            {
                key.Dispose();
            }
        }
示例#3
0
 public bool TryFindDup(ReadOnlyTransaction txn, Lookup direction, ref DirectBuffer key, ref DirectBuffer value)
 {
     using (var cursor = OpenReadOnlyCursor(txn))
     {
         return(cursor.TryFindDup(direction, ref key, ref value));
     }
 }
        public ReadOnlyTransaction BeginReadOnlyTransaction()
        {
            var txn   = TransactionImpl.Create(this, TransactionBeginFlags.ReadOnly);
            var rotxn = new ReadOnlyTransaction(txn);

            return(rotxn);
        }
示例#5
0
        public bool TryGet <TKey, TValue>(ReadOnlyTransaction txn, ref TKey key, out TValue value)
            where TKey : struct where TValue : struct
        {
            var keyPtr = AsPointer(ref key);
            var keyDb  = new DirectBuffer(TypeHelper <TKey> .EnsureFixedSize(), (byte *)keyPtr);

            return(TryGet(txn, ref keyDb, out value));
        }
 public T Read <T>(Func <ReadOnlyTransaction, object, T> readFunc, object state)
 {
     using (var txn = TransactionImpl.Create(this, TransactionBeginFlags.ReadOnly))
     {
         var rotxn = new ReadOnlyTransaction(txn);
         return(readFunc(rotxn, state));
     }
 }
 public void Read(Action <ReadOnlyTransaction, object> readAction, object state)
 {
     using (var txn = TransactionImpl.Create(this, TransactionBeginFlags.ReadOnly))
     {
         var rotxn = new ReadOnlyTransaction(txn);
         readAction(rotxn, state);
     }
 }
示例#8
0
        protected TrackDataDTO GetTrackById(ref DirectBuffer id, Spreads.LMDB.ReadOnlyTransaction transaction)
        {
            if (databasesHolder.TracksDatabase.TryGet(transaction, ref id, out var value))
            {
                return(MessagePackSerializer.Deserialize <TrackDataDTO>(value.Span.ToArray(), options: serializerOptions));
            }

            return(null);
        }
示例#9
0
        public bool TryGet <T>(ReadOnlyTransaction txn, ref T key, out DirectBuffer value)
            where T : struct
        {
            EnsureNoRefs <T>();

            var keyPtr = AsPointer(ref key);
            var keyDb  = new DirectBuffer(SizeOf <T>(), (nint)keyPtr);

            return(TryGet(txn, ref keyDb, out value));
        }
示例#10
0
        public bool TryGet(ReadOnlyTransaction txn, ref DirectBuffer key, out DirectBuffer value)
        {
            var keyPtr = AsPointer(ref key);

            value = default;
            var valuePtr = AsPointer(ref value);
            var res      = NativeMethods.AssertRead(NativeMethods.mdb_get((void *)txn._impl.Handle, _handle, keyPtr, valuePtr));

            return(res != NativeMethods.MDB_NOTFOUND);
        }
示例#11
0
        /// <summary>
        /// Iterate over dupsorted values by key.
        /// </summary>
        public IEnumerable <DirectBuffer> AsEnumerable <T>(ReadOnlyTransaction txn, T key)
        {
            var keyPtr    = AsPointer(ref key);
            var keyLength = TypeHelper <T> .EnsureFixedSize();

            var key1        = new DirectBuffer(keyLength, (byte *)keyPtr);
            var fixedMemory = BufferPool.Retain(keyLength, true);

            key1.Span.CopyTo(fixedMemory.Span);
            return(AsEnumerable(txn, fixedMemory));
        }
示例#12
0
        public bool TryGet <TKey, TValue>(ReadOnlyTransaction txn, ref TKey key, out TValue value)
            where TKey : struct where TValue : struct
        {
            EnsureNoRefs <TKey>();
            // EnsureNoRefs<TValue>(); it's called in TryGet below

            var keyPtr = AsPointer(ref key);
            var keyDb  = new DirectBuffer(SizeOf <TKey>(), (nint)keyPtr);

            return(TryGet(txn, ref keyDb, out value));
        }
示例#13
0
        /// <summary>
        /// Iterate over dupsorted values by key.
        /// </summary>
        public IEnumerable <DirectBuffer> AsEnumerable <T>(ReadOnlyTransaction txn, T key)
        {
            EnsureNoRefs <T>();

            var keyPtr      = AsPointer(ref key);
            var keyLength   = SizeOf <T>();
            var key1        = new DirectBuffer(keyLength, (nint)keyPtr);
            var fixedMemory = BufferPool.Retain(keyLength, true);

            key1.Span.CopyTo(fixedMemory.GetSpan());
            return(AsEnumerable(txn, fixedMemory));
        }
示例#14
0
        /// <summary>
        /// Iterate over dupsorted values by key.
        /// </summary>
        public IEnumerable <DirectBuffer> AsEnumerable(ReadOnlyTransaction txn, DirectBuffer key)
        {
            if (((int)OpenFlags & (int)DbFlags.DuplicatesSort) == 0)
            {
                throw new InvalidOperationException("AsEnumerable overload with key parameter should only be provided for dupsorted dbs");
            }

            var fixedMemory = BufferPool.Retain(key.Length, true);

            key.Span.CopyTo(fixedMemory.GetSpan());
            return(AsEnumerable(txn, fixedMemory));
        }
示例#15
0
        public bool TryGet <T>(ReadOnlyTransaction txn, ref DirectBuffer key, out T value)
            where T : struct
        {
            EnsureNoRefs <T>();

            if (TryGet(txn, ref key, out var valueDb))
            {
                value = ReadUnaligned <T>(valueDb.Data);
                return(true);
            }

            value = default;
            return(false);
        }
示例#16
0
        protected SubFingerprintDataDTO GetSubFingerprint(ulong id, Spreads.LMDB.ReadOnlyTransaction transaction)
        {
            var subFingerprintKey = BitConverter.GetBytes(id).AsMemory();

            using (subFingerprintKey.Pin())
            {
                var keyBuffer = new DirectBuffer(subFingerprintKey.Span);
                if (databasesHolder.SubFingerprintsDatabase.TryGet(transaction, ref keyBuffer, out var value))
                {
                    return(MessagePackSerializer.Deserialize <SubFingerprintDataDTO>(value.Span.ToArray(), options: serializerOptions));
                }

                throw new KeyNotFoundException();
            }
        }
示例#17
0
        public bool TryFindDup <TKey, TValue>(ReadOnlyTransaction txn, Lookup direction, ref TKey key, ref TValue value)
            where TKey : struct where TValue : struct
        {
            var keyPtr = AsPointer(ref key);
            var key1   = new DirectBuffer(TypeHelper <TKey> .EnsureFixedSize(), (byte *)keyPtr);

            var valuePtr = AsPointer(ref value);
            var value1   = new DirectBuffer(TypeHelper <TValue> .EnsureFixedSize(), (byte *)valuePtr);

            var res = TryFindDup(txn, direction, ref key1, ref value1);

            if (res)
            {
                key   = ReadUnaligned <TKey>(key1.Data);
                value = ReadUnaligned <TValue>(value1.Data);
                return(true);
            }
            return(false);
        }
示例#18
0
        /// <summary>
        /// Iterate over dupsorted values by key.
        /// </summary>
        public IEnumerable <TValue> AsEnumerable <TKey, TValue>(ReadOnlyTransaction txn, TKey key)
        {
            var keyPtr    = AsPointer(ref key);
            var keyLength = TypeHelper <TKey> .EnsureFixedSize();

            var key1        = new DirectBuffer(keyLength, (byte *)keyPtr);
            var fixedMemory = BufferPool.Retain(keyLength, true);

            key1.Span.CopyTo(fixedMemory.Span);

            return(AsEnumerable(txn, fixedMemory).Select(buf =>
            {
                var valueSize = TypeHelper <TValue> .EnsureFixedSize();
                if (buf.Length != valueSize)
                {
                    throw new InvalidOperationException("Buffer length does not equals to value size");
                }
                return buf.Read <TValue>(0);
            }));
        }
示例#19
0
        /// <summary>
        /// Iterate over db values.
        /// </summary>
        public IEnumerable <KeyValuePair <DirectBuffer, DirectBuffer> > AsEnumerable(ReadOnlyTransaction txn)
        {
            DirectBuffer key   = default;
            DirectBuffer value = default;

            using (var c = OpenReadOnlyCursor(txn))
            {
                if (c.TryGet(ref key, ref value, CursorGetOption.First))
                {
                    yield return(new KeyValuePair <DirectBuffer, DirectBuffer>(key, value));

                    value = default;

                    while (c.TryGet(ref key, ref value, CursorGetOption.NextNoDuplicate))
                    {
                        yield return(new KeyValuePair <DirectBuffer, DirectBuffer>(key, value));

                        value = default;
                    }
                }
            }
        }
示例#20
0
        public bool TryFindDup <TKey, TValue>(ReadOnlyTransaction txn, Lookup direction, ref TKey key, ref TValue value)
            where TKey : struct where TValue : struct
        {
            EnsureNoRefs <TKey>();
            EnsureNoRefs <TValue>();

            var keyPtr = AsPointer(ref key);
            var key1   = new DirectBuffer(SizeOf <TKey>(), (nint)keyPtr);

            var valuePtr = AsPointer(ref value);
            var value1   = new DirectBuffer(SizeOf <TValue>(), (nint)valuePtr);

            var res = TryFindDup(txn, direction, ref key1, ref value1);

            if (res)
            {
                key   = ReadUnaligned <TKey>(key1.Data);
                value = ReadUnaligned <TValue>(value1.Data);
                return(true);
            }
            return(false);
        }
示例#21
0
        public ReadOnlyCursor OpenReadOnlyCursor(ReadOnlyTransaction txn)
        {
            CursorImpl cursorImpl;

            if (txn._impl.IsReadOnly)
            {
                cursorImpl = ReadCursorPool.Rent();
                if (cursorImpl == null)
                {
                    cursorImpl = CursorImpl.Create(this, txn._impl, true);
                }
                else
                {
                    cursorImpl.Renew(txn._impl);
                }
            }
            else
            {
                cursorImpl = CursorImpl.Create(this, txn._impl, true);
            }
            return(new ReadOnlyCursor(cursorImpl));
        }
示例#22
0
        protected IEnumerable <SubFingerprintDataDTO> GetSubFingerprintsForTrack(ulong id, Spreads.LMDB.ReadOnlyTransaction transaction)
        {
            var trackKey = BitConverter.GetBytes(id).AsMemory();
            var list     = new List <SubFingerprintDataDTO>();

            using (trackKey.Pin())
                using (var cursor = indexesHolder.TracksSubfingerprintsIndex.OpenReadOnlyCursor(transaction))
                {
                    var keyBuffer   = new DirectBuffer(trackKey.Span);
                    var valueBuffer = default(DirectBuffer);
                    if (cursor.TryGet(ref keyBuffer, ref valueBuffer, CursorGetOption.Set) &&
                        cursor.TryGet(ref keyBuffer, ref valueBuffer, CursorGetOption.FirstDuplicate))
                    {
                        var subFingerprintId = valueBuffer.ReadUInt64(0);
                        list.Add(GetSubFingerprint(subFingerprintId, transaction));

                        while (cursor.TryGet(ref keyBuffer, ref valueBuffer, CursorGetOption.NextDuplicate))
                        {
                            subFingerprintId = valueBuffer.ReadUInt64(0);
                            list.Add(GetSubFingerprint(subFingerprintId, transaction));
                        }
                    }
                }
            return(list);
        }
示例#23
0
        protected Span <ulong> GetSubFingerprintsByHashTableAndHash(int table, int hash, Spreads.LMDB.ReadOnlyTransaction transaction)
        {
            var tableDatabase = databasesHolder.HashTables[table];
            var key           = hash;
            var value         = default(ulong);

            ulong[] buffer = null;

            using (var cursor = tableDatabase.OpenReadOnlyCursor(transaction))
            {
                if (cursor.TryGet(ref key, ref value, CursorGetOption.Set) &&
                    cursor.TryGet(ref key, ref value, CursorGetOption.FirstDuplicate))
                {
                    var counter = 0;
                    buffer          = new ulong[cursor.Count()];
                    buffer[counter] = value;

                    while (cursor.TryGet(ref key, ref value, CursorGetOption.NextDuplicate))
                    {
                        counter++;
                        buffer[counter] = value;
                    }

                    if (counter != (buffer.Length - 1))
                    {
                        throw new BadBufferLengthException("Bad buffer length");
                    }
                }
            }

#pragma warning disable RCS1084 // Use coalesce expression instead of conditional expression.
#pragma warning disable IDE0029 // Use coalesce expression
            return(buffer != null ? buffer : new Span <ulong>());

#pragma warning restore IDE0029 // Use coalesce expression
#pragma warning restore RCS1084 // Use coalesce expression instead of conditional expression.
        }
示例#24
0
        /// <summary>
        /// Iterate over db values.
        /// </summary>
        public IEnumerable <KeyValuePair <TKey, TValue> > AsEnumerable <TKey, TValue>(ReadOnlyTransaction txn)
        {
            EnsureNoRefs <TKey>();
            EnsureNoRefs <TValue>();

            var keySize   = SizeOf <TKey>();
            var valueSize = SizeOf <TValue>();

            return(AsEnumerable(txn).Select(kvp =>
            {
                if (kvp.Key.Length != keySize)
                {
                    throw new InvalidOperationException("Key buffer length does not equals to key size");
                }

                if (kvp.Value.Length != valueSize)
                {
                    throw new InvalidOperationException("Value buffer length does not equals to value size");
                }
                return new KeyValuePair <TKey, TValue>(kvp.Key.Read <TKey>(0), kvp.Value.Read <TValue>(0));
            }));
        }