/**
* This file is part of General Entity Annotator Benchmark.
*
* General Entity Annotator Benchmark 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.
*
* General Entity Annotator Benchmark 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 General Entity Annotator Benchmark. If not, see <http://www.gnu.org/licenses/>.
*/
package org.aksw.gerbil.semantic.sameas.impl.cache;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.Semaphore;
import org.aksw.gerbil.semantic.sameas.SameAsRetriever;
import org.aksw.gerbil.semantic.sameas.impl.cache.FileBasedCachingSameAsRetriever;
import org.junit.Assert;
import org.junit.Test;
import com.carrotsearch.hppc.BitSet;
import com.carrotsearch.hppc.ObjectIntOpenHashMap;
public class FileBasedCachingSameAsRetrieverTest extends FileBasedCachingSameAsRetriever {
private static final int MODULO_NR = 1024;
private static final int MAX_MUL = 10;
private static final int MAX_NR = MAX_MUL * MODULO_NR;
private static final int MAX_NR_SAME_AS_FOUND = 3;
private static final int NUMBER_OF_WORKERS = 4;
private static final int NUMBER_OF_REQUESTS_PER_WORKER = 5000;
private Semaphore cacheUsageFinished = new Semaphore(0);
public FileBasedCachingSameAsRetrieverTest() throws IOException {
super(new RandomNumberReturningSameAsRetriever(), new ObjectIntOpenHashMap<String>(),
new ArrayList<Set<String>>(), false, File.createTempFile("cache_test_", ".cache"),
File.createTempFile("cache_test_", ".cache_temp"));
}
@Test
public void test() throws InterruptedException {
///// test the cache itself
for (int i = 0; i < NUMBER_OF_WORKERS; ++i) {
(new Thread(new CacheUser(this))).start();
}
cacheUsageFinished.acquire(NUMBER_OF_WORKERS);
storeCache();
int setId;
Set<String> uris;
BitSet checkedSets = new BitSet(sets.size());
for (int i = 0; i < uriSetIdMapping.allocated.length; ++i) {
if (uriSetIdMapping.allocated[i]) {
setId = uriSetIdMapping.values[i];
if (setId != ENTITY_NOT_FOUND) {
// make sure that the set can exist
Assert.assertTrue(setId < sets.size());
uris = sets.get(setId);
// make sure that the URI pointing to this set is part of it
Assert.assertTrue(uris.contains(((Object[]) uriSetIdMapping.keys)[i]));
// If this set does not have been checked before, check all
// the URIs inside
if (!checkedSets.get(setId)) {
for (String s : uris) {
Assert.assertTrue(uriSetIdMapping.containsKey(s));
Assert.assertEquals(setId, uriSetIdMapping.get(s));
}
checkedSets.set(setId);
}
}
}
}
///// test the read/write operation
// read the cache with another cache object
FileBasedCachingSameAsRetriever otherCache = FileBasedCachingSameAsRetriever.create(decoratedRetriever, false,
cacheFile);
Assert.assertEquals(sets.size(), otherCache.sets.size());
Assert.assertEquals(uriSetIdMapping.assigned, otherCache.uriSetIdMapping.assigned);
checkedSets = new BitSet(sets.size());
int otherSetId;
String uri;
Set<String> otherUris;
for (int i = 0; i < uriSetIdMapping.allocated.length; ++i) {
if (uriSetIdMapping.allocated[i]) {
setId = uriSetIdMapping.values[i];
uri = (String) ((Object[]) uriSetIdMapping.keys)[i];
Assert.assertTrue(otherCache.uriSetIdMapping.containsKey(uri));
otherSetId = otherCache.uriSetIdMapping.get(uri);
if (setId != ENTITY_NOT_FOUND) {
Assert.assertNotEquals(ENTITY_NOT_FOUND, otherSetId);
uris = sets.get(setId);
otherUris = otherCache.sets.get(otherSetId);
Assert.assertEquals(uris.size(), otherUris.size());
for (String s : uris) {
Assert.assertTrue(otherUris.contains(s));
Assert.assertTrue(otherCache.uriSetIdMapping.containsKey(s));
Assert.assertEquals(otherSetId, otherCache.uriSetIdMapping.get(s));
}
} else {
Assert.assertEquals(ENTITY_NOT_FOUND, otherSetId);
}
}
}
}
public static class CacheUser implements Runnable {
private Random random = new Random();
private FileBasedCachingSameAsRetrieverTest cache;
public CacheUser(FileBasedCachingSameAsRetrieverTest cache) {
this.cache = cache;
}
@Override
public void run() {
Set<String> uris;
int uriNr, modValue;
for (int i = 0; i < NUMBER_OF_REQUESTS_PER_WORKER; ++i) {
uriNr = random.nextInt(MAX_NR);
modValue = uriNr % MODULO_NR;
uris = cache.retrieveSameURIs(Integer.toString(uriNr));
if (uris != null) {
for (String s : uris) {
Assert.assertEquals(modValue, Integer.parseInt(s) % MODULO_NR);
}
}
}
cache.cacheUsageFinished.release();
}
}
public static class RandomNumberReturningSameAsRetriever implements SameAsRetriever {
private Random random = new Random();
@Override
public Set<String> retrieveSameURIs(String uri) {
int uriValue = Integer.parseInt(uri);
int sameAsFound = random.nextInt(MAX_NR_SAME_AS_FOUND);
if (sameAsFound == 0) {
return null;
}
Set<String> result = new HashSet<String>();
result.add(uri);
int diff, newNr;
for (int i = 0; i < sameAsFound; ++i) {
diff = (random.nextInt(MAX_MUL - 1) + 1) * MODULO_NR;
newNr = uriValue + diff;
if (uriValue > MAX_NR) {
newNr = uriValue - diff;
if (newNr >= 0) {
result.add(Integer.toString(newNr));
}
} else {
result.add(Integer.toString(newNr));
}
}
return result;
}
@Override
public void addSameURIs(Set<String> uris) {
Set<String> temp = new HashSet<String>();
Set<String> result;
for (String uri : uris) {
result = retrieveSameURIs(uri);
if (result != null) {
temp.addAll(retrieveSameURIs(uri));
}
}
uris.addAll(temp);
}
@Override
public Set<String> retrieveSameURIs(String domain, String uri) {
return retrieveSameURIs(uri);
}
}
}