Example #1
0
        protected DBResult AddClusterEntry(LowLevelTransaction lltx, TreePage page, KVTuple kv, Stack <TreePage> path, TreeNodeHeaderFlags nodeFlags)
        {
            var dbResult = AddClusterEntry(lltx, page, kv, nodeFlags, false);

            if (dbResult.IsSplitPage() == false)
            {
                return(dbResult);
            }

            var ctx = SplitLeaf(lltx, page, path, kv.Key, page.LastMatchIndex);

            if (ctx.Current != page)
            {
                lltx.LockManager.SplitRecLock(page.Position, ctx.Sibling.Position, ctx.Index);
                lltx.LockManager.SplitRecLock(page.Position, ctx.Current.Position, 0);
            }
            else
            {
                lltx.LockManager.SplitRecLock(page.Position, ctx.Sibling.Position, ctx.Index);
            }

            if (ctx.Index >= page.LastMatchIndex)
            {
                return(AddClusterEntry(lltx, ctx.Current, kv, nodeFlags));
            }
            else
            {
                return(AddClusterEntry(lltx, ctx.Sibling, kv, nodeFlags));
            }
        }
Example #2
0
        public DBResult AddClusterEntry(LowLevelTransaction lltx, KVTuple kv, TreeNodeHeaderFlags nodeFlags)
        {
            var page = GetPageForUpdate(lltx, kv.Key, Constants.BTreeLeafPageDepth);

            if (page == null)
            {
                throw new NullReferenceException(nameof(page));
            }

            var dbResult = AddClusterEntry(lltx, page, kv, nodeFlags);

            if (dbResult.IsSplitPage() == false)
            {
                return(dbResult);
            }

            var size = TreeHelper.GetNodeSizeInPage(kv, nodeFlags);
            var path = GetPagePathForKey(lltx, kv.Key, size);

            if (path.Count == 0)
            {
                throw new InvalidOperationException("internal error!");
            }

            return(AddClusterEntry(lltx, path.Pop(), kv, path, nodeFlags));
        }
Example #3
0
        protected DBResult AddClusterEntry(LowLevelTransaction lltx, TreePage page, KVTuple kv, TreeNodeHeaderFlags nodeFlags, bool isOpmst = true)
        {
            var matchFlags = 0;
            var matchIndex = 0;

            if (true)
            {
                page.SearchForAdd(lltx, kv.Key, out matchFlags, out matchIndex);
            }

            if (matchFlags == 0)
            {
                return(AddClusterEntryInPlace(lltx, page, kv, matchIndex, nodeFlags));
            }

            var dbResult = LockRec(lltx, page, matchIndex, LockFlags.Document | LockFlags.Exclusive, true);

            if (dbResult.IsSuccess())
            {
                dbResult = AddKVToLeafPage(lltx, page, kv, matchIndex, nodeFlags);
            }

            if (isOpmst && dbResult.IsSplitPage())
            {
                lltx.ExitLatch(page.Position);
            }

            return(dbResult);
        }
