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)); } }
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)); }
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); }
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(); }
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); }
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)); }
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;
protected DBResult UpdateClusterEntry(LowLevelTransaction tx, TreePage cursor, KVTuple kv, ref TreeNodeEntry oldEntry, long rollbackNumber) { throw null; }
internal IndexRow(INativeData value) { _value = value; ValueTuple = new KVTuple(); ValueTuple.ReadFrom(_value.DataPtr, (int)_value.Size); }