Exemple #1
0
 public static extern int DispatchMessage(NativeMessage *lpMsg);
Exemple #2
0
 public static extern int PeekMessage(NativeMessage *lpMsg, void *hWnd, int wMsgFilterMin, int wMsgFilterMax, int wRemoveMsg);
Exemple #3
0
 public static extern int TranslateMessage(NativeMessage *lpMsg);
Exemple #4
0
        /// <summary>
        /// 处理Native委托Clr执行过滤扫描
        /// </summary>
        internal static unsafe void ScanByClr(IntPtr msgPtr)
        {
            NativeMessage *msg    = (NativeMessage *)msgPtr;
            var            shard  = msg->Shard;
            var            handle = msg->Handle;
            var            it     = msg->Data1;
            var            req    = msg->Data2;
            var            res    = msg->Data3;

            var queueOk = ThreadPool.UnsafeQueueUserWorkItem(s =>
            {
                //注意:需要处理异常
                //TODO:全局索引过滤特殊处理,本地索引可以通过Api直接读目标数据,但全局索引可考虑按批加载目标后再过滤

                IteratorKV itkv = new IteratorKV();
                var itkvPtr     = new IntPtr(&itkv);
                var reqInfo     = new ScanReqInfo();
                NativeApi.ScanGetReqInfo(req, new IntPtr(&reqInfo), it, itkvPtr); //注意同时填充第一条IteratorKV

                //处理过滤条件,注意:暂使用缓存方案,防止反复Expression.Compile(性能损耗太大)
                Debug.Assert(reqInfo.FilterPtr != IntPtr.Zero && reqInfo.FilterSize != IntPtr.Zero);
                BytesKey key = new BytesKey(reqInfo.FilterPtr, reqInfo.FilterSize.ToInt32());
                if (!filters.TryGet(key, out KVFilterFunc filterFunc))
                {
                    try
                    {
                        var filter = (Expressions.Expression)ModelStore.DeserializeModel(reqInfo.FilterPtr, reqInfo.FilterSize.ToInt32());
                        var body   = filter.ToLinqExpression(KVScanExpressionContext.Default); //TODO:参考FastExpressionCompiler直接编译
                        var exp    = Expression.Lambda <KVFilterFunc>(body,
                                                                      KVScanExpressionContext.Default.GetParameter("vp"),
                                                                      KVScanExpressionContext.Default.GetParameter("vs"),
                                                                      KVScanExpressionContext.Default.GetParameter("mv"),
                                                                      KVScanExpressionContext.Default.GetParameter("ts")
                                                                      );
                        //Expression<Func<KVTuple, bool>> exp = t => t.StringEquals(Consts.EMPLOEE_NAME_ID, testData); //测试过滤器2
                        //Expression<KVFilterFunc> exp = (vp, vs, mvcc, ts) => false;

                        filterFunc = exp.Compile(); //TODO:待进一步研究 exp.CompileFast();
                        filters.TryAdd(key.CopyToManaged(), filterFunc);
                    }
                    catch (Exception ex)
                    {
                        Log.Warn($"Compile filter expression error: Type: {ex.GetType()}\nMessage:{ex.Message}\nStack:{ex.StackTrace}");
                        NativeApi.ScanFinished(shard, handle, it, res, (uint)KVCommandError.ClrCompileFilterFailed);
                        return;
                    }
                }

                //int count = 0;
                //var sw = new Stopwatch();
                //long times = 0;
                //sw.Start();

                uint skipped = 0;
                uint taken   = 0;
                int itStatus = 0;
                while (true) //TODO:迭代过程异常处理
                {
                    //打印KV调试信息
                    //count++;
                    //var keyString = StringHelper.ToHexString(itkv.KeyPtr, itkv.KeySize.ToInt32());
                    //var valueString = StringHelper.ToHexString(itkv.ValuePtr, itkv.ValueSize.ToInt32());
                    //Log.Debug($"Key={keyString} Value={valueString}");

                    //开始过滤表达式判断
                    if (filterFunc(itkv.ValuePtr, itkv.ValueSize.ToInt32(), reqInfo.IsMvcc, reqInfo.Timestamp)) //50-60 -> 20
                    {
                        if (skipped < reqInfo.Skip)
                        {
                            skipped++;
                        }
                        else
                        {
                            NativeApi.ScanResponseAddKV(res, it, reqInfo.IsMvcc, reqInfo.Timestamp);
                            taken++;
                            if (taken >= reqInfo.Take)
                            {
                                break;
                            }
                        }
                    }

                    itStatus = NativeApi.ScanNextValidIterator(it, req, itkvPtr); //未优化前350-400 -> 95
                    if (itStatus == -1)                                           //读到已被GC的记录
                    {
                        NativeApi.ScanFinished(shard, handle, it, res, (uint)KVCommandError.ReadGCData);
                        return;
                    }
                    if (itStatus == 0)
                    {
                        break;
                    }
                } //end while

                //sw.Stop();
                //times += sw.ElapsedTicks;
                //Console.WriteLine($"Thread:{Thread.CurrentThread.ManagedThreadId} Scan:{count} 耗时:{sw.ElapsedMilliseconds}");
                //Console.WriteLine($"Scan:{count} 步骤耗时:{times / TimeSpan.TicksPerMillisecond}");
                NativeApi.ScanResponseSetSkipped(res, skipped); //TODO:移至ScanFinished参数
                NativeApi.ScanFinished(shard, handle, it, res, 0);
            }, null);

            if (!queueOk)
            {
                Log.Warn("Cannot queue scan task");
                NativeApi.ScanFinished(shard, handle, it, res, (uint)KVCommandError.ClrEnqueueTaskFailed);
            }
        }