コード例 #1
0
        public bool Upsert(T obj)
        {
            Debug.Assert(typeof(T) == obj.GetType(), AssertNotDerivedTypesMsg);

            var keyBytes   = KeyBytes(obj);
            var valueBytes = ValueBytes(obj);

            ResetKeyPrefix();
            if (_kvtr.Find(keyBytes) == FindResult.Exact)
            {
                var oldValueBytes = _kvtr.GetValue();

                _kvtr.CreateOrUpdateKeyValue(keyBytes, valueBytes);

                if (_hasSecondaryIndexes)
                {
                    UpdateSecondaryIndexes(obj, keyBytes, oldValueBytes);
                }

                FreeContentInUpdate(oldValueBytes, valueBytes);
                return(false);
            }

            _kvtr.CreateOrUpdateKeyValue(keyBytes, valueBytes);
            if (_hasSecondaryIndexes)
            {
                AddIntoSecondaryIndexes(obj);
            }
            _modificationCounter.MarkModification();
            return(true);
        }
コード例 #2
0
 /// <summary>
 /// Writes all key value pairs in current prefix to stream (prefix itself is not written)
 /// </summary>
 /// <param name="transaction">transaction from where export all data</param>
 /// <param name="stream">where to write it to</param>
 public static void Export(IKeyValueDBTransaction transaction, Stream stream)
 {
     if (transaction == null) throw new ArgumentNullException(nameof(transaction));
     if (stream == null) throw new ArgumentNullException(nameof(stream));
     if (!stream.CanWrite) throw new ArgumentException("stream must be writeable", nameof(stream));
     var keyValueCount = transaction.GetKeyValueCount();
     var tempbuf = new byte[16];
     tempbuf[0] = (byte)'B';
     tempbuf[1] = (byte)'T';
     tempbuf[2] = (byte)'D';
     tempbuf[3] = (byte)'B';
     tempbuf[4] = (byte)'E';
     tempbuf[5] = (byte)'X';
     tempbuf[6] = (byte)'P';
     tempbuf[7] = (byte)'2';
     PackUnpack.PackInt64LE(tempbuf, 8, keyValueCount);
     stream.Write(tempbuf, 0, 16);
     transaction.FindFirstKey();
     for (long kv = 0; kv < keyValueCount; kv++)
     {
         var key = transaction.GetKey();
         PackUnpack.PackInt32LE(tempbuf, 0, key.Length);
         stream.Write(tempbuf, 0, 4);
         stream.Write(key.Buffer, key.Offset, key.Length);
         var value = transaction.GetValue();
         PackUnpack.PackInt32LE(tempbuf, 0, value.Length);
         stream.Write(tempbuf, 0, 4);
         stream.Write(value.Buffer, value.Offset, value.Length);
         transaction.FindNextKey();
     }
 }
コード例 #3
0
        /// <summary>
        /// Writes all key value pairs in current prefix to stream (prefix itself is not written)
        /// </summary>
        /// <param name="transaction">transaction from where export all data</param>
        /// <param name="stream">where to write it to</param>
        public static void Export(IKeyValueDBTransaction transaction, Stream stream)
        {
            if (transaction == null)
            {
                throw new ArgumentNullException(nameof(transaction));
            }
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }
            if (!stream.CanWrite)
            {
                throw new ArgumentException("stream must be writeable", nameof(stream));
            }
            var keyValueCount = transaction.GetKeyValueCount();
            var tempbuf       = new byte[16];

            tempbuf[0] = (byte)'B';
            tempbuf[1] = (byte)'T';
            tempbuf[2] = (byte)'D';
            tempbuf[3] = (byte)'B';
            tempbuf[4] = (byte)'E';
            tempbuf[5] = (byte)'X';
            tempbuf[6] = (byte)'P';
            tempbuf[7] = (byte)'2';
            PackUnpack.PackInt64LE(tempbuf, 8, keyValueCount);
            stream.Write(tempbuf, 0, 16);
            transaction.FindFirstKey(new ReadOnlySpan <byte>());
            Span <byte> keyBuffer = stackalloc byte[256];

            for (long kv = 0; kv < keyValueCount; kv++)
            {
                var key = transaction.GetKey(ref MemoryMarshal.GetReference(keyBuffer), keyBuffer.Length);
                PackUnpack.PackInt32LE(tempbuf, 0, key.Length);
                stream.Write(tempbuf, 0, 4);
                stream.Write(key);
                var value = transaction.GetValue();
                PackUnpack.PackInt32LE(tempbuf, 0, value.Length);
                stream.Write(tempbuf, 0, 4);
                stream.Write(value);
                transaction.FindNextKey(new ReadOnlySpan <byte>());
            }
            var ulongCount = transaction.GetUlongCount();

            if (transaction.GetCommitUlong() != 0 || ulongCount != 0)
            {
                PackUnpack.PackUInt64LE(tempbuf, 0, transaction.GetCommitUlong());
                stream.Write(tempbuf, 0, 8);
            }
            if (ulongCount != 0)
            {
                PackUnpack.PackUInt32LE(tempbuf, 0, ulongCount);
                stream.Write(tempbuf, 0, 4);
                for (var i = 0u; i < ulongCount; i++)
                {
                    PackUnpack.PackUInt64LE(tempbuf, 0, transaction.GetUlong(i));
                    stream.Write(tempbuf, 0, 8);
                }
            }
        }
