// 运算逆波兰表,得到结果集 // 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); }
// 运算逆波兰表,得到结果集 // 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()); } }