/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package com.github.geophile.erdo.map.arraymap; import com.github.geophile.erdo.AbstractKey; import com.github.geophile.erdo.map.LazyRecord; import com.github.geophile.erdo.map.MapCursor; import java.io.IOException; public class ArrayMapCursor extends MapCursor { // MapCursor interface @Override public LazyRecord next() throws IOException, InterruptedException { return neighbor(true); } @Override public LazyRecord previous() throws IOException, InterruptedException { return neighbor(false); } // ArrayMapCursor interface ArrayMapCursor(ArrayMap map, AbstractKey startKey) throws IOException, InterruptedException { super(startKey, false); this.map = map; } // For use by this class private LazyRecord neighbor(boolean forward) throws IOException, InterruptedException { LazyRecord neighbor = null; switch (state) { case NEVER_USED: if (startKey == null) { position = forward ? 0 : (int) map.recordCount() - 1; } else { position = binarySearch(startKey); if (position < 0) { position = forward ? -position - 1 : -position - 2; } } state = State.IN_USE; break; case IN_USE: position += forward ? 1 : -1; break; case DONE: return null; } if (position >= 0 && position < map.recordCount()) { neighbor = map.records.get(position); if (!isOpen(neighbor.key())) { neighbor.destroyRecordReference(); neighbor = null; } } if (neighbor == null) { close(); } return neighbor; } // Adapted from java.util.Arrays.binarySearch0 private int binarySearch(AbstractKey key) throws IOException, InterruptedException { int low = 0; int high = map.records.size() - 1; AbstractKey midKey; while (low <= high) { int mid = (low + high) >>> 1; midKey = map.records.get(mid).key(); int c = midKey.compareTo(key); if (c < 0) { low = mid + 1; } else if (c > 0) { high = mid - 1; } else { return mid; // key found } } return -(low + 1); // key not found. } // Object state private final ArrayMap map; private int position; }