Beispiel #1
0
 internal RelationInfo CreateByName(IInternalObjectDBTransaction tr, string name, Type interfaceType)
 {
     name = string.Intern(name);
     uint id;
     if (!_name2Id.TryGetValue(name, out id))
     {
         id = _freeId++;
         _name2Id[name] = id;
         tr.KeyValueDBTransaction.SetKeyPrefixUnsafe(ObjectDB.RelationNamesPrefix);
         var nameWriter = new ByteBufferWriter();
         nameWriter.WriteString(name);
         var idWriter = new ByteBufferWriter();
         idWriter.WriteVUInt32(id);
         tr.KeyValueDBTransaction.CreateOrUpdateKeyValue(nameWriter.Data, idWriter.Data);
     }
     RelationInfo relation;
     if (_id2Relation.TryGetValue(id, out relation))
     {
         throw new BTDBException($"Relation with name '{name}' was already initialized");
     }
     var clientType = FindClientType(interfaceType);
     relation = new RelationInfo(id, name, _relationInfoResolver, interfaceType, clientType, tr);
     _id2Relation[id] = relation;
     return relation;
 }
Beispiel #2
0
        public object CreateInstance(IInternalObjectDBTransaction tr, ByteBuffer keyBytes, ByteBuffer valueBytes,
                                     bool keyContainsRelationIndex = true)
        {
            var obj       = Creator(tr);
            var keyReader = new ByteBufferReader(keyBytes);

            if (keyContainsRelationIndex)
            {
                keyReader.SkipVUInt32(); //index Relation
            }
            GetPrimaryKeysLoader(ClientTypeVersion)(tr, keyReader, obj);
            var valueReader = new ByteBufferReader(valueBytes);
            var version     = valueReader.ReadVUInt32();

            GetValueLoader(version)(tr, valueReader, obj);
            return(obj);
        }
Beispiel #3
0
        public RelationEnumerator(IInternalObjectDBTransaction tr, RelationInfo relationInfo, ByteBuffer keyBytes,
                                  IRelationModificationCounter modificationCounter)
        {
            RelationInfo = relationInfo;
            Transaction  = tr;

            _keyValueTr            = Transaction.KeyValueDBTransaction;
            _keyValueTrProtector   = Transaction.TransactionProtector;
            _prevProtectionCounter = _keyValueTrProtector.ProtectionCounter;

            KeyBytes             = keyBytes;
            _modificationCounter = modificationCounter;
            _keyValueTrProtector.Start();
            _keyValueTr.SetKeyPrefix(KeyBytes);
            _pos        = 0;
            _seekNeeded = true;
            _prevModificationCounter = _modificationCounter.ModificationCounter;
        }
Beispiel #4
0
        public ODBDictionary(IInternalObjectDBTransaction tr, ODBDictionaryConfiguration config, ulong id)
        {
            _tr           = tr;
            _keyHandler   = config.KeyHandler;
            _valueHandler = config.ValueHandler;
            _id           = id;
            var o = ObjectDB.AllDictionariesPrefix.Length;

            _prefix = new byte[o + PackUnpack.LengthVUInt(_id)];
            Array.Copy(ObjectDB.AllDictionariesPrefix, _prefix, o);
            PackUnpack.PackVUInt(_prefix, ref o, _id);
            _keyReader           = ((Func <AbstractBufferedReader, IReaderCtx, TKey>)config.KeyReader) !;
            _keyWriter           = ((Action <TKey, AbstractBufferedWriter, IWriterCtx>)config.KeyWriter) !;
            _valueReader         = ((Func <AbstractBufferedReader, IReaderCtx, TValue>)config.ValueReader) !;
            _valueWriter         = ((Action <TValue, AbstractBufferedWriter, IWriterCtx>)config.ValueWriter) !;
            _keyValueTr          = _tr.KeyValueDBTransaction;
            _keyValueTrProtector = _tr.TransactionProtector;
            _count = -1;
        }
