1 /* 2 * [The "BSD licence"] 3 * Copyright (c) 2005-2008 Terence Parr 4 * All rights reserved. 5 * 6 * Conversion to C#: 7 * Copyright (c) 2008-2009 Sam Harwell, Pixel Mine, Inc. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 namespace Antlr.Runtime.Misc { 34 using System.Collections.Generic; 35 using ArgumentException = System.ArgumentException; 36 using InvalidOperationException = System.InvalidOperationException; 37 38 /** A queue that can dequeue and get(i) in O(1) and grow arbitrarily large. 39 * A linked list is fast at dequeue but slow at get(i). An array is 40 * the reverse. This is O(1) for both operations. 41 * 42 * List grows until you dequeue last element at end of buffer. Then 43 * it resets to start filling at 0 again. If adds/removes are balanced, the 44 * buffer will not grow too large. 45 * 46 * No iterator stuff as that's not how we'll use it. 47 */ 48 public class FastQueue<T> { 49 /** <summary>dynamically-sized buffer of elements</summary> */ 50 internal List<T> _data = new List<T>(); 51 /** <summary>index of next element to fill</summary> */ 52 internal int _p = 0; 53 54 public virtual int Count { 55 get { 56 return _data.Count - _p; 57 } 58 } 59 60 /// <summary> 61 /// How deep have we gone? 62 /// </summary> 63 public virtual int Range { 64 get; 65 protected set; 66 } 67 68 /** <summary> 69 * Return element i elements ahead of current element. i==0 gets 70 * current element. This is not an absolute index into the data list 71 * since p defines the start of the real list. 72 * </summary> 73 */ 74 public virtual T this[int i] { 75 get { 76 int absIndex = _p + i; 77 if (absIndex >= _data.Count) 78 throw new ArgumentException(string.Format("queue index {0} > last index {1}", absIndex, _data.Count - 1)); 79 if (absIndex < 0) 80 throw new ArgumentException(string.Format("queue index {0} < 0", absIndex)); 81 82 if (absIndex > Range) 83 Range = absIndex; 84 85 return _data[absIndex]; 86 } 87 } 88 89 /** <summary>Get and remove first element in queue</summary> */ Dequeue()90 public virtual T Dequeue() { 91 if (Count == 0) 92 throw new InvalidOperationException(); 93 94 T o = this[0]; 95 _p++; 96 // have we hit end of buffer? 97 if (_p == _data.Count) { 98 // if so, it's an opportunity to start filling at index 0 again 99 Clear(); // size goes to 0, but retains memory 100 } 101 return o; 102 } 103 Enqueue(T o)104 public virtual void Enqueue(T o) { 105 _data.Add(o); 106 } 107 Peek()108 public virtual T Peek() { 109 return this[0]; 110 } 111 Clear()112 public virtual void Clear() { 113 _p = 0; 114 _data.Clear(); 115 } 116 117 /** <summary>Return string of current buffer contents; non-destructive</summary> */ ToString()118 public override string ToString() { 119 System.Text.StringBuilder buf = new System.Text.StringBuilder(); 120 int n = Count; 121 for (int i = 0; i < n; i++) { 122 buf.Append(this[i]); 123 if ((i + 1) < n) 124 buf.Append(" "); 125 } 126 return buf.ToString(); 127 } 128 } 129 } 130