コード例 #4
0
ファイル: ODBIterator.cs プロジェクト: yardee/BTDB
        public void LoadGlobalInfo(bool sortTableByNameAsc = false)
        {
            LoadTableNamesDict();
            LoadRelationInfoDict();
            MarkLastDictId();
            _trkv.InvalidateCurrentKey();
            _singletons = new Dictionary <uint, ulong>();
            while (_trkv.FindNextKey(ObjectDB.TableSingletonsPrefix))
            {
                _singletons.Add(new SpanReader(_trkv.GetKey().Slice((int)ObjectDB.TableSingletonsPrefixLen)).ReadVUInt32(), new SpanReader(_trkv.GetValue()).ReadVUInt64());
            }

            if (sortTableByNameAsc)
            {
                _singletons = _singletons.OrderBy(item => _tableId2Name.TryGetValue(item.Key, out var name) ? name : "").ToDictionary(item => item.Key, item => item.Value);
            }
        }
コード例 #5
0
ファイル: RelationEnumerator.cs プロジェクト: wikancz/BTDB
        protected virtual T CreateInstance(ByteBuffer keyBytes)
        {
            var writer = new ByteBufferWriter();

            writer.WriteBlock(_keyBytes.Buffer, _keyBytes.Offset + _lengthOfNonDataPrefix, _keyBytes.Length - _lengthOfNonDataPrefix);
            writer.WriteBlock(keyBytes);

            return((T)_manipulator.RelationInfo.CreateInstance(_tr, writer.Data, _keyValueTr.GetValue(), false));
        }
コード例 #6
0
ファイル: ObjectDB.cs プロジェクト: lanicon/BTDB
 internal static IEnumerable <KeyValuePair <uint, string> > LoadTablesEnum(IKeyValueDBTransaction tr)
 {
     tr.InvalidateCurrentKey();
     while (tr.FindNextKey(TableNamesPrefix))
     {
         yield return(new KeyValuePair <uint, string>(
                          (uint)PackUnpack.UnpackVUInt(tr.GetKey().Slice(TableNamesPrefixLen)),
                          new SpanReader(tr.GetValue()).ReadString()));
     }
 }
コード例 #7
0
        protected virtual T CreateInstance(ByteBuffer keyBytes)
        {
            var data = new byte[_keyBytes.Length - _lengthOfNonDataPrefix + keyBytes.Length];

            Array.Copy(_keyBytes.Buffer, _keyBytes.Offset + _lengthOfNonDataPrefix, data, 0,
                       _keyBytes.Length - _lengthOfNonDataPrefix);
            Array.Copy(keyBytes.Buffer, keyBytes.Offset, data, _keyBytes.Length - _lengthOfNonDataPrefix,
                       keyBytes.Length);

            return((T)ItemLoader.CreateInstance(_tr, ByteBuffer.NewAsync(data), _keyValueTr.GetValue()));
        }
コード例 #8
0
        protected virtual TValue CreateInstance(ByteBuffer prefixKeyBytes, ByteBuffer keyBytes)
        {
            var data = new byte[_keyBytes.Length - _lengthOfNonDataPrefix + keyBytes.Length];

            Array.Copy(_keyBytes.Buffer, _keyBytes.Offset + _lengthOfNonDataPrefix, data, 0,
                       _keyBytes.Length - _lengthOfNonDataPrefix);
            Array.Copy(keyBytes.Buffer, keyBytes.Offset, data, _keyBytes.Length - _lengthOfNonDataPrefix,
                       keyBytes.Length);

            return((TValue)_manipulator.RelationInfo.CreateInstance(_tr, ByteBuffer.NewAsync(data),
                                                                    _keyValueTr.GetValue(), false));
        }