Beispiel #5
0
        // ReSharper disable once MemberCanBePrivate.Global used by FieldHandler.Load
        public ODBDictionary(IInternalObjectDBTransaction tr, ODBDictionaryConfiguration config, ulong id)
        {
            _tr           = tr;
            _keyHandler   = config.KeyHandler !;
            _valueHandler = config.ValueHandler !;
            _id           = id;
            var len    = PackUnpack.LengthVUInt(id);
            var prefix = new byte[ObjectDB.AllDictionariesPrefixLen + len];

            MemoryMarshal.GetReference(prefix.AsSpan()) = ObjectDB.AllDictionariesPrefixByte;
            PackUnpack.UnsafePackVUInt(ref Unsafe.AddByteOffset(ref MemoryMarshal.GetReference(prefix.AsSpan()), (IntPtr)ObjectDB.AllDictionariesPrefixLen), id, len);
            _prefix      = prefix;
            _keyReader   = ((ReaderFun <TKey>)config.KeyReader) !;
            _keyWriter   = ((WriterFun <TKey>)config.KeyWriter) !;
            _valueReader = ((ReaderFun <TValue>)config.ValueReader) !;
            _valueWriter = ((WriterFun <TValue>)config.ValueWriter) !;
            _keyValueTr  = _tr.KeyValueDBTransaction;
            _count       = -1;
        }
Beispiel #6
0
        void CalculateSecondaryKey(IInternalObjectDBTransaction tr, IList <KeyValuePair <uint, SecondaryKeyInfo> > indexes)
        {
            var keyWriter = new ByteBufferWriter();

            var enumeratorType = typeof(RelationEnumerator <>).MakeGenericType(_clientType);

            keyWriter.WriteByteArrayRaw(ObjectDB.AllRelationsPKPrefix);
            keyWriter.WriteVUInt32(Id);
            var enumerator = (IEnumerator)Activator.CreateInstance(enumeratorType, tr, this, keyWriter.GetDataAndRewind().ToAsyncSafe(), new SimpleModificationCounter());

            var keySavers = new Action <IInternalObjectDBTransaction, AbstractBufferedWriter, object> [indexes.Count];

            for (int i = 0; i < indexes.Count; i++)
            {
                keySavers[i] = CreateSaver(ClientRelationVersionInfo.GetSecondaryKeyFields(indexes[i].Key),
                                           $"Relation_{Name}_Upgrade_SK_{indexes[i].Value.Name}_KeySaver");
            }

            while (enumerator.MoveNext())
            {
                var obj = enumerator.Current;

                tr.TransactionProtector.Start();
                tr.KeyValueDBTransaction.SetKeyPrefix(ObjectDB.AllRelationsSKPrefix);

                for (int i = 0; i < indexes.Count; i++)
                {
                    keyWriter.WriteVUInt32(Id);
                    keyWriter.WriteVUInt32(indexes[i].Key);
                    keySavers[i](tr, keyWriter, obj);
                    var keyBytes = keyWriter.GetDataAndRewind();

                    if (!tr.KeyValueDBTransaction.CreateOrUpdateKeyValue(keyBytes, ByteBuffer.NewEmpty()))
                    {
                        throw new BTDBException("Internal error, secondary key bytes must be always unique.");
                    }
                }
            }
        }
Beispiel #7
0
        void UpdateSecondaryKeys(IInternalObjectDBTransaction tr, RelationVersionInfo info, RelationVersionInfo previousInfo)
        {
            foreach (var prevIdx in previousInfo.SecondaryKeys.Keys)
            {
                if (!info.SecondaryKeys.ContainsKey(prevIdx))
                {
                    DeleteSecondaryKey(tr.KeyValueDBTransaction, prevIdx);
                }
            }
            var secKeysToAdd = new List <KeyValuePair <uint, SecondaryKeyInfo> >();

            foreach (var sk in info.SecondaryKeys)
            {
                if (!previousInfo.SecondaryKeys.ContainsKey(sk.Key))
                {
                    secKeysToAdd.Add(sk);
                }
            }
            if (secKeysToAdd.Count > 0)
            {
                CalculateSecondaryKey(tr, secKeysToAdd);
            }
        }
