From 6fecd0db885acc6374d1c5b7cb1d4c8fc1c36b37 Mon Sep 17 00:00:00 2001 From: Michael Christen Date: Thu, 15 Dec 2011 23:33:41 +0100 Subject: [PATCH] one more performance hack to prevent costly md5 computation --- source/net/yacy/kelondro/order/Digest.java | 27 ++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/source/net/yacy/kelondro/order/Digest.java b/source/net/yacy/kelondro/order/Digest.java index cb0a527b7..0d26ee5e8 100644 --- a/source/net/yacy/kelondro/order/Digest.java +++ b/source/net/yacy/kelondro/order/Digest.java @@ -45,7 +45,10 @@ import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.LinkedBlockingQueue; import net.yacy.cora.document.UTF8; +import net.yacy.cora.storage.ARC; +import net.yacy.cora.storage.ConcurrentARC; import net.yacy.kelondro.logging.Log; +import net.yacy.kelondro.util.MemoryControl; @@ -53,6 +56,16 @@ public class Digest { public static BlockingQueue digestPool = new LinkedBlockingDeque(); + private static final int md5CacheSize = Math.max(200000, Math.min(10000000, (int) (MemoryControl.available() / 20000L))); + private static ARC md5Cache = null; + static { + try { + md5Cache = new ConcurrentARC(md5CacheSize, Math.max(32, 4 * Runtime.getRuntime().availableProcessors())); + } catch (final OutOfMemoryError e) { + md5Cache = new ConcurrentARC(1000, Math.max(8, 2 * Runtime.getRuntime().availableProcessors())); + } + } + public static String encodeHex(final long in, final int length) { String s = Long.toHexString(in); while (s.length() < length) s = "0" + s; @@ -103,8 +116,11 @@ public class Digest { } public static byte[] encodeMD5Raw(final String key) { - MessageDigest digest = null; - digest = digestPool.poll(); + + byte[] h = md5Cache.get(key); + if (h != null) return h; + + MessageDigest digest = digestPool.poll(); if (digest == null) { // if there are no digest objects left, create some on the fly // this is not the most effective way but if we wouldn't do that the encoder would block @@ -124,6 +140,13 @@ public class Digest { //System.out.println("Digest Pool size = " + digestPool.size()); } catch ( InterruptedException e ) { } + + // update the cache + if (MemoryControl.shortStatus()) { + md5Cache.clear(); + } else { + md5Cache.insertIfAbsent(key, result); // prevent expensive MD5 computation and encoding + } return result; }