/* * This file is part of the Heritrix web crawler (crawler.archive.org). * * Licensed to the Internet Archive (IA) by one or more individual * contributors. * * The IA licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.archive.util.fingerprint; /** * Simple long fingerprint cache using a backing array; any long maps to * one of 'smear' slots. Longs inserted should be randomly distributed, * * @author gojomo */ public class ArrayLongFPCache implements LongFPSet { public static final int DEFAULT_CAPACITY = 1 << 20; // 1 million, 8MB public static final int DEFAULT_SMEAR = 5; protected long cache[] = new long[DEFAULT_CAPACITY]; protected int smear = DEFAULT_SMEAR; protected int count = 0; public void setCapacity(int newCapacity) { long[] oldCache = cache; cache = new long[newCapacity]; for(int i=0;i<oldCache.length;i++) { add(oldCache[i]); } } /* (non-Javadoc) * @see org.archive.util.fingerprint.LongFPSet#add(long) */ public boolean add(long l) { if(contains(l)) { return false; } int index = (Math.abs((int) (l % cache.length)) + (count % smear)) % cache.length; count++; cache[index]=l; return true; } /* (non-Javadoc) * @see org.archive.util.fingerprint.LongFPSet#contains(long) */ public boolean contains(long l) { int index = Math.abs((int) (l % cache.length)); for(int i = index; i < index + smear; i++) { if(cache[i%cache.length]==l) { return true; } } return false; } /* (non-Javadoc) * @see org.archive.util.fingerprint.LongFPSet#remove(long) */ public boolean remove(long l) { int index = Math.abs((int) (l % cache.length)); for(int i = index; i < index + smear; i++) { if(cache[i%cache.length]==l) { cache[i%cache.length]=0; count = Math.min(count,cache.length); count--; return true; } } return false; } /* (non-Javadoc) * @see org.archive.util.fingerprint.LongFPSet#count() */ public long count() { return Math.min(count,cache.length); } /* (non-Javadoc) * @see org.archive.util.fingerprint.LongFPSet#quickContains(long) */ public boolean quickContains(long fp) { return contains(fp); } public int cacheLength() { return cache.length; } }