Beispiel #8
0
        public RelationInfo(uint id, string name, IRelationInfoResolver relationInfoResolver, Type interfaceType,
                            Type clientType, IInternalObjectDBTransaction tr)
        {
            _id   = id;
            _name = name;
            _relationInfoResolver     = relationInfoResolver;
            _interfaceType            = interfaceType;
            _clientType               = clientType;
            ClientRelationVersionInfo = CreateVersionInfoByReflection();
            LoadVersionInfos(tr.KeyValueDBTransaction);
            ApartFields = FindApartFields(interfaceType, ClientRelationVersionInfo);
            if (LastPersistedVersion > 0 && RelationVersionInfo.Equal(_relationVersions[LastPersistedVersion], ClientRelationVersionInfo))
            {
                _relationVersions[LastPersistedVersion] = ClientRelationVersionInfo;
                ClientTypeVersion = LastPersistedVersion;
            }
            else
            {
                ClientTypeVersion = LastPersistedVersion + 1;
                _relationVersions.Add(ClientTypeVersion, ClientRelationVersionInfo);
                var writerk = new ByteBufferWriter();
                writerk.WriteByteArrayRaw(ObjectDB.RelationVersionsPrefix);
                writerk.WriteVUInt32(_id);
                writerk.WriteVUInt32(ClientTypeVersion);
                var writerv = new ByteBufferWriter();
                ClientRelationVersionInfo.Save(writerv);
                tr.KeyValueDBTransaction.SetKeyPrefix(ByteBuffer.NewEmpty());
                tr.KeyValueDBTransaction.CreateOrUpdateKeyValue(writerk.Data, writerv.Data);

                if (LastPersistedVersion > 0)
                {
                    CheckThatPrimaryKeyHasNotChanged(name, ClientRelationVersionInfo, _relationVersions[LastPersistedVersion]);
                    UpdateSecondaryKeys(tr, ClientRelationVersionInfo, _relationVersions[LastPersistedVersion]);
                }
            }
            _typeConvertorGenerator = tr.Owner.TypeConvertorGenerator;
        }
Beispiel #9
0
        internal RelationInfo CreateByName(IInternalObjectDBTransaction tr, string name, Type interfaceType,
                                           RelationBuilder builder)
        {
            name = string.Intern(name);
            if (!_name2Id.TryGetValue(name, out var id))
            {
                id             = _freeId++;
                _name2Id[name] = id;
                var nameWriter = new SpanWriter();
                nameWriter.WriteBlock(ObjectDB.RelationNamesPrefix);
                nameWriter.WriteString(name);
                var idWriter = new SpanWriter();
                idWriter.WriteVUInt32(id);
                tr.KeyValueDBTransaction.CreateOrUpdateKeyValue(nameWriter.GetSpan(), idWriter.GetSpan());
            }

            if (_id2Relation.TryGetValue(id, out var relation))
            {
                throw new BTDBException($"Relation with name '{name}' was already initialized");
            }
            relation         = new RelationInfo(id, name, builder, tr);
            _id2Relation[id] = relation;
            return(relation);
        }
Beispiel #10
0
 public RelationPrimaryKeyEnumerator(IInternalObjectDBTransaction tr, RelationInfo relationInfo, ByteBuffer keyBytes,
                                     RelationDBManipulator <T> manipulator)
     : base(tr, relationInfo, keyBytes, manipulator)
 {
     _skipBytes = relationInfo.Prefix.Length;
 }
Beispiel #11
0
 public RelationDBManipulator(IObjectDBTransaction transation, RelationInfo relationInfo)
 {
     _transaction         = (IInternalObjectDBTransaction)transation;
     _relationInfo        = relationInfo;
     _modificationCounter = _transaction.GetRelationModificationCounter(relationInfo.Id);
 }
Beispiel #12
0
 public DBWriterCtx(IInternalObjectDBTransaction transaction)
 {
     _transaction = transaction;
 }
