package proj.zoie.api.impl.util; /** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF 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. */ import it.unimi.dsi.fastutil.longs.LongCollection; import it.unimi.dsi.fastutil.longs.LongIterator; import it.unimi.dsi.fastutil.longs.LongSet; import java.util.Collection; import java.util.Iterator; /** * This class, a LongSet decorator, is for accelerating look-up by having a * filter in front of the underlying LongSet. The filter is basically a Bloom * filter. The hash table size and the hash function are tuned for fast * calculation of hash values. The underlying LongSet should not be updated * while this accelerator is in use. * * @author ymatsuda * */ public class LongSetAccelerator implements LongSet { private final long[] _filter; private final int _mask; private final LongSet _set; private static final int MIXER = 2147482951; // a prime number public LongSetAccelerator(LongSet set) { _set = set; int mask = set.size() / 4; mask |= (mask >> 1); mask |= (mask >> 2); mask |= (mask >> 4); mask |= (mask >> 8); mask |= (mask >> 16); _mask = mask; _filter = new long[mask + 1]; LongIterator iter = set.iterator(); while (iter.hasNext()) { long l = iter.nextLong(); int h = (int) ((l >>> 32) ^ l) * MIXER; long bits = _filter[h & _mask]; bits |= ((1L << (h >>> 26))); bits |= ((1L << ((h >> 20) & 0x3F))); _filter[h & _mask] = bits; } } public boolean contains(long val) { final int h = (int) (val >>> 32 ^ val) * MIXER; final long bits = _filter[h & _mask]; return (bits & (1L << (h >>> 26))) != 0 && (bits & (1L << ((h >> 20) & 0x3F))) != 0 && _set.contains(val); } public boolean contains(Object o) { return contains(((Long) (o)).longValue()); } public boolean containsAll(Collection<?> c) { final Iterator<?> i = c.iterator(); int n = c.size(); while (n-- != 0) if (!contains(i.next())) return false; return true; } public boolean containsAll(LongCollection c) { final LongIterator i = c.iterator(); int n = c.size(); while (n-- != 0) if (!contains(i.nextLong())) return false; return true; } public boolean add(long key) { throw new UnsupportedOperationException(); } public boolean add(Long o) { throw new UnsupportedOperationException(); } public boolean addAll(Collection<? extends Long> c) { throw new UnsupportedOperationException(); } public boolean addAll(LongCollection c) { throw new UnsupportedOperationException(); } public void clear() { throw new UnsupportedOperationException(); } public boolean equals(Object o) { return _set.equals(o); } public int hashCode() { return _set.hashCode(); } public LongIterator longIterator() { return _set.iterator(); } public boolean isEmpty() { return _set.isEmpty(); } public LongIterator iterator() { return _set.iterator(); } public boolean rem(long key) { throw new UnsupportedOperationException(); } public boolean remove(long key) { throw new UnsupportedOperationException(); } public boolean remove(Object o) { throw new UnsupportedOperationException(); } public boolean removeAll(Collection<?> c) { throw new UnsupportedOperationException(); } public boolean removeAll(LongCollection c) { throw new UnsupportedOperationException(); } public boolean retainAll(Collection<?> c) { throw new UnsupportedOperationException(); } public boolean retainAll(LongCollection c) { throw new UnsupportedOperationException(); } public int size() { return _set.size(); } public Object[] toArray() { return _set.toArray(); } public long[] toArray(long[] a) { return _set.toArray(a); } public <T> T[] toArray(T[] a) { return _set.toArray(a); } public long[] toLongArray() { return _set.toLongArray(); } public long[] toLongArray(long[] a) { return _set.toLongArray(a); } }