summaryrefslogtreecommitdiff
path: root/src/traffic-incidents-service/org.genivi.trafficinfo.dbus-java/src/main/java/org/freedesktop/dbus/EfficientQueue.java
blob: 5724730f28ca438f46e75fc19b21420b908ba437 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/*
   D-Bus Java Implementation
   Copyright (c) 2005-2006 Matthew Johnson

   This program is free software; you can redistribute it and/or modify it
   under the terms of either the GNU Lesser General Public License Version 2 or the
   Academic Free Licence Version 2.1.

   Full licence texts are included in the COPYING file with this program.
*/
package org.freedesktop.dbus;

import cx.ath.matthew.debug.Debug;

/**
 * Provides a Message queue which doesn't allocate objects
 * on insertion/removal. */
class EfficientQueue
{
   private Message[] mv;
   private int start;
   private int end;
   private int init_size;
   public EfficientQueue(int initial_size)
   {
      init_size = initial_size;
      shrink();
   }
   private void grow()
   {
      if (Debug.debug) Debug.print(Debug.DEBUG, "Growing");
      // create new vectors twice as long
      Message[] oldmv = mv;
      mv = new Message[oldmv.length*2];

      // copy start->length to the start of the new vector
      System.arraycopy(oldmv,start,mv,0,oldmv.length-start);
      // copy 0->end to the next part of the new vector
      if (end != (oldmv.length-1)) {
         System.arraycopy(oldmv,0,mv,oldmv.length-start,end+1);
      }
      // reposition pointers
      start = 0;
      end = oldmv.length;
   }
   // create a new vector with just the valid keys in and return it
   public Message[] getKeys()
   {
      if (start == end) return new Message[0];
      Message[] lv;
      if (start < end) {
         int size = end-start;
         lv = new Message[size];
         System.arraycopy(mv, start, lv, 0, size);
      } else {
         int size = mv.length-start+end;
         lv = new Message[size];
         System.arraycopy(mv, start, lv, 0, mv.length-start);
         System.arraycopy(mv, 0, lv, mv.length-start, end);
      }
      return lv;
   }
   private void shrink()
   {
      if (Debug.debug) Debug.print(Debug.DEBUG, "Shrinking");
      if (null != mv && mv.length == init_size) return;
      // reset to original size
      mv = new Message[init_size];
      start = 0;
      end = 0;
   }
   public void add(Message m)
   {
      if (Debug.debug) Debug.print(Debug.DEBUG, "Enqueueing Message "+m);
      // put this at the end
      mv[end] = m;
      // move the end
      if (end == (mv.length-1)) end = 0; else end++;
      // if we are out of space, grow.
      if (end == start) grow();
   }
   public Message remove()
   {
      if (start == end) return null;
      // find the item
      int pos = start;
      // get the value
      Message m = mv[pos];
      // set it as unused
      mv[pos] = null;
      if (start == (mv.length-1)) start = 0; else start++;
      if (Debug.debug) Debug.print(Debug.DEBUG, "Dequeueing "+m);
      return m;
   }
   public boolean isEmpty()
   {
      // check if find succeeds
      return start == end;
   }   
   public int size()
   {
      if (end >= start)
         return end-start;
      else
         return mv.length-start+end;
   }
}