/*
* This file is part of the HyperGraphDB source distribution. This is copyrighted
* software. For permitted uses, licensing options and redistribution, please see
* the LicensingInformation file at the root level of the distribution.
*
* Copyright (c) 2005-2010 Kobrix Software, Inc. All rights reserved.
*/
package org.hypergraphdb;
import java.util.ArrayList;
import org.hypergraphdb.handle.HGLiveHandle;
import org.hypergraphdb.storage.StorageBasedIncidenceSet;
import org.hypergraphdb.transaction.TxCacheSet;
import org.hypergraphdb.transaction.TxSet.SetTxBox;
import org.hypergraphdb.util.ArrayBasedSet;
import org.hypergraphdb.util.CountMe;
import org.hypergraphdb.util.DummyReadWriteLock;
import org.hypergraphdb.util.HGSortedSet;
import org.hypergraphdb.util.HGUtils;
import org.hypergraphdb.util.RefCountedMap;
import org.hypergraphdb.util.RefResolver;
/**
*
* <p>
* Support for incidence set caching - a reference resolver of incidence sets
* keyed by their atom handles. Used in the implementation of incidence set caches.
* </p>
*
* @author Borislav Iordanov
*
*/
@SuppressWarnings("unchecked")
class ISRefResolver implements RefResolver<HGPersistentHandle, IncidenceSet>
{
HyperGraph graph;
int keepInMemoryThreshold;
RefCountedMap<HGPersistentHandle, SetTxBox<HGHandle>> writeMap;
RefResolver<HGPersistentHandle, HGSortedSet<HGHandle>> loader =
new RefResolver<HGPersistentHandle, HGSortedSet<HGHandle>>()
{
public HGSortedSet<HGHandle> resolve(HGPersistentHandle key)
{
HGSearchResult<HGPersistentHandle> rs = graph.getStore().getIncidenceResultSet(key);
try
{
int size = rs == HGSearchResult.EMPTY ? 0 : ((CountMe)rs).count();
HGPersistentHandle [] A = new HGPersistentHandle[size];
for (int i = 0; i < A.length; i++)
A[i] = rs.next();
ArrayBasedSet<HGHandle> impl = new ArrayBasedSet<HGHandle>(A);
impl.setLock(new DummyReadWriteLock());
return impl;
}
finally
{
rs.close();
}
}
};
ISRefResolver(HyperGraph graph)
{
this.graph = graph;
this.keepInMemoryThreshold = graph.getConfig().getMaxCachedIncidenceSetSize();
this.writeMap = new RefCountedMap<HGPersistentHandle, SetTxBox<HGHandle>>(null);
}
public IncidenceSet resolve(HGPersistentHandle key)
{
HGSearchResult<HGPersistentHandle> rs = graph.getStore().getIncidenceResultSet(key);
try
{
int size = keepInMemoryThreshold;
if (keepInMemoryThreshold < Integer.MAX_VALUE)
size = rs == HGSearchResult.EMPTY ? 0 : ((CountMe)rs).count();
if (size <= keepInMemoryThreshold)
{
ArrayList<HGPersistentHandle> A = new ArrayList<HGPersistentHandle>();
while (rs.hasNext())
A.add(rs.next());
ArrayBasedSet<HGHandle> impl = new ArrayBasedSet<HGHandle>(A.toArray(HGUtils.EMPTY_HANDLE_ARRAY));
impl.setLock(new DummyReadWriteLock());
IncidenceSet result = new IncidenceSet(key,
new TxCacheSet(graph.getTransactionManager(),
impl,
key,
loader,
writeMap));
HGLiveHandle lHandle = graph.cache.get(key);
if (lHandle != null)
graph.updateLinksInIncidenceSet(result, lHandle);
return result;
}
else
return new IncidenceSet(key, new StorageBasedIncidenceSet(key, graph));
}
finally
{
rs.close();
}
}
}