/* Copyright 2008, 2009, 2010 by the Oxford University Computing Laboratory This file is part of HermiT. HermiT is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. HermiT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with HermiT. If not, see <http://www.gnu.org/licenses/>. */ package org.semanticweb.HermiT.blocking; import java.io.Serializable; import org.semanticweb.HermiT.tableau.Node; public class BlockingSignatureCache implements Serializable { private static final long serialVersionUID=-7692825443489644667L; protected final DirectBlockingChecker m_directBlockingChecker; protected BlockingSignature[] m_buckets; protected int m_numberOfElements; protected int m_threshold; public BlockingSignatureCache(DirectBlockingChecker directBlockingChecker) { m_directBlockingChecker=directBlockingChecker; m_buckets=new BlockingSignature[1024]; m_threshold=(int)(m_buckets.length*0.75); m_numberOfElements=0; } public boolean isEmpty() { return m_numberOfElements==0; } public boolean addNode(Node node) { int hashCode=m_directBlockingChecker.blockingHashCode(node); int bucketIndex=getIndexFor(hashCode,m_buckets.length); BlockingSignature entry=m_buckets[bucketIndex]; while (entry!=null) { if (hashCode==entry.hashCode() && entry.blocksNode(node)) return false; entry=entry.m_nextEntry; } entry=m_directBlockingChecker.getBlockingSignatureFor(node); entry.m_nextEntry=m_buckets[bucketIndex]; m_buckets[bucketIndex]=entry; m_numberOfElements++; if (m_numberOfElements>=m_threshold) resize(m_buckets.length*2); return true; } protected void resize(int newCapacity) { BlockingSignature[] newBuckets=new BlockingSignature[newCapacity]; for (int i=0;i<m_buckets.length;i++) { BlockingSignature entry=m_buckets[i]; while (entry!=null) { BlockingSignature nextEntry=entry.m_nextEntry; int newIndex=getIndexFor(entry.hashCode(),newCapacity); entry.m_nextEntry=newBuckets[newIndex]; newBuckets[newIndex]=entry; entry=nextEntry; } } m_buckets=newBuckets; m_threshold=(int)(newCapacity*0.75); } public boolean containsSignature(Node node) { if (m_directBlockingChecker.canBeBlocked(node)) { int hashCode=m_directBlockingChecker.blockingHashCode(node); int bucketIndex=getIndexFor(hashCode,m_buckets.length); BlockingSignature entry=m_buckets[bucketIndex]; while (entry!=null) { if (hashCode==entry.hashCode() && entry.blocksNode(node)) return true; entry=entry.m_nextEntry; } } return false; } protected static int getIndexFor(int hashCode,int tableLength) { hashCode+=~(hashCode << 9); hashCode^=(hashCode >>> 14); hashCode+=(hashCode << 4); hashCode^=(hashCode >>> 10); return hashCode & (tableLength-1); } }