コード例 #9
0
        /// <summary>
        /// Writes all key value pairs in current prefix to stream (prefix itself is not written)
        /// </summary>
        /// <param name="transaction">transaction from where export all data</param>
        /// <param name="stream">where to write it to</param>
        public static void Export(IKeyValueDBTransaction transaction, Stream stream)
        {
            if (transaction == null)
            {
                throw new ArgumentNullException(nameof(transaction));
            }
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }
            if (!stream.CanWrite)
            {
                throw new ArgumentException("stream must be writeable", nameof(stream));
            }
            var keyValueCount = transaction.GetKeyValueCount();
            var tempbuf       = new byte[16];

            tempbuf[0] = (byte)'B';
            tempbuf[1] = (byte)'T';
            tempbuf[2] = (byte)'D';
            tempbuf[3] = (byte)'B';
            tempbuf[4] = (byte)'E';
            tempbuf[5] = (byte)'X';
            tempbuf[6] = (byte)'P';
            tempbuf[7] = (byte)'2';
            PackUnpack.PackInt64LE(tempbuf, 8, keyValueCount);
            stream.Write(tempbuf, 0, 16);
            transaction.FindFirstKey();
            for (long kv = 0; kv < keyValueCount; kv++)
            {
                var key = transaction.GetKey();
                PackUnpack.PackInt32LE(tempbuf, 0, key.Length);
                stream.Write(tempbuf, 0, 4);
                stream.Write(key.Buffer, key.Offset, key.Length);
                var value = transaction.GetValue();
                PackUnpack.PackInt32LE(tempbuf, 0, value.Length);
                stream.Write(tempbuf, 0, 4);
                stream.Write(value.Buffer, value.Offset, value.Length);
                transaction.FindNextKey();
            }
            if (transaction.GetCommitUlong() != 0)
            {
                PackUnpack.PackUInt64LE(tempbuf, 0, transaction.GetCommitUlong());
                stream.Write(tempbuf, 0, 8);
            }
        }
コード例 #10
0
ファイル: KeyValueDBValueReader.cs プロジェクト: srsman/BTDB
 public KeyValueDBValueReader(IKeyValueDBTransaction transaction) : base(transaction.GetValue())
 {
     _transaction = transaction;
 }
コード例 #11
0
ファイル: KeyValueDBValueReader.cs プロジェクト: srsman/BTDB
 public void Restart()
 {
     Restart(_transaction.GetValue());
 }
コード例 #12
0
ファイル: ODBDictionary.cs プロジェクト: Waizik/BTDB
        void FreeContent(IReaderCtx readerCtx, int cfgId)
        {
            var config = ODBDictionaryConfiguration.Get(cfgId);
            var ctx    = (DBReaderWithFreeInfoCtx)readerCtx;

            if (config.FreeContent == null)
            {
                var method      = ILBuilder.Instance.NewMethod <FreeContentFun>($"IDictFinder_Cfg_{cfgId}");
                var ilGenerator = method.Generator;

                var readerLoc = ilGenerator.DeclareLocal(typeof(IReaderCtx));
                ilGenerator
                .Ldarg(0)
                .Ldarg(2)
                // ReSharper disable once ObjectCreationAsStatement
                .Newobj(() => new DBReaderWithFreeInfoCtx(null, null))
                .Stloc(readerLoc);

                var readerOrCtx = _valueHandler.NeedsCtx() ? (Action <IILGen>?)(il => il.Ldloc(readerLoc)) : null;
                _valueHandler.FreeContent(ilGenerator, il => il.Ldarg(1), readerOrCtx);
                ilGenerator.Ret();
                config.FreeContent = method.Create();
            }

            var findIDictAction = (FreeContentFun)config.FreeContent;

            long prevProtectionCounter = 0;
            long pos = 0;

            while (true)
            {
                if (pos == 0)
                {
                    if (!_keyValueTr.FindFirstKey(_prefix))
                    {
                        break;
                    }
                }
                else
                {
                    if (_keyValueTr.CursorMovedCounter != prevProtectionCounter)
                    {
                        if (!_keyValueTr.SetKeyIndex(_prefix, pos))
                        {
                            break;
                        }
                    }
                    else
                    {
                        if (!_keyValueTr.FindNextKey(_prefix))
                        {
                            break;
                        }
                    }
                }

                prevProtectionCounter = _keyValueTr.CursorMovedCounter;
                var valueBytes  = _keyValueTr.GetValue();
                var valueReader = new SpanReader(valueBytes);
                findIDictAction(ctx.GetTransaction(), ref valueReader, ctx.DictIds);

                pos++;
            }
        }
コード例 #13
0
 public ByteBuffer GetValue()
 {
     return(_keyValueDBTransaction.GetValue());
 }
コード例 #14
0
ファイル: KeyValueDBValueReader.cs プロジェクト: Xamarui/BTDB
 public KeyValueDBValueReader(IKeyValueDBTransaction transaction):base(transaction.GetValue())
 {
     _transaction = transaction;
 }
コード例 #15
0
ファイル: ExtensionMethods.cs プロジェクト: wikancz/BTDB
 public static byte[] GetValueAsByteArray(this IKeyValueDBTransaction transaction)
 {
     return(transaction.GetValue().ToByteArray());
 }