private static unsafe void WritePartitionKeyRange(KeyPredicate?[] predicates, byte appId, EntityModel model, byte *bk, byte *ek, int *varSizes) { var tableId = model.TableId; byte *tiPtr = (byte *)&tableId; bk[0] = ek[0] = appId; bk[1] = ek[1] = tiPtr[2]; bk[2] = ek[2] = tiPtr[1]; bk[3] = ek[3] = tiPtr[0]; bk[4] = ek[4] = KeyUtil.PARTCF_PART_TABLE_FLAG; if (predicates == null || !predicates[0].HasValue) //short path for no predicate { ek[4] = KeyUtil.PARTCF_PART_TABLE_FLAG + 1; return; } var bw = new EntityStoreWriter(bk, 5); var ew = new EntityStoreWriter(ek, 5); for (int i = 0; i < predicates.Length; i++) { if (!predicates[i].HasValue) { break; //没有指定谓词跳出 } var m = predicates[i].Value.Value; var ruleArg = model.SysStoreOptions.PartitionKeys[i].RuleArgument; switch (predicates[i].Value.Type) { case KeyPredicateType.Equal: { if (model.SysStoreOptions.PartitionKeys[i].Rule == PartitionKeyRule.Hash) { int pkValue = EntityStoreWriter.GetHashOfPK(m.BoxedValue, ruleArg); bw.WriteUInt16((ushort)(m.Id | 4)); bw.WriteInt32(pkValue); ew.WriteUInt16((ushort)(m.Id | 4)); ew.WriteInt32(pkValue); } else if (model.SysStoreOptions.PartitionKeys[i].Rule == PartitionKeyRule.RangeOfDate) { } else { } } break; default: throw new NotImplementedException(); } } }
/// <summary> /// 用于写入全部相等的分区Key /// </summary> private unsafe void WritePartitionKey(byte appId, EntityModel model, byte *key, int *varSizes) { var tableId = model.TableId; byte *tiPtr = (byte *)&tableId; key[0] = appId; key[1] = tiPtr[2]; key[2] = tiPtr[1]; key[3] = tiPtr[0]; key[4] = KeyUtil.PARTCF_PART_TABLE_FLAG; var w = new EntityStoreWriter(key, 5); for (int i = 0; i < predicates.Length; i++) { Debug.Assert(predicates[i].Value.Type == KeyPredicateType.Equal); var m = predicates[i].Value.Value; var ruleArg = model.SysStoreOptions.PartitionKeys[i].RuleArgument; if (model.SysStoreOptions.PartitionKeys[i].Rule == PartitionKeyRule.Hash) { int pkValue = EntityStoreWriter.GetHashOfPK(m.BoxedValue, ruleArg); w.WriteUInt16((ushort)(m.Id | 4)); //不用写排序标记 w.WriteInt32(pkValue); } else if (model.SysStoreOptions.PartitionKeys[i].Rule == PartitionKeyRule.RangeOfDate) { int pkValue = EntityStoreWriter.GetRangeOfPK(m.DateTimeValue, (DatePeriod)ruleArg); ushort mid = m.Id; if (model.SysStoreOptions.PartitionKeys[i].OrderByDesc) { mid |= 1 << IdUtil.MEMBERID_ORDER_OFFSET; } w.WriteUInt16((ushort)(mid | 4)); //写入排序标记 w.WriteInt32(pkValue); } else { w.WriteMember(ref m, varSizes + i, true, model.SysStoreOptions.PartitionKeys[i].OrderByDesc); } } }
internal unsafe static void WritePartitionKeys(Entity entity, EntityModel model, byte *pkPtr, int *varSizes) { var w = new EntityStoreWriter(pkPtr, 5); ushort memberId; for (int i = 0; i < model.SysStoreOptions.PartitionKeys.Length; i++) { memberId = model.SysStoreOptions.PartitionKeys[i].MemberId; switch (model.SysStoreOptions.PartitionKeys[i].Rule) { case PartitionKeyRule.Hash: { object fieldValue = memberId == 0 ? entity.CreateTimeUtc : entity.GetMember(memberId).BoxedValue; int pkValue = GetHashOfPK(fieldValue, model.SysStoreOptions.PartitionKeys[i].RuleArgument); w.WriteUInt16((ushort)(memberId | 4)); //不需要写入排序标记 w.WriteInt32(pkValue); } break; case PartitionKeyRule.RangeOfDate: { DateTime fieldValue = memberId == 0 ? entity.CreateTimeUtc : entity.GetDateTime(memberId); int pkValue = GetRangeOfPK(fieldValue, (DatePeriod)model.SysStoreOptions.PartitionKeys[i].RuleArgument); if (model.SysStoreOptions.PartitionKeys[i].OrderByDesc) //需要写入排序标记 { memberId |= 1 << IdUtil.MEMBERID_ORDER_OFFSET; } w.WriteUInt16((ushort)(memberId | 4)); w.WriteInt32(pkValue); } break; default: w.WriteMember(ref entity.GetMember(memberId), varSizes + i, true, //TODO: check write null model.SysStoreOptions.PartitionKeys[i].OrderByDesc); break; } } }
/// <summary> /// 写索引Value /// </summary> /// <returns>非惟一索引且没有覆盖字段返回IntPtr.Zero</returns> internal unsafe static IntPtr WriteIndexData(Entity entity, EntityIndexModel indexModel, out int dataSize) { if (!(indexModel.Unique || indexModel.HasStoringFields)) { dataSize = 0; return(IntPtr.Zero); } int *varSizes = null; int totalSize = indexModel.Unique ? 2 + 16 : 0; if (indexModel.HasStoringFields) { int *vars = stackalloc int[indexModel.StoringFields.Length]; for (int i = 0; i < indexModel.StoringFields.Length; i++) { totalSize += CalcMemberSize(ref entity.GetMember(indexModel.StoringFields[i]), vars + i, true); } varSizes = vars; } dataSize = totalSize; var w = new EntityStoreWriter(totalSize); //先写入惟一索引指向的EntityId if (indexModel.Unique) { w.WriteUInt16(IdUtil.STORE_FIELD_ID_OF_ENTITY_ID); w.WriteGuid(entity.Id.Data); } //再写入StoringFields if (indexModel.HasStoringFields) { for (int i = 0; i < indexModel.StoringFields.Length; i++) { w.WriteMember(ref entity.GetMember(indexModel.StoringFields[i]), varSizes + i, true, false); //TODO:考虑不写入Null } } return(w.nativeStringPtr); }