/* 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; /** * Provides a long => MethodCall map which doesn't allocate objects * on insertion/removal. Keys must be inserted in ascending order. */ class EfficientMap { private long[] kv; private MethodCall[] vv; private int start; private int end; private int init_size; public EfficientMap(int initial_size) { init_size = initial_size; shrink(); } private void grow() { // create new vectors twice as long long[] oldkv = kv; kv = new long[oldkv.length * 2]; MethodCall[] oldvv = vv; vv = new MethodCall[oldvv.length * 2]; // copy start->length to the start of the new vector System.arraycopy(oldkv, start, kv, 0, oldkv.length - start); System.arraycopy(oldvv, start, vv, 0, oldvv.length - start); // copy 0->end to the next part of the new vector if (end != (oldkv.length - 1)) { System.arraycopy(oldkv, 0, kv, oldkv.length - start, end + 1); System.arraycopy(oldvv, 0, vv, oldvv.length - start, end + 1); } // reposition pointers start = 0; end = oldkv.length; } // create a new vector with just the valid keys in and return it public long[] getKeys() { int size; if (start < end) size = end - start; else size = kv.length - (start - end); long[] lv = new long[size]; int copya; if (size > kv.length - start) copya = kv.length - start; else copya = size; System.arraycopy(kv, start, lv, 0, copya); if (copya < size) { System.arraycopy(kv, 0, lv, copya, size - copya); } return lv; } private void shrink() { if (null != kv && kv.length == init_size) return; // reset to original size kv = new long[init_size]; vv = new MethodCall[init_size]; start = 0; end = 0; } public void put(long l, MethodCall m) { // put this at the end kv[end] = l; vv[end] = m; // move the end if (end == (kv.length - 1)) end = 0; else end++; // if we are out of space, grow. if (end == start) grow(); } public MethodCall remove(long l) { // find the item int pos = find(l); // if we don't have it return null if (-1 == pos) return null; // get the value MethodCall m = vv[pos]; // set it as unused vv[pos] = null; kv[pos] = -1; // move the pointer to the first full element while (-1 == kv[start]) { if (start == (kv.length - 1)) start = 0; else start++; // if we have emptied the list, shrink it if (start == end) { shrink(); break; } } return m; } public boolean contains(long l) { // check if find succeeds return -1 != find(l); } /* could binary search, but it's probably the first one */ private int find(long l) { int i = start; while (i != end && kv[i] != l) if (i == (kv.length - 1)) i = 0; else i++; if (i == end) return -1; return i; } }