Beispiel #1
0
        // 运算逆波兰表,得到结果集
        // parameter:
        //		rpn         逆波兰表
        //		oResultSet  结果集
        // return:
        //		0   成功
        //		-1  出错 原因可能如下:
        //			1)rpn参数为null
        //			2)oResultSet参数为null
        //			3)栈里的某成员出错(node和result都为null)
        //			4)从栈中pop()或peek()元素时,出现栈空
        //			5)pop的类型,不是实际存在的类型
        //			6)通过一个节点,得到结果集,即调DoQuery()函数出错
        //			7)做运算时,调DpResultSetManager.Merge()函数出错
        //			8)最后栈里的元素多于1,则逆波兰表出错
        //			9)最后结果集为空
        //		-6	无足够的权限
        public int ProceedRPN(ArrayList rpn,
                              DpResultSet resultSet,
                              Delegate_isConnected isConnected,
                              out string strError)
        {
            strError = "";

            //???要搞清楚用不用清空
            //应该清空,后面的运算使用的结果集是堆栈变量,最后把运算结果拷贝到该结果集
            //DoQuery处,也应该先清空
            //doItem处,一进去先清空,但再对数据库循环检索时,千万不清空
            resultSet.Clear();

            if (rpn == null)
            {
                strError = "rpn不能为null";
                return(-1);
            }
            if (resultSet == null)
            {
                strError = "resultSet不能为null";
                return(-1);
            }
            if (rpn.Count == 0)
            {
                return(0);
            }

            int ret;

            // 声明栈,ReversePolishStack栈是自定义的类
            // 决定用一个栈做运算,如果遇到遇到操作数,就直接push到栈里
            // 遇到操作符,如果是双目,从栈里pop两项,进行运算
            // 注意SUB运算是,用后一次pop的对象减前一次pop的对象
            //
            // oReversePolandStack的成员为ReversePolishItem,
            // ReversePolishItem是一个复杂对象,
            // 包含m_int(类型),m_node(节点),m_resultSet.
            // 实际运用中,m_node和m_resultSet只有一项值有效,另一顶是null
            // m_int用于判断哪个值有效,
            // 0表示node有效,1表示resultSet有效
            ReversePolishStack oReversePolandStack =
                new ReversePolishStack();

            //做循环
            for (int i = 0; i < rpn.Count; i++)
            {
                XmlNode node = (XmlNode)rpn[i];

                if (node.Name != "operator")  //操作数直接push到栈里
                {
                    oReversePolandStack.PushNode(node);
                }
                else
                {
                    string strOpreator = DomUtil.GetAttr(node, "value");

                    //三个输出用于输入的参数,因为是指针,所以不用out
                    DpResultSet oTargetLeft   = new DpResultSet();
                    DpResultSet oTargetMiddle = new DpResultSet();
                    DpResultSet oTargetRight  = new DpResultSet();

                    //做一个两个成员的ArrayList,
                    //成员类型为DpResultSet,
                    //存放从栈里pop出的(如果是node,需要进行计算)的结果集
                    ArrayList oSource = new ArrayList();
                    oSource.Add(new DpResultSet());
                    oSource.Add(new DpResultSet());
                    try
                    {
                        for (int j = 0; j < 2; j++)
                        {
                            //类型为-1,表示node和resultSet都为null,出现错误
                            if (oReversePolandStack.PeekType() == -1)
                            {
                                strError = strOpreator + "时,PeekType()等于-1,则表示两项都是null,出错,返回-1<br/>";
                                return(-1);
                            }

                            //表示放得是node
                            if (oReversePolandStack.PeekType() == 0)
                            {
                                XmlNode nodePop;
                                nodePop = oReversePolandStack.PopNode();
                                if (nodePop == null)
                                {
                                    strError = "nodePop不为又能为null";
                                    return(-1);
                                }

                                // return:
                                //		-1	出错
                                //		-6	无权限
                                //		0	成功
                                ret = this.DoQuery(nodePop,
                                                   (DpResultSet)oSource[j],
                                                   isConnected,
                                                   out strError);
                                if (ret <= -1)
                                {
                                    return(ret);
                                }
                            }
                            else
                            {
                                oSource[j] = oReversePolandStack.PopResultSet();

                                if (oSource[j] == null)
                                {
                                    return(-1);
                                }
                            }
                        }
                    }
                    catch (StackUnderflowException)
                    {
                        return(-1);
                    }

                    string strDebugInfo;

                    //OR,AND,SUB运算都是调的DpResultSetManager.Merge()函数,
                    //注意参数的使用
                    if (strOpreator == "OR")
                    {
                        DpResultSet left = (DpResultSet)oSource[0];
                        left.EnsureCreateIndex();   // 确保创建了索引?
                        // ??????
                        //left.Sort();
                        DpResultSet right = (DpResultSet)oSource[1];
                        right.EnsureCreateIndex();
                        //right.Sort();

                        /*
                         * // new
                         * oTargetMiddle.EnsureCreateIndex();
                         */

                        ret = DpResultSetManager.Merge("OR",
                                                       left,
                                                       right,
                                                       null,
                                                       oTargetMiddle,
                                                       null,
                                                       false,
                                                       out strDebugInfo,
                                                       out strError);
                        if (ret == -1)
                        {
                            return(-1);
                        }

                        oReversePolandStack.PushResultSet(oTargetMiddle);

                        continue;
                    }

                    if (strOpreator == "AND")
                    {
                        DpResultSet left = (DpResultSet)oSource[0];
                        left.EnsureCreateIndex();
                        DpResultSet right = (DpResultSet)oSource[1];
                        right.EnsureCreateIndex();

                        /*
                         * // new
                         * oTargetMiddle.EnsureCreateIndex();
                         */

                        ret = DpResultSetManager.Merge("AND",
                                                       left,
                                                       right,
                                                       null, //oTargetLeft
                                                       oTargetMiddle,
                                                       null, //oTargetRight
                                                       false,
                                                       out strDebugInfo,
                                                       out strError);
                        if (ret == -1)
                        {
                            return(-1);
                        }

                        oReversePolandStack.PushResultSet(oTargetMiddle);

                        continue;
                    }

                    if (strOpreator == "SUB")
                    {
                        //因为使用从栈里pop,所以第0个是后面的,第1个是前面的
                        DpResultSet left = (DpResultSet)oSource[1];
                        left.EnsureCreateIndex();
                        DpResultSet right = (DpResultSet)oSource[0];
                        right.EnsureCreateIndex();

                        /*
                         * // new
                         * oTargetLeft.EnsureCreateIndex();
                         */

                        ret = DpResultSetManager.Merge("SUB",
                                                       left,
                                                       right,
                                                       oTargetLeft,
                                                       oTargetMiddle, //oTargetMiddle
                                                       oTargetRight,  //oTargetRight
                                                       false,
                                                       out strDebugInfo,
                                                       out strError);
                        if (ret == -1)
                        {
                            return(-1);
                        }

                        oReversePolandStack.PushResultSet(oTargetLeft);
                        continue;
                    }
                }
            }
            if (oReversePolandStack.Count > 1)
            {
                strError = "逆波兰出错";
                return(-1);
            }
            try
            {
                int nTemp = oReversePolandStack.PeekType();
                //如果类型为0,表示存放的是节点
                if (nTemp == 0)
                {
                    XmlNode node = oReversePolandStack.PopNode();

                    // return:
                    //		-1	出错
                    //		-6	无权限
                    //		0	成功
                    ret = this.DoQuery(node,
                                       resultSet,
                                       isConnected,
                                       out strError);
                    if (ret <= -1)
                    {
                        return(ret);
                    }
                }
                else if (nTemp == 1)
                {
                    //调DpResultSet的copy函数
                    resultSet.Copy((DpResultSet)(oReversePolandStack.PopResultSet()));
                }
                else
                {
                    strError = "oReversePolandStack的类型不可能为" + Convert.ToString(nTemp);
                    return(-1);
                }
            }
            catch (StackUnderflowException)
            {
                strError = "peek或pop时,抛出StackUnderflowException异常";
                return(-1);
            }

            //最后结果集为null,返回出错
            if (resultSet == null)
            {
                strError = "运算结束后PopResultSet为null" + Convert.ToString(oReversePolandStack.PeekType());
                return(-1);
            }
            return(0);
        }
