3 * Copyright (C) 2012 Maciej Piechotka
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 * Maciej Piechotka <uzytkownik2@gmail.com>
24 * Resizable array implementation of the {@link Deque} interface.
26 * The storage array grows automatically when needed.
28 * This implementation is pretty good for lookups at the end or random.
29 * Because they are stored in an array this structure does not fit for deleting
30 * arbitrary elements. For an alternative implementation see {@link LinkedList}.
34 public class Gee.ArrayQueue<G> : Gee.AbstractQueue<G>, Deque<G> {
36 * Constructs a new, empty array queue.
38 * If not provided, the function parameter is requested to the
39 * {@link Functions} function factory methods.
41 * @param equal_func an optional element equality testing function
43 public ArrayQueue (owned EqualDataFunc<G>? equal_func = null) {
44 if (equal_func == null) {
45 equal_func = Functions.get_equal_func_for (typeof (G));
47 this.equal_func = equal_func;
48 this._items = new G[10];
51 [CCode (notify = false)]
52 public EqualDataFunc<G> equal_func { private set; get; }
57 public override int size { get { return _length; } }
59 public bool is_empty { get { return _length == 0; } }
64 public override bool read_only { get { return false; } }
69 public override int capacity { get {return Queue.UNBOUNDED_CAPACITY;} }
74 public override int remaining_capacity { get {return Queue.UNBOUNDED_CAPACITY;} }
79 public override bool is_full { get { return false; } }
84 public override Gee.Iterator<G> iterator() {
85 return new Iterator<G> (this);
91 public override bool add (G element) {
92 return offer_tail (element);
98 public override bool contains (G item) {
99 return find_index(item) != -1;
105 public override bool remove (G item) {
107 int index = find_index (item);
119 public override void clear() {
121 for (int i = 0; i < _length; i++) {
122 _items[(_start + i) % _items.length] = null;
124 _start = _length = 0;
130 public override G? peek () {
137 public override G? poll () {
144 public bool offer_head (G element) {
146 _start = (_items.length + _start - 1) % _items.length;
148 _items[_start] = element;
156 public G? peek_head () {
157 return _items[_start];
163 public G? poll_head () {
170 G result = (owned)_items[_start];
171 _start = (_start + 1) % _items.length;
172 return (owned)result;
179 public int drain_head (Collection<G> recipient, int amount = -1) {
180 return drain (recipient, amount);
186 public bool offer_tail (G element) {
188 _items[(_start + _length++) % _items.length] = element;
196 public G? peek_tail () {
197 return _items[(_items.length + _start + _length - 1) % _items.length];
203 public G? poll_tail () {
209 return (owned)_items[(_items.length + _start + --_length) % _items.length];
216 public int drain_tail (Collection<G> recipient, int amount = -1) {
219 while((amount == -1 || --amount >= 0) && (item = poll_tail ()) != null) {
229 private void grow_if_needed () {
230 if (_items.length < _length +1 ) {
231 _items.resize (2 * _items.length);
233 _items.move (0, _length, _start);
236 for(int i = 0; i < _start; i++)
237 _items[_length + i] = (owned)_items[i];
242 private int find_index (G item) {
243 for (int i = _start; i < int.min(_items.length, _start + _length); i++) {
244 if (equal_func(item, _items[i])) {
248 for (int i = 0; i < _start + _length - _items.length; i++) {
249 if (equal_func(item, _items[i])) {
256 private void remove_at (int index) {
257 int end = (_items.length + _start + _length - 1) % _items.length + 1;
258 if (index == _start) {
259 _items[_start++] = null;
262 } else if (index > _start && end <= _start) {
263 _items[index] = null;
264 _items.move (index + 1, index, _items.length - 1);
265 _items[_items.length - 1] = (owned)_items[0];
266 _items.move (1, 0, end - 1);
269 _items[index] = null;
270 _items.move (index + 1, index, end - (index + 1));
275 private class Iterator<G> : GLib.Object, Traversable<G>, Gee.Iterator<G> {
276 public Iterator (ArrayQueue<G> queue) {
278 _stamp = _queue._stamp;
281 public bool next () {
282 assert (_queue._stamp == _stamp);
292 public bool has_next () {
293 assert (_queue._stamp == _stamp);
294 return _offset + 1 < _queue._length;
297 public new G get () {
298 assert (_queue._stamp == _stamp);
299 assert (_offset != -1);
301 return _queue._items[(_queue._start + _offset) % _queue._items.length];
304 public void remove () {
305 assert (_queue._stamp++ == _stamp++);
306 _queue.remove_at((_queue._start + _offset) % _queue._items.length);
311 public bool valid { get {return _offset != -1 && !_removed;} }
313 public bool read_only { get {return false;} }
315 public bool foreach (ForallFunc<G> f) {
316 assert (_queue._stamp == _stamp);
321 for (int i = _offset; i < _queue._length; i++) {
322 if (!f (_queue._items[(_queue._start + i) % _queue._items.length])) {
330 private ArrayQueue _queue;
332 private int _offset = -1;
333 private bool _removed = false;
337 private int _start = 0;
338 private int _length = 0;
339 private int _stamp = 0;