protected override void BuildMetaData(TransactionDiscStorage transactionStorage, long sliceIndex)
        {
            var  dirtyData    = new DirtyData();
            var  commitItems  = NewCommitItems();
            Hash previousHash = null; // Todo, get hash from previous storage

            for (var transactionId = transactionStorage.StartIndex; transactionId <= transactionStorage.EndIndex; transactionId++)
            {
                if (transactionId <= LastProcessedTransactionId)
                {
                    continue;
                }

                var transactionData = transactionStorage.GetBlockDataRawIndex(transactionId);
                var item            = new TransactionItem <MaintainTransaction>(transactionData);

                if (previousHash != null)
                {
                    if (!item.Validation.IsValid(previousHash, new ArraySegment <byte>(transactionData, 0, transactionData.Length - ValidationOperation.ValidationOperationDataSize)))
                    {
                        throw new Exception("Transaction Validation failed");
                    }
                }
                previousHash = item.Validation.Hash;

                ConsumeTransaction(dirtyData, commitItems, item);
            }

            CommmitDirtyData(dirtyData, commitItems);
            commitItems.Commit();
        }
        internal void ReceiveMessage(DirtyData message)
        {
            switch (message.Operation)
            {
            case OperationType.Add:
                if (!DirtyEntities.Contains(message.Source))
                {
                    DirtyEntities.Add(message.Source);
                    RaisePropertyChanged(nameof(IsConsistentState));
                }

                break;

            case OperationType.Remove:
                if (DirtyEntities.Contains(message.Source))
                {
                    DirtyEntities.Remove(message.Source);
                    RaisePropertyChanged(nameof(IsConsistentState));
                }

                break;

            default:
                throw new ArgumentException(ErrorMessages.UnexpectedType.GetDescription(),
                                            nameof(message.Operation));
            }
        }
    public static CleanData Validate(DirtyData d)
    {
        CleanData data = new CleanData();

        if (ValidateString(d.Name))
        {
            data.Name = d.Name
        }
        else
        {
            throw new ValidationException();
        }
        return(CleanData);
    }
        void ConsumeTransaction(DirtyData dirtyData, CommitItems commitItems, TransactionItem <MaintainTransaction> dataItem)
        {
            var transaction   = dataItem.Transaction;
            var transactionId = transaction.TransactionId;

            if (transactionId <= LastProcessedTransactionId)
            {
                return;
            }

            if (transaction.TargetChainId == ChainId)
            {
                var type = transaction.TransactionType;

                if (type == MainTainTransactionTypes.Revenue)
                {
                    var rev         = transaction as RevenueMaintainTransaction;
                    var revenueInfo = rev.RevenueInfo;
                    var tick        = rev.Tick;

                    lock (_revenueLock)
                    {
                        var revenues = GetRevenueReceivers(tick);
                        if (revenues == null)
                        {
                            revenues = new RevenueReceivers(tick, rev.PreviousTick, revenueInfo);
                            _revenueReceivers[tick] = revenues;
                            _revenueReceiversStroage.AddEntry(tick, revenues.ToByteArray());
                        }

                        if (revenueInfo.Index > revenues.RevenueInfo.Index)
                        {
                            revenues.RevenueInfo = revenueInfo;
                        }

                        foreach (var aId in rev.Accounts)
                        {
                            revenues.Accounts.Add(aId);
                        }
                    }

                    dirtyData.DirtyRevenueTicks.Add(tick);
                }

                ConsumeTransactionFeatures(0, transaction, null, commitItems);
            }
        }
        public void ConsumeBlockData(BlockData <MaintainBlock> blockData)
        {
            if (!Active)
            {
                return;
            }

            var block = blockData.Block;

            if (block.BlockId <= LastProcessedBlockId)
            {
                return;
            }

            var dirtyData   = new DirtyData();
            var commitItems = NewCommitItems();

            foreach (var item in block.Items)
            {
                ConsumeTransaction(dirtyData, commitItems, item);
                TransactionStorage.Add(block.BlockId, item);
            }

            CommmitDirtyData(dirtyData, commitItems);
            commitItems.Commit();

            var lastTransactionid = LastProcessedTransactionId;
            var count             = block.Transactions.Count;

            if (count > 0)
            {
                lastTransactionid = block.Transactions[count - 1].TransactionId;
            }

            foreach (var metaStorage in _metaDiscStorage)
            {
                metaStorage.LastBlockId       = block.BlockId;
                metaStorage.LastTransactionId = lastTransactionid;
                metaStorage.Commit();
            }

            TransactionStorage.Save();
        }
        void CommmitDirtyData(DirtyData dirtyData, CommitItems commitItems)
        {
            lock (_revenueLock)
            {
                foreach (var tick in dirtyData.DirtyRevenueTicks)
                {
                    var revenues = GetRevenueReceivers(tick);

                    _revenueReceiversStroage.UpdateEntry(tick, revenues.ToByteArray());
                    _revenueReceiversStroage.LastAvailableTick = Math.Max(tick, _revenueReceiversStroage.LastAvailableTick);
                }

                var last = GetRevenueReceivers(_revenueReceiversStroage.LastAvailableTick);
                if (last != null)
                {
                    var previous      = GetRevenueReceivers(last.PreviousTick);
                    var lastProcessed = _revenueReceiversStroage.LastProcessedTick;

                    while (previous != null)
                    {
                        if (previous.Tick <= lastProcessed)
                        {
                            break;
                        }

                        var tick        = previous.Tick;
                        var accounts    = previous.Accounts;
                        var count       = accounts.Count;
                        var revenueInfo = previous.RevenueInfo;

                        var tickRevenue    = revenueInfo.Revenue * revenueInfo.AccountRevenueFactor;
                        var accountRevenue = tickRevenue / count;
                        var maxCount       = tickRevenue / Currency.OneCen;

                        if (count > maxCount)
                        {
                            var list = new List <long>(accounts);
                            list.Sort((a, b) => a.CompareTo(b));

                            var rand = new Lehmer(count);
                            for (var i = 0; i < count; i++)
                            {
                                var a = rand.Next(count);

                                var tmp = list[i];
                                list[i] = list[a];
                                list[a] = tmp;
                            }

                            for (var i = 0; i < maxCount; i++)
                            {
                                var accountId = list[i];
                                var account   = GetMaintainAccount(accountId);
                                account.AddRevenue(tick, (int)Currency.OneCen);
                                commitItems.DirtyAccounts.Add(accountId);
                            }
                        }
                        else
                        {
                            foreach (var accountId in accounts)
                            {
                                var account = GetMaintainAccount(accountId);
                                account.AddRevenue(tick, accountRevenue);
                                commitItems.DirtyAccounts.Add(accountId);
                            }
                        }

                        previous = GetRevenueReceivers(previous.PreviousTick);
                    }

                    _revenueReceiversStroage.LastProcessedTick = last.PreviousTick;
                }
            }

            foreach (var accountId in commitItems.DirtyAccounts)
            {
                var account = GetMaintainAccount(accountId);
                _maintainAccountStorage.UpdateEntry(accountId, account.ToByteArray());
            }
        }
        public void SendModifiedPBToKZ(ConsMixprop entity, string[] DirtyDataArr)
        {
            using (var tx = this.m_UnitOfWork.BeginTransaction())
            {
                try
                {
                    if (DirtyDataArr != null)
                    {
                        ////先保存子表数据,只用到编号与数量
                        string        is2012   = "";
                        Synmonitor    synTable = null;
                        PublicService op       = null;

                        foreach (string DirtyData in DirtyDataArr)
                        {
                            string[] dirty = DirtyData.Split(',');
                            ConsMixpropItemService consMixpropItemservice = new ConsMixpropItemService(this.m_UnitOfWork);
                            ConsMixpropItem        item = consMixpropItemservice.Get(Convert.ToInt32(dirty[0]));
                            item.Amount = Convert.ToDecimal(dirty[1]);
                            consMixpropItemservice.Update(item, null);

                            is2012 = ConfigurationManager.AppSettings["Is2012"];
                            if (is2012 == "true")
                            {
                                //是2012工控则插入同步表
                                synTable               = new Synmonitor();
                                synTable.tb_name       = "view_ConsMixpropItems";
                                synTable.tb_action     = "UPDATE";
                                synTable.key_name      = "ConsMixpropID";
                                synTable.key_value     = dirty[0];
                                synTable.key_type      = "0";
                                synTable.action_time   = DateTime.Now;
                                synTable.ProductLineID = item.ConsMixprop.ProductLineID;
                                if (op == null)
                                {
                                    op = new PublicService();
                                }
                                op.Synmonitor.Add(synTable);
                            }
                        }
                    }
                    IConsMixpropItemRepository IConItems = this.m_UnitOfWork.ConsMixpropItemRepository;
                    IList <ConsMixpropItem>    citems    = IConItems.Query().Where(m => m.ConsMixpropID == entity.ID).ToList();
                    decimal totolWeight = 0;
                    foreach (ConsMixpropItem citem in citems)
                    {
                        totolWeight = totolWeight + citem.Amount;
                    }
                    ConsMixprop cons = this.Get(entity.ID);
                    cons.SynStatus = entity.SynStatus;
                    base.Update(cons, null);
                    entity = this.Get(entity.ID);
                    SysConfigService configService = new SysConfigService(this.m_UnitOfWork);
                    SysConfig        config        = configService.GetSysConfig(SysConfigEnum.IsAllowConsMixpropLimit);
                    if (!entity.IsSlurry)
                    {
                        SysConfig configFormulaRZMax = configService.GetSysConfig(SysConfigEnum.FormulaRZMax);
                        SysConfig configFormulaRZMin = configService.GetSysConfig(SysConfigEnum.FormulaRZMin);
                        decimal   dFormulaRZMax      = decimal.Parse(configFormulaRZMax.ConfigValue);
                        decimal   dFormulaRZMin      = decimal.Parse(configFormulaRZMin.ConfigValue);
                        decimal   weight             = entity.Weight ?? 0;
                        if (config != null && bool.Parse(config.ConfigValue) && entity.ProduceTask.CementType == Model.Enums.CementType.CommonCement)
                        {
                            if (totolWeight > dFormulaRZMax || totolWeight < dFormulaRZMin)
                            {
                                throw new Exception("混凝土配比超出容重范围");
                            }
                            string measureError = CheckMesureScale(entity.TaskID, entity.ProductLineID, 0, 0, true, false);
                            if (!string.IsNullOrEmpty(measureError))
                            {
                                throw new Exception(measureError);
                            }
                        }
                    }
                    else
                    {
                        if (config != null && bool.Parse(config.ConfigValue) && entity.ProduceTask.CementType == Model.Enums.CementType.CommonCement)
                        {
                            string measureError = CheckMesureScale(entity.TaskID, entity.ProductLineID, 0, 0, false, true);
                            if (!string.IsNullOrEmpty(measureError))
                            {
                                throw new Exception(measureError);
                            }
                        }
                    }
                    if (entity.SynStatus == 1)      //发送配比
                    {
                        /*//直连:通知控制系统修改配比
                         * by:Sky 2013/3/17
                         *****************************************************************************/
                        IList <ConsMixpropItem> cmItems = this.m_UnitOfWork.GetRepositoryBase <ConsMixpropItem>().All("ConsMixpropID='" + entity.ID + "'", "ID", true);
                        ResultInfo result = controlSystem.UpdateConsMixprop(entity, cmItems);
                        if (!result.Result)       //配比没有发送成功
                        {
                            throw new Exception(result.Message);
                        }
                    }
                    tx.Commit();
                }
                catch (Exception e)
                {
                    tx.Rollback();
                    throw e;
                }
            }
        }