Example #4
0
        protected DBResult UpdateClusterEntry(LowLevelTransaction tx, TreePage page, KVTuple kv)
        {
            var flags = LockRec(tx, page, page.LastMatchIndex, LockFlags.Exclusive | LockFlags.Document);

            if (flags != DBResult.Success)
            {
                return(flags);
            }

            if (!page.TryGetNodeEntry(page.LastMatchIndex, out var entry))
            {
                throw new InvalidOperationException($"read the tree's entry for {kv.Key.ToString()} failed at page:{page.Position}! ");
            }

            if (!entry.Header.IsDeleted)
            {
                throw new InvalidOperationException($"duplicate key for {kv.Key.ToString()}");
            }

            if (entry.VersionHeader.TransactionNumber == tx.Id)
            {
                return(UpdateClusterEntry(tx, page, kv, ref entry, entry.VersionHeader.TransactionRollbackNumber));
            }

            var undo = BackUpUndoEntry(tx, page, page.LastMatchIndex);

            if (undo == -1)
            {
                throw new InvalidOperationException("back up undo failed!");
            }

            return(UpdateClusterEntry(tx, page, kv, ref entry, undo));
        }
        internal static void ReadEntityFields(EntityModel model, Entity obj, IntPtr valuePtr, int valueSize)
        {
            //TODO:暂使用KVTuple解析,待优化
            var fields = new KVTuple();

            fields.ReadFrom(valuePtr, valueSize);
            ushort fieldId;

            for (int i = 0; i < fields.fs.Count; i++)
            {
                fieldId = fields.fs[i].Id;
                var m = model.GetMember(fieldId, true);
                if (m.Type == EntityMemberType.DataField)
                {
                    var df = (DataFieldModel)m;
                    switch (df.DataType)
                    {
                    case EntityFieldType.String:
                        obj.SetString(fieldId, fields.GetString(fieldId)); break;

                    case EntityFieldType.Binary:
                        obj.SetBytes(fieldId, fields.GetBytes(fieldId)); break;

                    case EntityFieldType.Int32:
                        obj.SetInt32Nullable(fieldId, fields.GetInt32(fieldId)); break;

                    case EntityFieldType.UInt64:
                        obj.SetUInt64Nullable(fieldId, fields.GetUInt64(fieldId)); break;

                    case EntityFieldType.EntityId:
                        obj.SetEntityId(fieldId, fields.GetGuid(fieldId)); break;     //TODO:可能null处理

                    case EntityFieldType.Guid:
                        obj.SetGuidNullable(fieldId, fields.GetGuid(fieldId)); break;

                    case EntityFieldType.Byte:
                        obj.SetByteNullable(fieldId, fields.GetByte(fieldId)); break;

                    case EntityFieldType.Boolean:
                        obj.SetBooleanNullable(fieldId, fields.GetBool(fieldId)); break;

                    case EntityFieldType.DateTime:
                        obj.SetDateTimeNullable(fieldId, fields.GetDateTime(fieldId)); break;

                    case EntityFieldType.Float:
                        obj.SetFloatNullable(fieldId, fields.GetFloat(fieldId)); break;

                    default:
                        throw ExceptionHelper.NotImplemented($"{df.DataType}");
                    }
                }
                else
                {
                    throw new Exception("Only read DataField");
                }
            }

            //TODO:待修改上述赋值后不再需要,参考SqlQuery填充实体
            obj.ChangeToUnChanged();//obj.AcceptChanges();
        }
Example #6
0
        public static ushort GetNodeSizeInPage(KVTuple kv, TreeNodeHeaderFlags nodeFlags)
        {
            var size = kv.Length > Tree.MaxEntrySizeInPage ? kv.Key.Length : kv.Length;

            size += TreeNodeHeader.SizeOf + sizeof(short);
            size += nodeFlags.HasVersion() ? TreeNodeVersionHeader.SizeOf : 0;
            return((ushort)size);
        }
Example #7
0
        public unsafe void ReadFieldsTest()
        {
            byte[] data   = StringHelper.FromHexString("40000600004141414141418000060000424242424242");
            var    fields = new KVTuple();

            fixed(byte *ptr = data)
            {
                fields.ReadFrom(new IntPtr(ptr), data.Length);
                for (int i = 0; i < fields.fs.Count; i++)
                {
                    Console.WriteLine($"{fields.fs[i].Id} {fields.fs[i].DataPtr} {fields.fs[i].DataSize}");
                }
            }

            Assert.Equal("AAAAAA", fields.GetString(0x40));
            Assert.Equal("BBBBBB", fields.GetString(0x80));
        }
Example #8
0
        protected DBResult AddClusterEntryInPlace(LowLevelTransaction lltx, TreePage page, KVTuple kv, int index, TreeNodeHeaderFlags nodeFlags)
        {
            var e1 = page.GetNodeEntry(index);

            if (e1.Header.IsDeleted == false)
            {
                throw new InvalidOperationException("duplicate key for...");
            }

            var ctx = new TreeNodeEntryAllocContext()
            {
                Key       = kv.Key,
                Size      = (ushort)kv.Length,
                KeySize   = (ushort)kv.Key.Length,
                ValueSize = (ushort)kv.Value.Length,
                NodeFlags = nodeFlags,
            };

            if (page.Alloc(lltx, index, ref ctx, out var entry))
            {
                ref var header = ref entry.Header;

                header.IsDeleted = false;
                header.KeySize   = (ushort)kv.Key.Length;
                header.DataSize  = (ushort)kv.Value.Length;
                header.NodeFlags = nodeFlags;

                kv.Key.CopyTo(entry.Key);
                kv.Value.CopyTo(entry.Value);

                ref var versionHeader = ref entry.VersionHeader;
Example #9
0
 protected DBResult UpdateClusterEntry(LowLevelTransaction tx, TreePage cursor, KVTuple kv, ref TreeNodeEntry oldEntry, long rollbackNumber)
 {
     throw null;
 }
Example #10
0
 internal IndexRow(INativeData value)
 {
     _value = value;
     ValueTuple = new KVTuple();
     ValueTuple.ReadFrom(_value.DataPtr, (int)_value.Size);
 }