Beispiel #13
0
        public RelationAdvancedOrderedEnumerator(IRelationDbManipulator manipulator,
                                                 ByteBuffer prefixBytes, uint prefixFieldCount,
                                                 EnumerationOrder order,
                                                 KeyProposition startKeyProposition, ByteBuffer startKeyBytes,
                                                 KeyProposition endKeyProposition, ByteBuffer endKeyBytes, bool initKeyReader, int loaderIndex)
        {
            _prefixFieldCount = prefixFieldCount;
            _manipulator      = manipulator;
            ItemLoader        = _manipulator.RelationInfo.ItemLoaderInfos[loaderIndex];
            _tr        = manipulator.Transaction;
            _ascending = order == EnumerationOrder.Ascending;

            _keyValueTr            = _tr.KeyValueDBTransaction;
            _keyValueTrProtector   = _tr.TransactionProtector;
            _prevProtectionCounter = _keyValueTrProtector.ProtectionCounter;

            _keyBytes = prefixBytes;
            if (endKeyProposition == KeyProposition.Included)
            {
                endKeyBytes = RelationAdvancedEnumerator <TValue> .FindLastKeyWithPrefix(_keyBytes, endKeyBytes,
                                                                                         _keyValueTr, _keyValueTrProtector);
            }

            _keyValueTrProtector.Start();
            _keyValueTr.SetKeyPrefix(_keyBytes);

            long startIndex;
            long endIndex;

            if (endKeyProposition == KeyProposition.Ignored)
            {
                endIndex = _keyValueTr.GetKeyValueCount() - 1;
            }
            else
            {
                switch (_keyValueTr.Find(endKeyBytes))
                {
                case FindResult.Exact:
                    endIndex = _keyValueTr.GetKeyIndex();
                    if (endKeyProposition == KeyProposition.Excluded)
                    {
                        endIndex--;
                    }

                    break;

                case FindResult.Previous:
                    endIndex = _keyValueTr.GetKeyIndex();
                    break;

                case FindResult.Next:
                    endIndex = _keyValueTr.GetKeyIndex() - 1;
                    break;

                case FindResult.NotFound:
                    endIndex = -1;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            if (startKeyProposition == KeyProposition.Ignored)
            {
                startIndex = 0;
            }
            else
            {
                switch (_keyValueTr.Find(startKeyBytes))
                {
                case FindResult.Exact:
                    startIndex = _keyValueTr.GetKeyIndex();
                    if (startKeyProposition == KeyProposition.Excluded)
                    {
                        startIndex++;
                    }

                    break;

                case FindResult.Previous:
                    startIndex = _keyValueTr.GetKeyIndex() + 1;
                    break;

                case FindResult.Next:
                    startIndex = _keyValueTr.GetKeyIndex();
                    break;

                case FindResult.NotFound:
                    startIndex = 0;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            _count     = (uint)Math.Max(0, endIndex - startIndex + 1);
            _startPos  = (uint)(_ascending ? startIndex : endIndex);
            _pos       = 0;
            _seekState = SeekState.Undefined;

            if (initKeyReader)
            {
                var primaryKeyFields       = manipulator.RelationInfo.ClientRelationVersionInfo.GetPrimaryKeyFields();
                var advancedEnumParamField = primaryKeyFields[(int)_prefixFieldCount];
                if (advancedEnumParamField.Handler.NeedsCtx())
                {
                    throw new BTDBException("Not supported.");
                }
                _keyReader = (Func <AbstractBufferedReader, IReaderCtx, TKey>)manipulator.RelationInfo
                             .GetSimpleLoader(new RelationInfo.SimpleLoaderType(advancedEnumParamField.Handler, typeof(TKey)));

                _lengthOfNonDataPrefix = manipulator.RelationInfo.Prefix.Length;
            }
        }
Beispiel #14
0
 public RelationPrimaryKeyEnumerator(IInternalObjectDBTransaction tr, RelationInfo relationInfo,
                                     ByteBuffer keyBytes, IRelationModificationCounter modificationCounter, int loaderIndex)
     : base(tr, relationInfo, keyBytes, modificationCounter, loaderIndex)
 {
     _skipBytes = relationInfo.Prefix.Length;
 }
Beispiel #15
0
 public DBWriterCtx(IInternalObjectDBTransaction transaction, AbstractBufferedWriter writer)
 {
     _transaction = transaction;
     _writer      = writer;
 }
Beispiel #16
0
 public DBReaderCtx(IInternalObjectDBTransaction transaction, AbstractBufferedReader reader)
 {
     _transaction = transaction;
     _reader = reader;
     _lastIdOfObj = -1;
 }
Beispiel #17
0
 public DBReaderCtx(IInternalObjectDBTransaction transaction)
 {
     _transaction = transaction;
     _reader = null;
     _lastIdOfObj = -1;
 }
Beispiel #18
0
 public RelationDBManipulator(IObjectDBTransaction transation, RelationInfo relationInfo)
 {
     _transaction  = (IInternalObjectDBTransaction)transation;
     _relationInfo = relationInfo;
 }
Beispiel #19
0
 public RelationPrimaryKeyEnumerator(IInternalObjectDBTransaction tr, RelationInfo relationInfo,
                                     in ReadOnlySpan <byte> keyBytes, IRelationModificationCounter modificationCounter, int loaderIndex)
Beispiel #20
0
 public DBWriterCtx(IInternalObjectDBTransaction transaction, AbstractBufferedWriter writer)
 {
     _transaction = transaction;
     _writer = writer;
 }
Beispiel #21
0
 public DBReaderCtx(IInternalObjectDBTransaction transaction, AbstractBufferedReader reader)
 {
     _transaction = transaction;
     _reader      = reader;
     _lastIdOfObj = -1;
 }
Beispiel #22
0
        public RelationAdvancedEnumerator(
            IRelationDbManipulator manipulator,
            ByteBuffer prefixBytes, uint prefixFieldCount,
            EnumerationOrder order,
            KeyProposition startKeyProposition, ByteBuffer startKeyBytes,
            KeyProposition endKeyProposition, ByteBuffer endKeyBytes, int loaderIndex)
        {
            _prefixFieldCount = prefixFieldCount;
            _manipulator      = manipulator;
            ItemLoader        = _manipulator.RelationInfo.ItemLoaderInfos[loaderIndex];

            _ascending = order == EnumerationOrder.Ascending;

            _tr                    = manipulator.Transaction;
            _keyValueTr            = _tr.KeyValueDBTransaction;
            _keyValueTrProtector   = _tr.TransactionProtector;
            _prevProtectionCounter = _keyValueTrProtector.ProtectionCounter;

            _keyBytes = prefixBytes;
            if (endKeyProposition == KeyProposition.Included)
            {
                endKeyBytes = FindLastKeyWithPrefix(_keyBytes, endKeyBytes, _keyValueTr, _keyValueTrProtector);
            }

            _keyValueTrProtector.Start();
            _keyValueTr.SetKeyPrefix(_keyBytes);

            _prevModificationCounter = manipulator.ModificationCounter.ModificationCounter;

            long startIndex;
            long endIndex;

            if (endKeyProposition == KeyProposition.Ignored)
            {
                endIndex = _keyValueTr.GetKeyValueCount() - 1;
            }
            else
            {
                switch (_keyValueTr.Find(endKeyBytes))
                {
                case FindResult.Exact:
                    endIndex = _keyValueTr.GetKeyIndex();
                    if (endKeyProposition == KeyProposition.Excluded)
                    {
                        endIndex--;
                    }

                    break;

                case FindResult.Previous:
                    endIndex = _keyValueTr.GetKeyIndex();
                    break;

                case FindResult.Next:
                    endIndex = _keyValueTr.GetKeyIndex() - 1;
                    break;

                case FindResult.NotFound:
                    endIndex = -1;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            if (startKeyProposition == KeyProposition.Ignored)
            {
                startIndex = 0;
            }
            else
            {
                switch (_keyValueTr.Find(startKeyBytes))
                {
                case FindResult.Exact:
                    startIndex = _keyValueTr.GetKeyIndex();
                    if (startKeyProposition == KeyProposition.Excluded)
                    {
                        startIndex++;
                    }

                    break;

                case FindResult.Previous:
                    startIndex = _keyValueTr.GetKeyIndex() + 1;
                    break;

                case FindResult.Next:
                    startIndex = _keyValueTr.GetKeyIndex();
                    break;

                case FindResult.NotFound:
                    startIndex = 0;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            _count                 = (uint)Math.Max(0, endIndex - startIndex + 1);
            _startPos              = (uint)(_ascending ? startIndex : endIndex);
            _pos                   = 0;
            _seekNeeded            = true;
            _lengthOfNonDataPrefix = manipulator.RelationInfo.Prefix.Length;
        }
Beispiel #23
0
 public DBReaderCtx(IInternalObjectDBTransaction transaction)
 {
     _transaction = transaction;
     _reader      = null;
     _lastIdOfObj = -1;
 }
Beispiel #24
0
 // ReSharper disable once UnusedMember.Global
 public ODBSet(IInternalObjectDBTransaction tr, ODBDictionaryConfiguration config) : this(tr, config,
                                                                                          tr.AllocateDictionaryId())
 {
 }
Beispiel #25
0
 public DBWriterCtx(IInternalObjectDBTransaction transaction, AbstractBufferedWriter writer, bool preferInline)
 {
     _transaction = transaction;
     _writer = writer;
     _preferInline = preferInline;
 }