/* * 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.keyarray; import com.github.geophile.erdo.AbstractKey; import com.github.geophile.erdo.map.Factory; import com.github.geophile.erdo.map.diskmap.CompressibleLongArray; import com.github.geophile.erdo.memorymonitor.MemoryMonitor; import com.github.geophile.erdo.memorymonitor.MemoryTracker; import com.github.geophile.erdo.util.ErdoIdArray; import com.github.geophile.erdo.util.PackedArray; public class KeyArray { public void append(AbstractKey key) { assert !closed; erdoIds.append(key.erdoId()); timestamps.append(key.transactionTimestamp()); array.object().append(key); } public int size() { return array.object().size(); } public KeyArrayCursor cursor(AbstractKey startKey) { assert closed; return new KeyArrayCursor(this, startKey); } public void close() { timestamps.close(); closed = true; } public void destroy() { array.object(null); } // public only for use by tests // Adapted from java.util.Arrays.binarySearch0 public int binarySearch(AbstractKey key) { int low = 0; int high = array.object().size() - 1; AbstractKey midKey = null; while (low <= high) { int mid = (low + high) >>> 1; midKey = key(mid, midKey); 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. } public KeyArray(Factory factory, int initialCapacity) { this.factory = factory; this.erdoIds = new ErdoIdArray(); this.timestamps = new CompressibleLongArray(initialCapacity); MemoryTracker<PackedArray> arrayMemoryTracker = new MemoryTracker<>(factory.memoryMonitor(), MemoryMonitor.KEY_ARRAY_KEYS); arrayMemoryTracker.object(new PackedArray(arrayMemoryTracker)); this.array = arrayMemoryTracker; } // For use by this package AbstractKey key(int position, AbstractKey key) { assert closed; int erdoId = erdoIds.at(position); if (key == null || key.erdoId() != erdoId) { key = factory.recordFactory(erdoId).newKey(); } key.clearTransactionState(); key.erdoId(erdoId); key.transactionTimestamp(timestamps.at(position)); array.object().at(position, key); return key; } // Object state private final Factory factory; private final ErdoIdArray erdoIds; private final CompressibleLongArray timestamps; private final MemoryTracker<PackedArray> array; private boolean closed = false; }