DidYouMean - changed to much simpler LinkedBlockingQueue

git-svn-id: https://svn.berlios.de/svnroot/repos/yacy/trunk@6071 6c8d7289-2bf4-0310-a012-ef5d649a1542
pull/1/head
apfelmaennchen 16 years ago
parent 01ac1b5d7e
commit c3c4dd0933

@ -2,8 +2,8 @@ package de.anomic.tools;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
import java.util.concurrent.LinkedBlockingQueue;
import de.anomic.kelondro.text.IndexCell;
import de.anomic.kelondro.text.referencePrototype.WordReference;
@ -23,69 +23,66 @@ public class DidYouMean {
'q','r','s','t','u','v','w','x','y','z','\u00e4','\u00f6','\u00fc','\u00df'};
private static final long TIMEOUT = 500;
final LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<String>();
private final Set<String> set;
private final IndexCell<WordReference> index;
private String word;
private int len;
private Thread ChangingOneLetter;
private Thread AddingOneLetter;
private Thread DeletingOneLetter;
private Thread ReversingTwoConsecutiveLetters;
private final BlockingQueue bq = new BlockingQueue();
public DidYouMean(final IndexCell<WordReference> index) {
// this.set = Collections.synchronizedSortedSet(new TreeSet<String>(new wordSizeComparator()));
this.set = Collections.synchronizedSet(new HashSet<String>());
this.word = "";
this.len = 0;
this.index = index;
this.ChangingOneLetter = new ChangingOneLetter();
this.AddingOneLetter = new AddingOneLetter();
this.DeletingOneLetter = new DeletingOneLetter();
this.ReversingTwoConsecutiveLetters = new ReversingTwoConsecutiveLetters();
}
public Set<String> getSuggestion(final String word) {
long startTime = System.currentTimeMillis();
this.word = word.toLowerCase();
this.len = word.length();
// create worker threads
Thread[] workers = new Thread[8];
for (int i=0; i<workers.length; i++) {
workers[i] = new Worker("WorkerThread_"+i);
}
// first push the tasks for calculation of word variations on blocking queue
bq.push(this.ChangingOneLetter);
bq.push(this.AddingOneLetter);
bq.push(this.DeletingOneLetter);
bq.push(this.ReversingTwoConsecutiveLetters);
// check for timeout
boolean run = true;
while(run && (System.currentTimeMillis()-startTime) < TIMEOUT) {
if(bq.size() > 0) {
run = true;
} else {
run = false;
}
// create producers
Thread[] producers = new Thread[4];
producers[0] = new ChangingOneLetter();
producers[1] = new AddingOneLetter();
producers[2] = new DeletingOneLetter();
producers[3] = new ReversingTwoConsecutiveLetters();
// start producers
for (int i=0; i<producers.length; i++) {
producers[i].start();
}
// create and start 8 consumers threads
Thread[] consumers = new Thread[8];
for (int i=0; i<consumers.length; i++) {
consumers[i] = new Consumer();
consumers[i].start();
}
// check if timeout has been reached
while(((System.currentTimeMillis()-startTime) < TIMEOUT) && queue.size()>0) {
// consume more ...
}
// push "poison pill" for each worker thread
for (int i=0; i<workers.length; i++) {
bq.push(new Thread() {
public void run() {
Thread.currentThread().interrupt();
}
});
// put "poison pill" for each consumer thread
for (int i=0; i<consumers.length; i++) {
try {
queue.put("\n");
} catch (InterruptedException e) {
}
}
// interupt all remaining producer threads
for (int i=0; i<producers.length; i++) {
producers[i].interrupt();
}
this.set.remove(word.toLowerCase());
Log.logInfo("DidYouMean", "found "+this.set.size()+" terms; execution time: "
+(System.currentTimeMillis()-startTime)+"ms"+ (run?"(timed out)":""));
+(System.currentTimeMillis()-startTime)+"ms"+ (queue.size()>0?"(timed out)":""));
return this.set;
@ -93,17 +90,17 @@ public class DidYouMean {
private class ChangingOneLetter extends Thread {
public ChangingOneLetter() {
this.setName("ChangingOneLetter");
}
// tests: alphabet.length * len
public void run() {
String s;
for(int i=0; i<len; i++) {
for(int j=0; j<alphabet.length; j++) {
s = word.substring(0, i) + alphabet[j] + word.substring(i+1);
bq.push(new Tester(s));
try {
queue.put(s);
} catch (InterruptedException e) {
return;
}
}
}
}
@ -111,104 +108,75 @@ public class DidYouMean {
private class DeletingOneLetter extends Thread {
public DeletingOneLetter() {
this.setName("DeletingOneLetter");
}
// tests: len
public void run() {
String s;
for(int i=0; i<len;i++) {
s = word.substring(0, i) + word.substring(i+1);
bq.push(new Tester(s));
try {
queue.put(s);
} catch (InterruptedException e) {
return;
}
}
}
}
private class AddingOneLetter extends Thread {
public AddingOneLetter() {
this.setName("AddingOneLetter");
}
// tests: alphabet.length * len
public void run() {
String s;
for(int i=0; i<=len;i++) {
for(int j=0; j<alphabet.length; j++) {
s = word.substring(0, i) + alphabet[j] + word.substring(i);
bq.push(new Tester(s));
try {
queue.put(s);
} catch (InterruptedException e) {
return;
}
}
}
}
}
private class ReversingTwoConsecutiveLetters extends Thread {
public ReversingTwoConsecutiveLetters() {
this.setName("ReversingTwoConsecutiveLetters");
}
// tests: (len - 1)
public void run() {
String s;
for(int i=0; i<len-1; i++) {
s = word.substring(0,i)+word.charAt(i+1)+word.charAt(i)+word.substring(i+2);
bq.push(new Tester(s));
}
}
}
private class Tester extends Thread {
private String s;
public Tester(String s) {
this.s = s;
}
public void run() {
if (index.has(Word.word2hash(s))) {
set.add(s);
try {
queue.put(s);
} catch (InterruptedException e) {
return;
}
}
}
}
private class Worker extends Thread {
public Worker(String name) {
super(name);
start();
}
class Consumer extends Thread {
public void run() {
try {
while(!isInterrupted()) {
((Runnable)bq.pop()).run();
while(true) {
String s = (String)queue.take();
if(s.equals("\n"))
this.interrupt();
else
consume(s);
}
} catch(InterruptedException e) {
}
}
}
private class BlockingQueue {
private final LinkedList<Thread> queue = new LinkedList<Thread>();
public void push(Thread t) {
synchronized(queue) {
queue.add(t);
queue.notify();
} catch (InterruptedException e) {
return;
}
}
public Object pop() throws InterruptedException {
synchronized(queue) {
while (queue.isEmpty()) {
queue.wait();
}
return queue.removeFirst();
void consume(String s) {
if (index.has(Word.word2hash(s))) {
set.add(s);
}
}
public int size() {
return queue.size();
}
}
}
/*
private class wordSizeComparator implements Comparator<String> {

Loading…
Cancel
Save