QueryProcessor.cs 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122
  1. //------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //------------------------------------------------------------
  4. namespace System.ServiceModel.Dispatcher
  5. {
  6. using System.Collections.Generic;
  7. using System.Collections.ObjectModel;
  8. using System.Runtime;
  9. using System.ServiceModel.Channels;
  10. using System.ServiceModel.Diagnostics;
  11. using System.Threading;
  12. class ProcessingContext
  13. {
  14. internal ProcessingContext next; // for chaining together in free lists
  15. int nodeCount;
  16. QueryProcessor processor;
  17. EvalStack sequenceStack;
  18. EvalStack valueStack;
  19. internal ProcessingContext()
  20. {
  21. this.valueStack = new EvalStack(2, 4);
  22. this.sequenceStack = new EvalStack(1, 2);
  23. this.nodeCount = -1;
  24. }
  25. #if NO
  26. internal int FrameCount
  27. {
  28. get
  29. {
  30. return this.valueStack.FrameCount;
  31. }
  32. }
  33. internal int FramePtr
  34. {
  35. get
  36. {
  37. return this.valueStack.FramePtr;
  38. }
  39. }
  40. #endif
  41. internal StackFrame this[int frameIndex]
  42. {
  43. get
  44. {
  45. return this.valueStack[frameIndex];
  46. }
  47. }
  48. internal int IterationCount
  49. {
  50. get
  51. {
  52. if (-1 == this.nodeCount)
  53. {
  54. this.nodeCount = this.sequenceStack.CalculateNodecount();
  55. if (this.nodeCount == 0 && !this.sequenceStack.InUse)
  56. {
  57. this.nodeCount = 1;
  58. }
  59. }
  60. return this.nodeCount;
  61. }
  62. }
  63. internal int NodeCount
  64. {
  65. get
  66. {
  67. return this.nodeCount;
  68. }
  69. set
  70. {
  71. this.nodeCount = value;
  72. }
  73. }
  74. internal ProcessingContext Next
  75. {
  76. get
  77. {
  78. return this.next;
  79. }
  80. set
  81. {
  82. this.next = value;
  83. }
  84. }
  85. internal QueryProcessor Processor
  86. {
  87. get
  88. {
  89. return this.processor;
  90. }
  91. set
  92. {
  93. this.processor = value;
  94. }
  95. }
  96. internal StackFrame SecondArg
  97. {
  98. get
  99. {
  100. return this.valueStack.SecondArg;
  101. }
  102. }
  103. internal Value[] Sequences
  104. {
  105. get
  106. {
  107. return this.sequenceStack.Buffer;
  108. }
  109. }
  110. internal bool SequenceStackInUse
  111. {
  112. get
  113. {
  114. return this.sequenceStack.InUse;
  115. }
  116. }
  117. internal bool StacksInUse
  118. {
  119. get
  120. {
  121. return (this.valueStack.frames.Count > 0 || this.sequenceStack.frames.Count > 0);
  122. }
  123. }
  124. internal StackFrame TopArg
  125. {
  126. get
  127. {
  128. return this.valueStack.TopArg;
  129. }
  130. }
  131. internal StackFrame TopSequenceArg
  132. {
  133. get
  134. {
  135. return this.sequenceStack.TopArg;
  136. }
  137. }
  138. internal Value[] Values
  139. {
  140. get
  141. {
  142. return this.valueStack.Buffer;
  143. }
  144. }
  145. internal ProcessingContext Clone()
  146. {
  147. return this.processor.CloneContext(this);
  148. }
  149. internal void ClearContext()
  150. {
  151. this.sequenceStack.Clear();
  152. this.valueStack.Clear();
  153. this.nodeCount = -1;
  154. }
  155. internal void CopyFrom(ProcessingContext context)
  156. {
  157. Fx.Assert(null != context, "");
  158. this.processor = context.processor;
  159. if (context.sequenceStack.frames.Count > 0)
  160. {
  161. this.sequenceStack.CopyFrom(ref context.sequenceStack);
  162. }
  163. else
  164. {
  165. this.sequenceStack.Clear();
  166. }
  167. if (context.valueStack.frames.Count > 0)
  168. {
  169. this.valueStack.CopyFrom(ref context.valueStack);
  170. }
  171. else
  172. {
  173. this.valueStack.Clear();
  174. }
  175. this.nodeCount = context.nodeCount;
  176. }
  177. internal NodeSequence CreateSequence()
  178. {
  179. NodeSequence sequence = this.processor.PopSequence();
  180. if (null == sequence)
  181. {
  182. sequence = new NodeSequence();
  183. }
  184. sequence.OwnerContext = this;
  185. sequence.refCount++;
  186. return sequence;
  187. }
  188. internal bool LoadVariable(int var)
  189. {
  190. return this.Processor.LoadVariable(this, var);
  191. }
  192. internal void EvalCodeBlock(Opcode block)
  193. {
  194. this.processor.Eval(block, this);
  195. }
  196. internal bool PeekBoolean(int index)
  197. {
  198. return this.valueStack.PeekBoolean(index);
  199. }
  200. internal double PeekDouble(int index)
  201. {
  202. return this.valueStack.PeekDouble(index);
  203. }
  204. #if NO
  205. internal int PeekInteger(int index)
  206. {
  207. return (int) this.valueStack.PeekInteger(index);
  208. }
  209. #endif
  210. internal NodeSequence PeekSequence(int index)
  211. {
  212. return this.valueStack.PeekSequence(index);
  213. }
  214. internal string PeekString(int index)
  215. {
  216. return this.valueStack.PeekString(index);
  217. }
  218. internal void PopFrame()
  219. {
  220. this.valueStack.PopFrame(this);
  221. }
  222. internal void PopSequenceFrame()
  223. {
  224. this.sequenceStack.PopFrame(this);
  225. this.nodeCount = -1;
  226. }
  227. internal void PopContextSequenceFrame()
  228. {
  229. PopSequenceFrame();
  230. if (!this.sequenceStack.InUse)
  231. this.sequenceStack.contextOnTopOfStack = false;
  232. }
  233. internal void Push(bool boolVal)
  234. {
  235. this.valueStack.Push(boolVal);
  236. }
  237. internal void Push(bool boolVal, int addCount)
  238. {
  239. this.valueStack.Push(boolVal, addCount);
  240. }
  241. #if NO
  242. internal void Push(double doubleVal)
  243. {
  244. this.valueStack.Push(doubleVal);
  245. }
  246. #endif
  247. internal void Push(double doubleVal, int addCount)
  248. {
  249. this.valueStack.Push(doubleVal, addCount);
  250. }
  251. internal void Push(NodeSequence sequence)
  252. {
  253. this.valueStack.Push(sequence);
  254. }
  255. internal void Push(NodeSequence sequence, int addCount)
  256. {
  257. this.valueStack.Push(sequence, addCount);
  258. }
  259. internal void Push(string stringVal)
  260. {
  261. this.valueStack.Push(stringVal);
  262. }
  263. internal void Push(string stringVal, int addCount)
  264. {
  265. this.valueStack.Push(stringVal, addCount);
  266. }
  267. internal void PushFrame()
  268. {
  269. this.valueStack.PushFrame();
  270. }
  271. internal void PopSequenceFrameToValueStack()
  272. {
  273. this.sequenceStack.PopSequenceFrameTo(ref this.valueStack);
  274. this.nodeCount = -1;
  275. }
  276. internal void PushSequence(NodeSequence seq)
  277. {
  278. this.sequenceStack.Push(seq);
  279. this.nodeCount = -1;
  280. }
  281. internal void PushSequenceFrame()
  282. {
  283. this.sequenceStack.PushFrame();
  284. this.nodeCount = -1;
  285. }
  286. internal void PushContextSequenceFrame()
  287. {
  288. if (!this.sequenceStack.InUse)
  289. this.sequenceStack.contextOnTopOfStack = true;
  290. PushSequenceFrame();
  291. }
  292. internal void PushSequenceFrameFromValueStack()
  293. {
  294. this.valueStack.PopSequenceFrameTo(ref this.sequenceStack);
  295. this.nodeCount = -1;
  296. }
  297. internal void ReleaseSequence(NodeSequence sequence)
  298. {
  299. Fx.Assert(null != sequence, "");
  300. if (this == sequence.OwnerContext)
  301. {
  302. sequence.refCount--;
  303. Fx.Assert(sequence.refCount >= 0, "");
  304. if (0 == sequence.refCount)
  305. {
  306. this.processor.ReleaseSequenceToPool(sequence);
  307. }
  308. }
  309. }
  310. internal void Release()
  311. {
  312. this.processor.ReleaseContext(this);
  313. }
  314. internal void ReplaceSequenceAt(int index, NodeSequence sequence)
  315. {
  316. this.sequenceStack.ReplaceAt(index, sequence);
  317. this.nodeCount = -1;
  318. }
  319. internal void SaveVariable(int var, int count)
  320. {
  321. this.Processor.SaveVariable(this, var, count);
  322. }
  323. internal void SetValue(ProcessingContext context, int index, bool val)
  324. {
  325. this.valueStack.SetValue(this, index, val);
  326. }
  327. internal void SetValue(ProcessingContext context, int index, double val)
  328. {
  329. this.valueStack.SetValue(this, index, val);
  330. }
  331. internal void SetValue(ProcessingContext context, int index, string val)
  332. {
  333. this.valueStack.SetValue(this, index, val);
  334. }
  335. internal void SetValue(ProcessingContext context, int index, NodeSequence val)
  336. {
  337. this.valueStack.SetValue(this, index, val);
  338. }
  339. internal void TransferSequenceSize()
  340. {
  341. this.sequenceStack.TransferSequenceSizeTo(ref this.valueStack);
  342. }
  343. internal void TransferSequencePositions()
  344. {
  345. this.sequenceStack.TransferPositionsTo(ref this.valueStack);
  346. }
  347. #region IQueryBufferPool Members
  348. #if NO
  349. public virtual void Reset()
  350. {
  351. this.valueStack.Clear();
  352. this.valueStack.Trim();
  353. this.sequenceStack.Clear();
  354. this.sequenceStack.Trim();
  355. }
  356. public virtual void Trim()
  357. {
  358. this.valueStack.Trim();
  359. this.sequenceStack.Trim();
  360. }
  361. #endif
  362. #endregion
  363. }
  364. internal enum QueryProcessingFlags : byte
  365. {
  366. None = 0x00,
  367. Match = 0x01,
  368. Message = 0x02,
  369. //Select = 0x04,
  370. }
  371. internal class QueryProcessor : ProcessingContext
  372. {
  373. SeekableXPathNavigator contextNode; // original context node off which everything started
  374. ProcessingContext contextPool;
  375. INodeCounter counter;
  376. QueryProcessingFlags flags;
  377. QueryMatcher matcher;
  378. Message message;
  379. bool matchMessageBody;
  380. int refCount;
  381. bool result; // for singleton matches...
  382. XPathResult queryResult; // for singleton queries...
  383. QueryBranchResultSet resultPool;
  384. Collection<MessageFilter> matchList;
  385. ICollection<MessageFilter> matchSet; // for inverse queries that produce multiple matches
  386. ICollection<KeyValuePair<MessageQuery, XPathResult>> resultSet; // for inverse queries that produce multiple query results
  387. NodeSequence sequencePool;
  388. //string selectResults;
  389. SubExprVariable[] subExprVars;
  390. string messageAction;
  391. //string messageAddress;
  392. //string messageVia;
  393. string messageId;
  394. string messageSoapUri;
  395. string messageTo;
  396. internal QueryProcessor(QueryMatcher matcher)
  397. : base()
  398. {
  399. this.Processor = this;
  400. this.matcher = matcher;
  401. this.flags = QueryProcessingFlags.Match;
  402. // PERF, [....], see if we can just let these to their default init
  403. this.messageAction = null;
  404. //this.messageAddress = null;
  405. //this.messageVia = null;
  406. this.messageId = null;
  407. this.messageSoapUri = null;
  408. this.messageTo = null;
  409. if (matcher.SubExprVarCount > 0)
  410. {
  411. this.subExprVars = new SubExprVariable[matcher.SubExprVarCount];
  412. }
  413. }
  414. internal string Action
  415. {
  416. get
  417. {
  418. return this.messageAction;
  419. }
  420. set
  421. {
  422. this.messageAction = value;
  423. }
  424. }
  425. #if NO
  426. internal string Address
  427. {
  428. get
  429. {
  430. return this.messageAddress;
  431. }
  432. set
  433. {
  434. this.messageAddress = value;
  435. }
  436. }
  437. #endif
  438. // IMPORTANT: Either ContextNode.get or CounterMarker.get MUST be called before this.counter
  439. // can be considered valid.
  440. internal SeekableXPathNavigator ContextNode
  441. {
  442. get
  443. {
  444. if (null == this.contextNode)
  445. {
  446. if (null != this.message)
  447. {
  448. this.contextNode = this.matcher.CreateMessageNavigator(this.message, this.matchMessageBody);
  449. }
  450. else
  451. {
  452. #pragma warning suppress 56503 // [....], property is more readable for this
  453. throw DiagnosticUtility.ExceptionUtility.ThrowHelperCritical(new QueryProcessingException(QueryProcessingError.Unexpected));
  454. }
  455. this.counter = this.contextNode as INodeCounter;
  456. if (null == this.counter)
  457. {
  458. this.counter = DummyNodeCounter.Dummy;
  459. }
  460. }
  461. return this.contextNode;
  462. }
  463. set
  464. {
  465. this.contextNode = value;
  466. this.counter = value as INodeCounter;
  467. }
  468. }
  469. internal Message ContextMessage
  470. {
  471. get
  472. {
  473. return this.message;
  474. }
  475. set
  476. {
  477. this.message = value;
  478. if (null != value)
  479. {
  480. this.flags |= QueryProcessingFlags.Message;
  481. }
  482. else
  483. {
  484. this.flags &= ~QueryProcessingFlags.Message;
  485. }
  486. }
  487. }
  488. // IMPORTANT: Either ContextNode.get or CounterMarker.get MUST be called before this.counter
  489. // can be considered valid.
  490. internal int CounterMarker
  491. {
  492. get
  493. {
  494. if (this.counter == null)
  495. {
  496. this.counter = this.ContextNode as INodeCounter;
  497. if (this.counter == null)
  498. this.counter = DummyNodeCounter.Dummy;
  499. }
  500. return this.counter.CounterMarker;
  501. }
  502. set
  503. {
  504. this.counter.CounterMarker = value;
  505. }
  506. }
  507. #if NO
  508. internal QueryProcessingFlags Flags
  509. {
  510. get
  511. {
  512. return this.flags;
  513. }
  514. }
  515. internal bool HasContextNode
  516. {
  517. get
  518. {
  519. return (null != this.contextNode);
  520. }
  521. }
  522. #endif
  523. internal bool MatchBody
  524. {
  525. #if NO
  526. get
  527. {
  528. return this.matchMessageBody;
  529. }
  530. #endif
  531. set
  532. {
  533. this.matchMessageBody = value;
  534. }
  535. }
  536. internal QueryMatcher Matcher
  537. {
  538. get
  539. {
  540. return this.matcher;
  541. }
  542. }
  543. internal ICollection<KeyValuePair<MessageQuery, XPathResult>> ResultSet
  544. {
  545. get
  546. {
  547. return this.resultSet;
  548. }
  549. set
  550. {
  551. this.resultSet = value;
  552. }
  553. }
  554. internal string MessageId
  555. {
  556. get
  557. {
  558. return this.messageId;
  559. }
  560. set
  561. {
  562. this.messageId = value;
  563. }
  564. }
  565. internal bool Result
  566. {
  567. get
  568. {
  569. return this.result;
  570. }
  571. set
  572. {
  573. this.result = value;
  574. }
  575. }
  576. internal XPathResult QueryResult
  577. {
  578. get
  579. {
  580. return this.queryResult;
  581. }
  582. set
  583. {
  584. this.queryResult = value;
  585. }
  586. }
  587. internal Collection<MessageFilter> MatchList
  588. {
  589. get
  590. {
  591. return this.matchList;
  592. }
  593. }
  594. internal ICollection<MessageFilter> MatchSet
  595. {
  596. get
  597. {
  598. return this.matchSet;
  599. }
  600. set
  601. {
  602. this.matchSet = value;
  603. }
  604. }
  605. internal string SoapUri
  606. {
  607. get
  608. {
  609. return this.messageSoapUri;
  610. }
  611. set
  612. {
  613. this.messageSoapUri = value;
  614. }
  615. }
  616. internal string ToHeader
  617. {
  618. get
  619. {
  620. return this.messageTo;
  621. }
  622. set
  623. {
  624. this.messageTo = value;
  625. }
  626. }
  627. #if NO
  628. internal string Via
  629. {
  630. get
  631. {
  632. return this.messageVia;
  633. }
  634. set
  635. {
  636. this.messageVia = value;
  637. }
  638. }
  639. #endif
  640. internal void AddRef()
  641. {
  642. Interlocked.Increment(ref this.refCount);
  643. }
  644. internal void ClearProcessor()
  645. {
  646. base.ClearContext();
  647. this.flags = QueryProcessingFlags.Match;
  648. this.messageAction = null;
  649. //this.messageAddress = null;
  650. //this.messageVia = null;
  651. this.messageId = null;
  652. this.messageSoapUri = null;
  653. this.messageTo = null;
  654. int exprCount = this.matcher.SubExprVarCount;
  655. if (exprCount == 0)
  656. {
  657. // No vars. Recycle entire subexpression cache
  658. this.subExprVars = null;
  659. return;
  660. }
  661. SubExprVariable[] vars = this.subExprVars; // save locally for speed
  662. if (vars == null)
  663. {
  664. // Allocate space for sub-expressions
  665. this.subExprVars = new SubExprVariable[exprCount];
  666. return;
  667. }
  668. int varCount = vars.Length;
  669. // The # of subexpressions changed since this processor was last used.
  670. if (varCount != exprCount)
  671. {
  672. this.subExprVars = new SubExprVariable[exprCount];
  673. return;
  674. }
  675. if (varCount == 1)
  676. {
  677. NodeSequence seq = vars[0].seq;
  678. if (seq != null)
  679. {
  680. this.ReleaseSequenceToPool(seq);
  681. }
  682. return;
  683. }
  684. // We can reuse the sub-expression cache
  685. // Clear out the sub-expression results from an earlier run, and return sequences to pool
  686. for (int i = 0; i < varCount; ++i)
  687. {
  688. NodeSequence seq = vars[i].seq;
  689. if (seq != null && seq.refCount > 0)
  690. {
  691. this.ReleaseSequenceToPool(seq);
  692. }
  693. }
  694. Array.Clear(vars, 0, vars.Length);
  695. }
  696. internal ProcessingContext CloneContext(ProcessingContext srcContext)
  697. {
  698. ProcessingContext context = this.PopContext();
  699. if (null == context)
  700. {
  701. context = new ProcessingContext();
  702. }
  703. context.CopyFrom(srcContext);
  704. return context;
  705. }
  706. internal QueryBranchResultSet CreateResultSet()
  707. {
  708. QueryBranchResultSet resultSet = this.PopResultSet();
  709. if (null == resultSet)
  710. {
  711. resultSet = new QueryBranchResultSet();
  712. }
  713. else
  714. {
  715. resultSet.Clear();
  716. }
  717. return resultSet;
  718. }
  719. internal int ElapsedCount(int marker)
  720. {
  721. return this.counter.ElapsedCount(marker);
  722. }
  723. internal void EnsureFilterCollection()
  724. {
  725. this.resultSet = null;
  726. if (null == this.matchSet)
  727. {
  728. if (null == this.matchList)
  729. {
  730. this.matchList = new Collection<MessageFilter>();
  731. }
  732. else
  733. {
  734. this.matchList.Clear();
  735. }
  736. this.matchSet = this.matchList;
  737. }
  738. }
  739. internal void Eval(Opcode block)
  740. {
  741. Opcode op = block;
  742. try
  743. {
  744. // Walk over and evaulate the entire trace
  745. while (null != op)
  746. {
  747. op = op.Eval(this);
  748. }
  749. }
  750. catch (XPathNavigatorException e)
  751. {
  752. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(e.Process(op));
  753. }
  754. catch (NavigatorInvalidBodyAccessException e)
  755. {
  756. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(e.Process(op));
  757. }
  758. }
  759. internal void Eval(Opcode block, ProcessingContext context)
  760. {
  761. Opcode op = block;
  762. try
  763. {
  764. // Walk over and evaulate the entire trace
  765. while (null != op)
  766. {
  767. op = op.Eval(context);
  768. }
  769. }
  770. catch (XPathNavigatorException e)
  771. {
  772. throw TraceUtility.ThrowHelperError(e.Process(op), this.message);
  773. }
  774. catch (NavigatorInvalidBodyAccessException e)
  775. {
  776. throw TraceUtility.ThrowHelperError(e.Process(op), this.message);
  777. }
  778. }
  779. //
  780. // Set up the query processor to match messages
  781. //
  782. internal void Eval(Opcode block, Message message, bool matchBody)
  783. {
  784. this.result = false;
  785. this.ContextNode = null;
  786. this.ContextMessage = message;
  787. this.MatchBody = matchBody;
  788. this.Eval(block);
  789. this.message = null;
  790. this.contextNode = null;
  791. }
  792. internal void Eval(Opcode block, SeekableXPathNavigator navigator)
  793. {
  794. this.result = false;
  795. this.ContextNode = navigator;
  796. this.ContextMessage = null;
  797. this.Eval(block);
  798. }
  799. internal bool LoadVariable(ProcessingContext context, int var)
  800. {
  801. if (this.subExprVars[var].seq == null)
  802. {
  803. return false;
  804. }
  805. int iter = context.IterationCount;
  806. this.counter.IncreaseBy(iter * this.subExprVars[var].count);
  807. NodeSequence seq = this.subExprVars[var].seq;
  808. context.PushSequenceFrame();
  809. for (int i = 0; i < iter; ++i)
  810. {
  811. seq.refCount++;
  812. context.PushSequence(seq);
  813. }
  814. return true;
  815. }
  816. internal ProcessingContext PopContext()
  817. {
  818. ProcessingContext context = this.contextPool;
  819. if (null != context)
  820. {
  821. this.contextPool = context.Next;
  822. context.Next = null;
  823. }
  824. return context;
  825. }
  826. internal NodeSequence PopSequence()
  827. {
  828. NodeSequence sequence = this.sequencePool;
  829. if (null != sequence)
  830. {
  831. this.sequencePool = sequence.Next;
  832. sequence.Next = null;
  833. }
  834. return sequence;
  835. }
  836. internal QueryBranchResultSet PopResultSet()
  837. {
  838. QueryBranchResultSet resultSet = this.resultPool;
  839. if (null != resultSet)
  840. {
  841. this.resultPool = resultSet.Next;
  842. resultSet.Next = null;
  843. }
  844. return resultSet;
  845. }
  846. internal void PushContext(ProcessingContext context)
  847. {
  848. Fx.Assert(null != context, "");
  849. context.Next = this.contextPool;
  850. this.contextPool = context;
  851. }
  852. internal void PushResultSet(QueryBranchResultSet resultSet)
  853. {
  854. Fx.Assert(null != resultSet, "");
  855. resultSet.Next = this.resultPool;
  856. this.resultPool = resultSet;
  857. }
  858. internal bool ReleaseRef()
  859. {
  860. return (Interlocked.Decrement(ref this.refCount) == 0);
  861. }
  862. internal void ReleaseContext(ProcessingContext context)
  863. {
  864. Fx.Assert(null != context, "");
  865. this.PushContext(context);
  866. }
  867. internal void ReleaseResults(QueryBranchResultSet resultSet)
  868. {
  869. Fx.Assert(null != resultSet, "");
  870. this.PushResultSet(resultSet);
  871. }
  872. internal void ReleaseSequenceToPool(NodeSequence sequence)
  873. {
  874. if (NodeSequence.Empty != sequence)
  875. {
  876. sequence.Reset(this.sequencePool);
  877. this.sequencePool = sequence;
  878. }
  879. }
  880. internal void SaveVariable(ProcessingContext context, int var, int count)
  881. {
  882. NodeSequence seq = context.Sequences[context.TopSequenceArg.basePtr].Sequence;
  883. if (seq == null)
  884. seq = CreateSequence();
  885. seq.OwnerContext = null;
  886. this.subExprVars[var].seq = seq;
  887. this.subExprVars[var].count = count;
  888. }
  889. #region IQueryBufferPool Members
  890. #if NO
  891. public override void Reset()
  892. {
  893. base.Release();
  894. // Trim local pools by releasing all references
  895. while (null != this.PopResultSet());
  896. this.resultPool = null;
  897. while (null != this.PopSequence());
  898. this.sequencePool = null;
  899. while (null != this.PopContext());
  900. this.contextPool = null;
  901. }
  902. public override void Trim()
  903. {
  904. // Trim stacks
  905. base.Trim();
  906. // Trim local pools individually
  907. QueryBranchResultSet result = this.resultPool;
  908. while (null != result)
  909. {
  910. result.Trim();
  911. result = result.Next;
  912. }
  913. NodeSequence sequence = this.sequencePool;
  914. while (null != sequencePool)
  915. {
  916. sequencePool.Trim();
  917. sequence = sequence.Next;
  918. }
  919. ProcessingContext context = this.contextPool;
  920. while (null != context)
  921. {
  922. context.Trim();
  923. context = context.Next;
  924. }
  925. }
  926. #endif
  927. #endregion
  928. struct SubExprVariable
  929. {
  930. internal NodeSequence seq;
  931. internal int count;
  932. }
  933. }
  934. #if NO
  935. internal struct QueryStatistics
  936. {
  937. int backupCapacity;
  938. int nodeCapacity;
  939. int seqStackCapacity;
  940. int seqFrameCapacity;
  941. int valFrameCapacity;
  942. int valStackCapacity;
  943. internal QueryStatistics()
  944. {
  945. this.backupCapacity = 8;
  946. this.nodeCapacity = 8;
  947. this.seqFrameCapacity = 2;
  948. this.seqStackCapacity = 4;
  949. this.valFrameCapacity = 2;
  950. this.valStackCapacity = 4;
  951. }
  952. internal int BackupCapacity
  953. {
  954. get
  955. {
  956. return this.backupCapacity;
  957. }
  958. }
  959. internal int NodeCapacity
  960. {
  961. get
  962. {
  963. return this.nodeCapacity;
  964. }
  965. }
  966. internal int SeqFrameCapacity
  967. {
  968. get
  969. {
  970. return this.seqFrameCapacity;
  971. }
  972. }
  973. internal int SeqStackCapacity
  974. {
  975. get
  976. {
  977. return this.seqStackCapacity;
  978. }
  979. }
  980. internal int ValFrameCapacity
  981. {
  982. get
  983. {
  984. return this.valFrameCapacity;
  985. }
  986. }
  987. internal int ValStackCapacity
  988. {
  989. get
  990. {
  991. return this.valStackCapacity;
  992. }
  993. }
  994. }
  995. #endif
  996. }