// This software is released into the Public Domain. See copying.txt for details.
package org.openstreetmap.osmosis.core.store;
import java.io.File;
import org.openstreetmap.osmosis.core.lifecycle.Completable;
/**
* Provides a store for objects that can be located by a long identifier.
*
* @param <T>
* The object type to be stored.
* @author Brett Henderson
*/
public class IndexedObjectStore<T extends Storeable> implements Completable {
private RandomAccessObjectStore<T> objectStore;
private IndexStore<Long, LongLongIndexElement> indexStore;
/**
* Creates a new instance.
*
* @param serializationFactory
* The factory defining the object serialisation implementation.
* @param tmpFilePrefix
* The prefix of the storage file.
*/
public IndexedObjectStore(ObjectSerializationFactory serializationFactory, String tmpFilePrefix) {
objectStore = new RandomAccessObjectStore<T>(serializationFactory, tmpFilePrefix + "d");
indexStore = new IndexStore<Long, LongLongIndexElement>(
LongLongIndexElement.class,
new ComparableComparator<Long>(),
tmpFilePrefix + "i"
);
}
/**
* Creates a new instance.
*
* @param serializationFactory
* The factory defining the object serialisation implementation.
* @param objectStorageFile
* The storage file to use for objects.
* @param indexStorageFile
* The storage file to use for the index.
*/
public IndexedObjectStore(
ObjectSerializationFactory serializationFactory, File objectStorageFile, File indexStorageFile) {
objectStore = new RandomAccessObjectStore<T>(serializationFactory, objectStorageFile);
indexStore = new IndexStore<Long, LongLongIndexElement>(
LongLongIndexElement.class,
new ComparableComparator<Long>(),
indexStorageFile
);
}
/**
* Adds the specified object to the store.
*
* @param id
* The identifier allowing the object to be retrieved.
* @param data
* The object to be added.
*/
public void add(long id, T data) {
long objectOffset;
// Write the object to the object store.
objectOffset = objectStore.add(data);
// Write the object offset keyed by the id to the index store.
indexStore.write(new LongLongIndexElement(id, objectOffset));
}
/**
* Creates a new reader capable of accessing the contents of this store. The
* reader must be explicitly released when no longer required. Readers must
* be released prior to this store.
*
* @return A store reader.
*/
public IndexedObjectStoreReader<T> createReader() {
RandomAccessObjectStoreReader<T> objectStoreReader = null;
objectStoreReader = objectStore.createReader();
try {
IndexStoreReader<Long, LongLongIndexElement> indexStoreReader;
IndexedObjectStoreReader<T> reader;
indexStoreReader = indexStore.createReader();
reader = new IndexedObjectStoreReader<T>(objectStoreReader, indexStoreReader);
objectStoreReader = null;
return reader;
} finally {
if (objectStoreReader != null) {
objectStoreReader.close();
}
}
}
/**
* {@inheritDoc}
*/
@Override
public void complete() {
objectStore.complete();
indexStore.complete();
}
/**
* {@inheritDoc}
*/
public void close() {
objectStore.close();
indexStore.close();
}
}