Пример #1
0
        void CopyFromBuffer(IILGen ilGenerator, int bufferIdx, int skFieldIdx, ref BufferInfo bi, Dictionary <int, MemorizedPositionWithLength> outOfOrderPKParts,
                            List <TableFieldInfo> pks, IList <FieldId> skFields, IILLocal positionLoc, IILLocal memoPositionLoc, Action <IILGen> pushWriter)
        {
            for (var idx = bi.ActualFieldIdx; idx < skFieldIdx; idx++)
            {
                var field = skFields[idx];
                if (field.IsFromPrimaryKey)
                {
                    outOfOrderPKParts[(int)field.Index] = SkipWithMemorizing(bufferIdx, ilGenerator, bi.PushReader,
                                                                             pks[(int)field.Index].Handler, positionLoc);
                }
                else
                {
                    var f = ClientRelationVersionInfo.GetSecondaryKeyField((int)field.Index);
                    f.Handler.Skip(ilGenerator, bi.PushReader);
                }
            }

            var skField = skFields[skFieldIdx];

            GenerateCopyFieldFromByteBufferToWriterIl(ilGenerator, pks[(int)skField.Index].Handler, bi.PushReader,
                                                      pushWriter, positionLoc, memoPositionLoc);

            bi.ActualFieldIdx = skFieldIdx + 1;
        }
Пример #2
0
 internal Action <IInternalObjectDBTransaction, AbstractBufferedWriter, object, object> GetSecondaryKeysKeySaver
     (uint secondaryKeyIndex, string name)
 {
     return(_secondaryKeysSavers.GetOrAdd(secondaryKeyIndex,
                                          idx => CreateSaverWithApartFields(ClientRelationVersionInfo.GetSecondaryKeyFields(secondaryKeyIndex),
                                                                            $"Relation_{Name}_SK_{name}_KeySaver")));
 }
Пример #3
0
        Action <byte[], byte[], AbstractBufferedWriter> CreatePrimaryKeyFromSKDataMerger(uint secondaryKeyIndex,
                                                                                         int paramFieldCountInFirstBuffer, string mergerName)
        {
            var method      = ILBuilder.Instance.NewMethod <Action <byte[], byte[], AbstractBufferedWriter> >(mergerName);
            var ilGenerator = method.Generator;

            Action <IILGen> pushWriter = il => il.Ldarg(2);
            var             skFields   = ClientRelationVersionInfo.SecondaryKeys[secondaryKeyIndex].Fields;

            var positionLoc     = ilGenerator.DeclareLocal(typeof(ulong)); //stored position
            var memoPositionLoc = ilGenerator.DeclareLocal(typeof(IMemorizedPosition));

            var firstBuffer  = new BufferInfo();
            var secondBuffer = new BufferInfo {
                ActualFieldIdx = paramFieldCountInFirstBuffer
            };
            var outOfOrderPKParts = new Dictionary <int, MemorizedPositionWithLength>(); //index -> bufferIdx, IMemorizedPosition, length

            var pks = ClientRelationVersionInfo.GetPrimaryKeyFields().ToList();

            for (var pkIdx = 0; pkIdx < pks.Count; pkIdx++)
            {
                if (outOfOrderPKParts.ContainsKey(pkIdx))
                {
                    var memo       = outOfOrderPKParts[pkIdx];
                    var pushReader = GetBufferPushAction(memo.BufferIndex, firstBuffer.PushReader, secondBuffer.PushReader);
                    CopyFromMemorizedPosition(ilGenerator, pushReader, pushWriter, memo, memoPositionLoc);
                    continue;
                }
                int bufferIdx, skFieldIdx;
                FindPosition(pkIdx, skFields, paramFieldCountInFirstBuffer, out bufferIdx, out skFieldIdx);
                if (bufferIdx == 0)
                {
                    MergerInitializeFirstBufferReader(ilGenerator, ref firstBuffer);
                    CopyFromBuffer(ilGenerator, bufferIdx, skFieldIdx, ref firstBuffer, outOfOrderPKParts, pks, skFields, positionLoc,
                                   memoPositionLoc, pushWriter);
                }
                else
                {
                    MergerInitializeBufferReader(ilGenerator, ref secondBuffer, 1);
                    CopyFromBuffer(ilGenerator, bufferIdx, skFieldIdx, ref secondBuffer, outOfOrderPKParts, pks, skFields, positionLoc,
                                   memoPositionLoc, pushWriter);
                }
            }

            ilGenerator.Ret();
            return(method.Create());
        }
Пример #4
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.");
                    }
                }
            }
        }
Пример #5
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;
        }