fixed a deadlock during secondary remote search

pull/1/head
Michael Christen 13 years ago
parent c715d19c09
commit 86b3385847

@ -26,8 +26,10 @@
package net.yacy.kelondro.data.word; package net.yacy.kelondro.data.word;
import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap; import java.util.TreeMap;
import net.yacy.cora.document.ASCII; import net.yacy.cora.document.ASCII;
@ -39,15 +41,18 @@ import net.yacy.kelondro.util.ByteBuffer;
public class WordReferenceFactory implements ReferenceFactory<WordReference> { public class WordReferenceFactory implements ReferenceFactory<WordReference> {
@Override
public WordReference produceSlow(final Entry e) { public WordReference produceSlow(final Entry e) {
return new WordReferenceRow(e); return new WordReferenceRow(e);
} }
@Override
public WordReference produceFast(final WordReference r) { public WordReference produceFast(final WordReference r) {
if (r instanceof WordReferenceVars) return r; if (r instanceof WordReferenceVars) return r;
return new WordReferenceVars(r); return new WordReferenceVars(r);
} }
@Override
public Row getRow() { public Row getRow() {
return WordReferenceRow.urlEntryRow; return WordReferenceRow.urlEntryRow;
} }
@ -110,8 +115,8 @@ public class WordReferenceFactory implements ReferenceFactory<WordReference> {
* @param peerhash * @param peerhash
* @return * @return
*/ */
public static final TreeMap<String, StringBuilder> decompressIndex(ByteBuffer ci, final String peerhash) { public static final SortedMap<String, StringBuilder> decompressIndex(ByteBuffer ci, final String peerhash) {
TreeMap<String, StringBuilder> target = new TreeMap<String, StringBuilder>(); SortedMap<String, StringBuilder> target = Collections.synchronizedSortedMap(new TreeMap<String, StringBuilder>());
// target is a mapping from url-hashes to a string of peer-hashes // target is a mapping from url-hashes to a string of peer-hashes
if (ci.byteAt(0) != '{' || ci.byteAt(ci.length() - 1) != '}') return target; if (ci.byteAt(0) != '{' || ci.byteAt(ci.length() - 1) != '}') return target;
//System.out.println("DEBUG-DECOMPRESS: input is " + ci.toString()); //System.out.println("DEBUG-DECOMPRESS: input is " + ci.toString());

@ -26,6 +26,7 @@
package net.yacy.search.query; package net.yacy.search.query;
import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.SortedMap; import java.util.SortedMap;
@ -516,8 +517,8 @@ public final class SearchEvent
private final Semaphore trigger; private final Semaphore trigger;
public SecondarySearchSuperviser() { public SecondarySearchSuperviser() {
this.abstractsCache = new TreeMap<String, SortedMap<String, StringBuilder>>(); this.abstractsCache = Collections.synchronizedSortedMap(new TreeMap<String, SortedMap<String, StringBuilder>>());
this.checkedPeers = new TreeSet<String>(); this.checkedPeers = Collections.synchronizedSortedSet(new TreeSet<String>());
this.trigger = new Semaphore(0); this.trigger = new Semaphore(0);
} }
@ -527,16 +528,14 @@ public final class SearchEvent
* @param wordhash * @param wordhash
* @param singleAbstract // a mapping from url-hashes to a string of peer-hashes * @param singleAbstract // a mapping from url-hashes to a string of peer-hashes
*/ */
public void addAbstract(final String wordhash, final TreeMap<String, StringBuilder> singleAbstract) { public void addAbstract(final String wordhash, final SortedMap<String, StringBuilder> singleAbstract) {
final SortedMap<String, StringBuilder> oldAbstract; final SortedMap<String, StringBuilder> oldAbstract;
synchronized ( this.abstractsCache ) {
oldAbstract = this.abstractsCache.get(wordhash); oldAbstract = this.abstractsCache.get(wordhash);
if ( oldAbstract == null ) { if ( oldAbstract == null ) {
// new abstracts in the cache // new abstracts in the cache
this.abstractsCache.put(wordhash, singleAbstract); this.abstractsCache.put(wordhash, singleAbstract);
return; return;
} }
}
// extend the abstracts in the cache: join the single abstracts // extend the abstracts in the cache: join the single abstracts
new Thread() { new Thread() {
@Override @Override
@ -544,14 +543,12 @@ public final class SearchEvent
for ( final Map.Entry<String, StringBuilder> oneref : singleAbstract.entrySet() ) { for ( final Map.Entry<String, StringBuilder> oneref : singleAbstract.entrySet() ) {
final String urlhash = oneref.getKey(); final String urlhash = oneref.getKey();
final StringBuilder peerlistNew = oneref.getValue(); final StringBuilder peerlistNew = oneref.getValue();
synchronized ( oldAbstract ) {
final StringBuilder peerlistOld = oldAbstract.put(urlhash, peerlistNew); final StringBuilder peerlistOld = oldAbstract.put(urlhash, peerlistNew);
if ( peerlistOld != null ) { if ( peerlistOld != null ) {
peerlistOld.append(peerlistNew); peerlistOld.append(peerlistNew);
} }
} }
} }
}
}.start(); }.start();
// abstractsCache.put(wordhash, oldAbstract); // put not necessary since it is sufficient to just change the value content (it stays assigned) // abstractsCache.put(wordhash, oldAbstract); // put not necessary since it is sufficient to just change the value content (it stays assigned)
} }
@ -567,7 +564,6 @@ public final class SearchEvent
SortedMap<String, StringBuilder> urlPeerlist; SortedMap<String, StringBuilder> urlPeerlist;
int p; int p;
boolean hasURL; boolean hasURL;
synchronized ( this ) {
final Iterator<Map.Entry<String, SortedMap<String, StringBuilder>>> i = final Iterator<Map.Entry<String, SortedMap<String, StringBuilder>>> i =
this.abstractsCache.entrySet().iterator(); this.abstractsCache.entrySet().iterator();
while ( i.hasNext() ) { while ( i.hasNext() ) {
@ -588,7 +584,6 @@ public final class SearchEvent
wordlist += word; wordlist += word;
} }
} }
}
return wordlist; return wordlist;
} }

Loading…
Cancel
Save