<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">Bryan,<div><br></div><div><div><div>On 2010-02-02, at 7:49 PM, Bryan Thompson wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite">
<div style="WORD-WRAP: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space">
<div dir="ltr" align="left"><span class="131211200-03022010"><font face="Courier New" color="#0000ff" size="4">Vladimir,</font></span></div>
<div dir="ltr" align="left"><span class="131211200-03022010"><font face="Courier New" color="#0000ff" size="4"></font></span>&nbsp;</div>
<div dir="ltr" align="left"><span class="131211200-03022010"><font face="Courier New" color="#0000ff" size="4">I now have a workload where I have a hotspot on our cache 
which is 8% of the total time.&nbsp; I am going to use this to test BCHM under a 
realistic workload.</font></span></div>
<div dir="ltr" align="left"><span class="131211200-03022010"><font face="Courier New" color="#0000ff" size="4"></font></span>&nbsp;</div>
<div dir="ltr" align="left"><span class="131211200-03022010"><font face="Courier New" color="#0000ff" size="4">One thing which I like about your design is that by placing 
the array buffering the operations for a thread within the Segment, you are 
using the lock guarding the Segment to control updates to that array.&nbsp; 
While this has less potential throughput than a truely thread-local design 
(which is non-blocking until the thread-local array is full), it seems that the 
array buffering the updates can not "escape" under your design.&nbsp; Was this 
intentional?</font></span></div>
<div dir="ltr" align="left"><span class="131211200-03022010"><font face="Courier New" color="#0000ff" size="4"></font></span></div></div></blockquote><div><br></div><div>Yes. Escaping could also potentially be handled by shared pool of array buffers. Ideally shared pool would be some lock free structure since &nbsp;there would be a lot of contention among threads for these array buffers (that record accesses)</div><div>&nbsp;</div><div><br></div><br><blockquote type="cite"><div style="WORD-WRAP: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space"><div dir="ltr" align="left">&nbsp;</div>
<div dir="ltr" align="left"><span class="131211200-03022010"><font face="Courier New" color="#0000ff" size="4">The danger with a true thread-local design is that a thread 
can come in and do some work, get some updates buffered in its thread-local 
array, and then never visit again.&nbsp; In this case those updates would remain 
buffered on the thread and would not in fact cause the access order to be 
updated in a timely manner.&nbsp; Worse, if you are relying on WeakReference 
semantics, the buffered updates would remain strongly reachable and the 
corresponding objects would be wired into the cache.</font></span></div></div></blockquote><div><br></div><div>Not if you return updates into above mentioned pool as the thread unwinds from call into cache (container).&nbsp;</div><br><blockquote type="cite"><div style="WORD-WRAP: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space">
<div dir="ltr" align="left"><span class="131211200-03022010"><font face="Courier New" color="#0000ff" size="4"></font></span>&nbsp;</div>
<div dir="ltr" align="left"><span class="131211200-03022010"><font face="Courier New" color="#0000ff" size="4">I've worked around this issue in a different context where 
it made sense to scope the buffers to an owning object (a B+Tree 
instance).&nbsp; In that case, when the B+Tree container was closed, all 
buffered updates were discarded.&nbsp; This nicely eliminated the problems with 
"escaping" threads.</font></span></div></div></blockquote><div><br></div>Yes, there has to be some container boundary! In Infinispan this would be a cache instance, DataContainer to be exact. &nbsp;</div><div><br><blockquote type="cite"><div style="WORD-WRAP: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space">
<div dir="ltr" align="left"><span class="131211200-03022010"><font face="Courier New" color="#0000ff" size="4"></font></span>&nbsp;</div>
<div dir="ltr" align="left"><span class="131211200-03022010"><font face="Courier New" color="#0000ff" size="4">However, I like your approach better.</font></span></div>
<div dir="ltr" align="left"><span class="131211200-03022010"><font face="Courier New" color="#0000ff" size="4"></font></span>&nbsp;</div>
<div dir="ltr" align="left"><span class="131211200-03022010"><font face="Courier New" color="#0000ff" size="4">Bryan</font></span></div>
<div><font face="Courier New" color="#0000ff" size="4"></font>&nbsp;</div>
<div><span class="131211200-03022010"><font face="Courier New" color="#0000ff" size="4">PS: I see a comment on LRU#onEntryHit() indicating that it is invoked 
without holding the Segment lock.&nbsp; Is that true only when BCHM#get() is 
invoked?</font></span></div></div></blockquote><div><br></div><div>Yes, I'll change javadoc to say : "is potentially invoked without holding a lock".</div><br><blockquote type="cite"><div style="WORD-WRAP: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space">
<div><span class="131211200-03022010"><font face="Courier New" color="#0000ff" size="4"></font></span>&nbsp;</div>
<div><span class="131211200-03022010"><font face="Courier New" color="#0000ff" size="4">PPS: Also, can you expand on the role of the LRU#accessQueue vs 
LRU#lruQueue?&nbsp; Is there anything which corresponds to the total LRU order 
(after batching updates through the Segment)?</font></span></div></div></blockquote><div><br></div><div><br></div><div>LRU#accessQueue records hits on a Segment. This is the batching FIFO queue from BP-Wrapper paper except it is not per thread but rather per Segment. Notice that LRU#accessQueue is lock free but thread safe since we expect a lot of threads recording accesses per Segment. Ideal collection for this use case is <span class="Apple-style-span" style="font-family: 'Lucida Grande'; font-size: 11px; ">ConcurrentLinkedQueue.&nbsp;</span></div><div><br></div><div>LRU#lruQueue is simply just a simple LRU stack implementation with one end of the queue holding most recently accessed entries and the other end of the queue with least recently accessed entries.</div><div><br></div><div><br></div><div>Regards,</div><div>Vladimir</div><div><br></div><div><br></div></div></div></body></html>