Return-Path: Delivered-To: apmail-hbase-dev-archive@www.apache.org Received: (qmail 84751 invoked from network); 9 Jun 2010 00:59:52 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 9 Jun 2010 00:59:52 -0000 Received: (qmail 86565 invoked by uid 500); 9 Jun 2010 00:59:52 -0000 Delivered-To: apmail-hbase-dev-archive@hbase.apache.org Received: (qmail 86407 invoked by uid 500); 9 Jun 2010 00:59:52 -0000 Mailing-List: contact dev-help@hbase.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@hbase.apache.org Delivered-To: mailing list dev@hbase.apache.org Received: (qmail 86387 invoked by uid 99); 9 Jun 2010 00:59:52 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 09 Jun 2010 00:59:52 +0000 X-ASF-Spam-Status: No, hits=-0.0 required=10.0 tests=SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (nike.apache.org: local policy) Received: from [203.89.202.182] (HELO postoffice2.aconex.com) (203.89.202.182) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 09 Jun 2010 00:59:43 +0000 X-ASG-Debug-ID: 1276045159-07a8021e0000-pO6Xgt X-Barracuda-URL: http://postoffice2.aconex.com:8000/cgi-bin/mark.cgi Received: from postoffice.aconex.com (localhost [127.0.0.1]) by postoffice2.aconex.com (Spam & Virus Firewall) with ESMTP id E6152780A9E for ; Wed, 9 Jun 2010 10:59:19 +1000 (EST) Received: from postoffice.aconex.com (postoffice.yarra.acx [192.168.102.1]) by postoffice2.aconex.com with ESMTP id bW2rpRjuIiqD1g6b for ; Wed, 09 Jun 2010 10:59:19 +1000 (EST) X-Barracuda-Envelope-From: cowan@aconex.com Received: from gatekeeper.aconex.com (gatekeeper.yarra.acx [192.168.102.10]) by postoffice.aconex.com (Postfix) with ESMTP id 12B8FA501BC for ; Wed, 9 Jun 2010 10:55:48 +1000 (EST) Received: from localhost (localhost.localdomain [127.0.0.1]) by gatekeeper.aconex.com (Postfix) with ESMTP id B8F3C4887BF for ; Wed, 9 Jun 2010 10:59:19 +1000 (EST) X-Virus-Scanned: amavisd-new at aconex.com Received: from gatekeeper.aconex.com ([127.0.0.1]) by localhost (gatekeeper.aconex.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 5LNiGN1sXtsS for ; Wed, 9 Jun 2010 10:59:15 +1000 (EST) Received: from [192.168.7.31] (unknown [203.89.193.116]) by gatekeeper.aconex.com (Postfix) with ESMTP id 0DC884887B6 for ; Wed, 9 Jun 2010 10:59:15 +1000 (EST) Message-ID: <4C0EE75C.6070709@aconex.com> Date: Wed, 09 Jun 2010 10:59:08 +1000 From: Paul Cowan Organization: Aconex User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.9) Gecko/20100423 Thunderbird/3.0.4 MIME-Version: 1.0 To: dev@hbase.apache.org X-ASG-Orig-Subj: Re: Review Request: HBASE-2468: Improvements to prewarm META cache on clients. Subject: Re: Review Request: HBASE-2468: Improvements to prewarm META cache on clients. References: <20100528211314.13032.44086@ip-10-250-10-165.ec2.internal> <20100528215936.21168.90293@ip-10-250-10-165.ec2.internal> <4C008851.7070807@aconex.com> In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: postoffice.yarra.acx[192.168.102.1] X-Barracuda-Start-Time: 1276045159 X-Barracuda-Virus-Scanned: by Aconex Staff Email Spam Firewall at aconex.com X-Virus-Checked: Checked by ClamAV on apache.org Hi tsuna, >> Changing this class to use ConcurrentHashMap, and completely removing >> synchronization, won't work, as it's written. The lazy-loading in >> regionCachePreFetchEnabled() (get - if null, put) won't work correctly with >> a ConcurrentHashMap without external synchronization. > > I'm not sure to understand why, can you explain? No problem. With that change, there would be a potential race condition: Thread 1 Thread 2 ---------- ------------- enter regionCachePrefetchEnabled call ConcurrentMap.get() - get null enter disableRegionCachePrefetch ConcurrentMap.put(false); exit disableRegionCachePrefetch ConcurrentMap.put(true) exit regionCachePrefetchEnabled which means that after one (nominally 'read-only') call to regionCachePrefetchEnabled and one call to disableRegionCachePrefetch have completed, the value in the cache for the table is true, when it really should be false. The get-nullcheck-put triad really needs to be atomic, which requires either external synchronization or use of some of the other features of ConcurrentHashMap like below. > Slide 31 of the aforementioned presentation reads "Calls putIfAbsent > every time it needs to read a value" "Unfortunately, this usage is > very common" so I think this is not a good idea. > > I'm still fairly new to Java so I tend to trust what people like > Joshua Bloch write, but I can be convinced otherwise :) That's purely for performance reasons -- you're right, I should have suggested get, if (result == null) {putIfAbsent, get} rather than putIfAbsent, get Both are correct but as Josh talks about on that slide (and the subsequent one) it's needless contention. I would be almost certain that it's still faster than a synchronized block, but not as much as other options. Should have mentioned that. Of the 4 options I mentioned (putIfAbsent(), get() and default return value if missing, CopyOnWriteArraySet, ConcurrentHashSet), the putIfAbsent() method is likely the slowest (given the usage pattern anyway), and (more importantly, in my opinion) the least clear anyway. I think the ConcurrentSet solution is much cleaner. Hope that makes thing clear. Cheers, Paul