Beispiel #2
0
        // 运算逆波兰表,得到结果集
        // parameter:
        //		rpn         逆波兰表
        //		resultSet  结果集
        // return:
        //		0   成功
        //		-1  出错 原因可能如下:
        //			1)rpn参数为null
        //			2)oResultSet参数为null
        //			3)栈里的某成员出错(node和result都为null)
        //			4)从栈中pop()或peek()元素时,出现栈空
        //			5)pop的类型,不是实际存在的类型
        //			6)通过一个节点,得到结果集,即调DoQuery()函数出错
        //			7)做运算时,调DpResultSetManager.Merge()函数出错
        //			8)最后栈里的元素多于1,则逆波兰表出错
        //			9)最后结果集为空
        //		-6	无足够的权限
        public int ProceedRPN(
            SessionInfo sessioninfo,
            string strOutputStyle,
            ArrayList rpn,
            ref DpResultSet resultSet,
            ChannelHandle handle,
            // Delegate_isConnected isConnected,
            out string strError)
        {
            DateTime start_time = DateTime.Now;
            Debug.WriteLine("Begin ProceedRPN()");

            try
            {
                strError = "";
                //???要搞清楚用不用清空
                //应该清空,后面的运算使用的结果集是堆栈变量,最后把运算结果拷贝到该结果集
                //DoQuery处,也应该先清空
                //doItem处,一进去先清空,但再对数据库循环检索时,千万不清空

                if (resultSet != null)
                    resultSet.Clear();

                if (rpn == null)
                {
                    strError = "rpn不能为null";
                    return -1;
                }
#if NO
                if (resultSet == null)
                {
                    strError = "resultSet不能为null";
                    return -1;
                }
#endif

                if (rpn.Count == 0)
                    return 0;

                int ret;

                // 声明栈,ReversePolishStack栈是自定义的类
                // 决定用一个栈做运算,如果遇到遇到操作数,就直接push到栈里
                // 遇到操作符,如果是双目,从栈里pop两项,进行运算
                // 注意SUB运算是,用后一次pop的对象减前一次pop的对象
                //
                // oReversePolandStack的成员为ReversePolishItem,
                // ReversePolishItem是一个复杂对象,
                // 包含m_int(类型),m_node(节点),m_resultSet.
                // 实际运用中,m_node和m_resultSet只有一项值有效,另一顶是null
                // m_int用于判断哪个值有效,
                // 0表示node有效,1表示resultSet有效
                ReversePolishStack oReversePolandStack =
                    new ReversePolishStack();

                //做循环
                for (int i = 0; i < rpn.Count; i++)
                {
                    XmlElement node = (XmlElement)rpn[i];

                    if (node.Name != "operator")  //操作数直接push到栈里
                    {
                        oReversePolandStack.PushNode(node);
                    }
                    else
                    {
                        string strOpreator = DomUtil.GetAttr(node, "value");

#if NO
                        //三个输出用于输入的参数,因为是指针,所以不用out
                        DpResultSet oTargetLeft = sessioninfo.NewResultSet();   // new DpResultSet();
                        DpResultSet oTargetMiddle = sessioninfo.NewResultSet();   // new DpResultSet();
                        DpResultSet oTargetRight = sessioninfo.NewResultSet();   // new DpResultSet();
#endif

                        //做一个两个成员的ArrayList,
                        //成员类型为DpResultSet,
                        //存放从栈里pop出的(如果是node,需要进行计算)的结果集
                        List<DpResultSet> oSource = new List<DpResultSet>();
                        oSource.Add(sessioninfo.NewResultSet());   // new DpResultSet()
                        oSource.Add(sessioninfo.NewResultSet());   // new DpResultSet()
                        try
                        {
                            for (int j = 0; j < 2; j++)
                            {
                                //类型为-1,表示node和resultSet都为null,出现错误
                                if (oReversePolandStack.PeekType() == -1)
                                {
                                    strError = strOpreator + "时,PeekType()等于-1,则表示两项都是null,出错,返回-1<br/>";
                                    return -1;
                                }

                                //表示放得是node
                                if (oReversePolandStack.PeekType() == 0)
                                {
                                    XmlElement nodePop;
                                    nodePop = oReversePolandStack.PopNode();
                                    if (nodePop == null)
                                    {
                                        strError = "nodePop不为又能为null";
                                        return -1;
                                    }

                                    DpResultSet temp = oSource[j];
                                    // return:
                                    //		-1	出错
                                    //		-6	无权限
                                    //		0	成功
                                    ret = this.DoQuery(
                                        sessioninfo,
                                        strOutputStyle,
                                        nodePop,
                                        ref temp,
                                        handle,
                                        // isConnected,
                                        out strError);
                                    if (ret <= -1)
                                        return ret;
                                    if (temp != oSource[j])
                                    {
                                        // 2014/3/11
                                        if (oSource[j] != null)
                                            oSource[j].Close();
                                        oSource[j] = temp;
                                    }
                                }
                                else
                                {
                                    DpResultSet temp = oReversePolandStack.PopResultSet();
                                    Debug.Assert(temp != oSource[j], "");

                                    // 2014/3/11
                                    if (oSource[j] != null)
                                        oSource[j].Close();
                                    oSource[j] = temp;

                                    if (oSource[j] == null)
                                    {
                                        strError = "PopResultSet() return null";
                                        return -1;
                                    }
                                }
                            }
                        }
                        catch (StackUnderflowException /*ex*/)
                        {
                            // 2008/12/4
                            string strOutXml = "";
                            if (node.ParentNode != null)
                            {
                                int nRet = DomUtil.GetIndentXml(node.ParentNode.OuterXml,
                                    out strOutXml,
                                    out strError);
                            }
                            strError = strOpreator + " 是二元操作符,它缺乏操作数。";

                            if (String.IsNullOrEmpty(strOutXml) == false)
                                strError += "\r\n" + strOutXml;

                            // strError = "StackUnderflowException :" + ex.Message;
                            return -1;
                        }

                        // string strDebugInfo;

                        //OR,AND,SUB运算都是调的DpResultSetManager.Merge()函数,
                        //注意参数的使用
                        if (strOpreator == "OR")
                        {
                            bool bOutputKeyCount = StringUtil.IsInList("keycount", strOutputStyle);
                            bool bOutputKeyID = StringUtil.IsInList("keyid", strOutputStyle);

                            DpResultSet left = oSource[1];
                            DpResultSet right = oSource[0];

#if DEBUG
                            Debug.Assert(left.IsClosed == false, "");
                            Debug.Assert(right.IsClosed == false, "");
#endif

                            {
                                // 直接相加
                                if (left.Count == 0)
                                {
                                    oReversePolandStack.PushResultSet(
                                        right
                                        );
                                    // 2014/3/11
                                    Debug.Assert(left != right, "");
                                    left.Close();
                                }
                                else if (right.Count == 0)
                                {
                                    oReversePolandStack.PushResultSet(
                                        left
                                        );
                                    // 2014/3/11
                                    Debug.Assert(left != right, "");
                                    right.Close();
                                }
                                else
                                {
                                    if (EnsureSorted(left, handle, out strError) == -1)
                                        return -1;
                                    if (EnsureSorted(right, handle, out strError) == -1)
                                        return -1;
                                    // return:
                                    //      -1  出错
                                    //      0   没有交叉部分
                                    //      1   有交叉部分
                                    ret = DpResultSetManager.IsCross(left,
                                        right,
                                        out strError);
                                    if (ret == -1)
                                        return -1;
                                    if (ret == 0)
                                    {
                                        DpResultSet left_save = left;
                                        // 注意:函数执行过程,可能交换 left 和 right。也就是说返回后, left == right
                                        ret = DpResultSetManager.AddResults(ref left,
                                            right,
                                            out strError);
                                        if (ret == -1)
                                            return -1;

                                        oReversePolandStack.PushResultSet(
                                            left
                                            );
                                        // 2014/3/11
                                        if (left != right)
                                        {
                                            Debug.Assert(left_save == left, "");
                                            right.Close();
                                        }
                                        else
                                        {
                                            Debug.Assert(left_save != left, "");
                                            left_save.Close();
                                        }
                                    }
                                    else
                                    {
                                        if (left.Asc != right.Asc)
                                        {
                                            right.Asc = left.Asc;
                                            right.Sorted = false;
                                        }

                                        if (EnsureSorted(left, handle, out strError) == -1)
                                            return -1;
                                        if (EnsureSorted(right, handle, out strError) == -1)
                                            return -1;

                                        {
                                            DpResultSet oTargetMiddle = sessioninfo.NewResultSet();   // new DpResultSet();
                                            StringBuilder debugInfo = null;
                                            ret = DpResultSetManager.Merge(LogicOper.OR,
        left,
        right,
        strOutputStyle,
        null,
        oTargetMiddle,
        null,
                                                // false,
        querystop,
        handle,
        ref debugInfo,
        out strError);
                                            if (ret == -1)
                                                return -1;

                                            oReversePolandStack.PushResultSet(oTargetMiddle);
                                            // 2014/3/11
                                            Debug.Assert(left != oTargetMiddle, "");
                                            Debug.Assert(right != oTargetMiddle, "");
                                            left.Close();
                                            right.Close();
                                        }
                                    }
                                }
                            }

                            continue;
                        }

                        if (strOpreator == "AND")
                        {
                            DpResultSet left = oSource[1];
                            DpResultSet right = oSource[0];
#if DEBUG
                            Debug.Assert(left.IsClosed == false, "");
                            Debug.Assert(right.IsClosed == false, "");
#endif

                            if (left.Asc != right.Asc)
                            {
                                right.Asc = left.Asc;
                                right.Sorted = false;
                            }

                            if (EnsureSorted(left, handle, out strError) == -1)
                                return -1;
                            if (EnsureSorted(right, handle, out strError) == -1)
                                return -1;

                            // 优化
                            if (left.Count == 0)
                            {
                                oReversePolandStack.PushResultSet(
                                    left
                                    );
                                // 2014/3/11
                                Debug.Assert(left != right, "");
                                right.Close();
                            }
                            else if (right.Count == 0)
                            {
                                oReversePolandStack.PushResultSet(
                                    right
                                    );
                                // 2014/3/11
                                Debug.Assert(left != right, "");
                                left.Close();
                            }
                            else
                            {
                                DpResultSet oTargetMiddle = sessioninfo.NewResultSet();   // new DpResultSet();

                                StringBuilder debugInfo = null;

                                ret = DpResultSetManager.Merge(LogicOper.AND,
                                    left,
                                    right,
                                    strOutputStyle,
                                    null,    //oTargetLeft
                                    oTargetMiddle,
                                    null,   //oTargetRight
                                    // false,
                                    querystop,
                                    handle,
                                    ref debugInfo,
                                    out strError);
                                if (ret == -1)
                                    return -1;

                                oReversePolandStack.PushResultSet(oTargetMiddle);
                                // 2014/3/11
                                Debug.Assert(left != oTargetMiddle, "");
                                Debug.Assert(right != oTargetMiddle, "");
                                left.Close();
                                right.Close();
                            }

                            continue;
                        }

                        if (strOpreator == "SUB")
                        {
                            //因为使用从栈里pop,所以第0个是后面的,第1个是前面的
                            DpResultSet left = oSource[1];
                            DpResultSet right = oSource[0];
#if DEBUG
                            Debug.Assert(left.IsClosed == false, "");
                            Debug.Assert(right.IsClosed == false, "");
#endif

                            if (left.Asc != right.Asc)
                            {
                                right.Asc = left.Asc;
                                right.Sorted = false;
                            }

                            if (EnsureSorted(left, handle, out strError) == -1)
                                return -1;
                            if (EnsureSorted(right, handle, out strError) == -1)
                                return -1;

                            // 优化
                            if (left.Count == 0)
                            {
                                oReversePolandStack.PushResultSet(
                                    left
                                    );
                                // 2014/3/11
                                Debug.Assert(left != right, "");
                                right.Close();
                            }
                            else if (right.Count == 0)
                            {
                                oReversePolandStack.PushResultSet(
                                    left
                                    );
                                // 2014/3/11
                                Debug.Assert(left != right, "");
                                right.Close();
                            }
                            else
                            {
                                DpResultSet oTargetLeft = sessioninfo.NewResultSet();   // new DpResultSet();

                                StringBuilder debugInfo = null;

                                ret = DpResultSetManager.Merge(LogicOper.SUB,
                                    left,
                                    right,
                                    strOutputStyle,
                                    oTargetLeft,
                                    null, //oTargetMiddle
                                    null, //oTargetRight
                                    // false,
                                    querystop,
                                    handle,
                                    ref debugInfo,
                                    out strError);
                                if (ret == -1)
                                {
                                    return -1;
                                }

                                oReversePolandStack.PushResultSet(oTargetLeft);
                                // 2014/3/11
                                Debug.Assert(left != oTargetLeft, "");
                                Debug.Assert(right != oTargetLeft, "");
                                left.Close();
                                right.Close();
                            }

                            continue;
                        }
                    }
                }
                if (oReversePolandStack.Count > 1)
                {
                    strError = "逆波兰出错";
                    return -1;
                }
                try
                {
                    int nTemp = oReversePolandStack.PeekType();
                    //如果类型为0,表示存放的是节点
                    if (nTemp == 0)
                    {
                        XmlElement node = oReversePolandStack.PopNode();

                        // return:
                        //		-1	出错
                        //		-6	无权限
                        //		0	成功
                        ret = this.DoQuery(
                            sessioninfo,
                            strOutputStyle,
                            node,
                            ref resultSet,
                            handle,
                            // isConnected,
                            out strError);
                        if (ret <= -1)
                            return ret;
                    }
                    else if (nTemp == 1)
                    {
                        // 调DpResultSet的copy函数

                        // TODO: 测算这个Copy所花费的时间。
                        // resultSet.Copy((DpResultSet)(oReversePolandStack.PopResultSet()));
                        resultSet = (DpResultSet)(oReversePolandStack.PopResultSet());
                    }
                    else
                    {
                        strError = "oReversePolandStack的类型不可能为" + Convert.ToString(nTemp);
                        return -1;
                    }
                }
                catch (StackUnderflowException)
                {
                    strError = "peek或pop时,抛出StackUnderflowException异常";
                    return -1;
                }

                //最后结果集为null,返回出错
                if (resultSet == null)
                {
                    strError = "运算结束后PopResultSet为null" + Convert.ToString(oReversePolandStack.PeekType());
                    return -1;
                }

                return 0;
            }
            finally
            {
                TimeSpan delta = DateTime.Now - start_time;
                Debug.WriteLine("End ProceedRPN() 耗时 " + delta.ToString());
            }
        }