<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=iso-8859-1">
<STYLE type=text/css>DIV {
        MARGIN: 0px
}
</STYLE>

<META content="MSHTML 6.00.5730.11" name=GENERATOR></HEAD>
<BODY>
<DIV dir=ltr align=left><SPAN class=781370113-23012007><FONT face=Arial 
color=#0000ff size=2>Connections and transactions should live as long as the 
cache, not a single mdx query.</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=781370113-23012007><FONT face=Arial 
color=#0000ff size=2></FONT></SPAN>&nbsp;</DIV>
<DIV dir=ltr align=left><SPAN class=781370113-23012007><FONT face=Arial 
color=#0000ff size=2>I am about to check in other changes to the rolapstar like 
I described before in this thread,</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=781370113-23012007><FONT face=Arial 
color=#0000ff size=2>please note that transactions and connection change will 
not be there yet.&nbsp; The changes</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=781370113-23012007><FONT face=Arial 
color=#0000ff size=2>I will check in have most of to do with multi-user access 
and the plugin.</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=781370113-23012007><FONT face=Arial 
color=#0000ff size=2></FONT></SPAN>&nbsp;</DIV>
<DIV dir=ltr align=left><SPAN class=781370113-23012007><FONT face=Arial 
color=#0000ff size=2>When a query is executed, first changes are checked by 
using the data source change listener plugin.</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=781370113-23012007><FONT face=Arial 
color=#0000ff size=2></FONT></SPAN>&nbsp;</DIV>
<DIV dir=ltr align=left><SPAN class=781370113-23012007><FONT face=Arial 
color=#0000ff size=2>When changes are detected, than the transaction for - this 
thread only - should be stopped and a new</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=781370113-23012007><FONT face=Arial 
color=#0000ff size=2>one should be taken.&nbsp; Other concurrently running 
threads should use the old connection/transactions.</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=781370113-23012007><FONT face=Arial 
color=#0000ff size=2></FONT></SPAN>&nbsp;</DIV>
<DIV dir=ltr align=left><SPAN class=781370113-23012007><FONT face=Arial 
color=#0000ff size=2>When new queries are executed after changes have check in, 
a new connection/transaction should be started.</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=781370113-23012007><FONT face=Arial 
color=#0000ff size=2></FONT></SPAN>&nbsp;</DIV>
<DIV dir=ltr align=left><SPAN class=781370113-23012007><FONT face=Arial 
color=#0000ff size=2>That way, a&nbsp;single mdx query should always look at the 
same data - what should be the whole point.</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=781370113-23012007><FONT face=Arial 
color=#0000ff size=2></FONT></SPAN>&nbsp;</DIV>
<DIV dir=ltr align=left><SPAN class=781370113-23012007><FONT face=Arial 
color=#0000ff size=2>The changes I have made now apply to the data source change 
listener plugin, but a similar approach could</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=781370113-23012007><FONT face=Arial 
color=#0000ff size=2>be taken for explicit cache flushing.</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=781370113-23012007><FONT face=Arial 
color=#0000ff size=2></FONT></SPAN>&nbsp;</DIV>
<DIV dir=ltr align=left><SPAN class=781370113-23012007><FONT face=Arial 
color=#0000ff size=2>Bart</FONT></SPAN></DIV><BR>
<DIV class=OutlookMessageHeader lang=en-us dir=ltr align=left>
<HR tabIndex=-1>
<FONT face=Tahoma size=2><B>From:</B> mondrian-bounces@pentaho.org 
[mailto:mondrian-bounces@pentaho.org] <B>On Behalf Of </B>michael 
bienstein<BR><B>Sent:</B> dinsdag 23 januari 2007 13:52<BR><B>To:</B> Mondrian 
developer mailing list<BR><B>Subject:</B> Re : [Mondrian] 
Re:VirtualCubeTest.testCalculatedMemberAcrossCubesfailing on 
SMP<BR></FONT><BR></DIV>
<DIV></DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">Just 
two thoughts on this:</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">1) 
Currently I think that a HashMap is used for the global cache.&nbsp; HashMap is 
not safely synchronized.&nbsp; There is a synchronize block that is too large 
probably - the whole aggregations data.&nbsp; </DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">2) 
Two-tier using threadlocal sounds good.&nbsp; Can we do this idea:</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">interface 
QueryContext&nbsp;{</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
Connection getConnection(DataSource ds);</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
some sort of common filter for aggregation cache and hierarchy caches</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
void dispose();</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">}</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">class 
QueryContextImpl {</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
private HashMap&lt;DataSource, Connection&gt; openConnections = new 
HashMap&lt;DataSource,Connection&gt;();</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
public Connection getConnection(DataSource ds) {</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
Connection c = openConnections.get(ds);</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; if (c != null) {</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return c;</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; }</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; try {</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c = ds.getConnection();</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; openConnections.put(ds, c);</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return c;</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; } catch (SQLException ex) {</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; throw new 
MondrianExceptionOrSomething(ex);</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; }</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
}</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
//TODO some filtering to the global aggregation and hierarchy caches</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
public void dispose() {</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; for (Connection c : openConnections.valueSet()) {</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; try {</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; c.close();</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } catch (SQLException ex) {</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; log it ...</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; }</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
}</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">}</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">RolapResult.java:</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">{</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
private static ThreadLocal&lt;QueryContext&gt; qContext = new 
ThreadLocal&lt;QueryContext&gt;();</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
public static QueryContext getQueryContext() {</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; return qContext.get();</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
}</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
public RolapResult(...) {</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
...</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; if (!execute) {</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return;</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; }</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //Going to execute</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; QueryContext qc = createQueryContext();</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; qContext.set(qc);</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; try {</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //Do execute stuff here</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; } finally {</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; qContext.clear();</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; qc.dispose();</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; }</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
}&nbsp; </DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
//Use a property to override the class used?&nbsp; That way we can configure 
each Connection specifically?</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
public QueryContext createQueryContext() {</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; return new QueryContextImpl();</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;&nbsp;&nbsp; 
}<BR>}<BR>//All places in the code base that use DataSource to obtain a 
Connection in the context of a query should use:</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">Connection 
c = RolapResult.getQueryContext().getConnection(ds);</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">That 
way we only open one connection per query and we use the database's transaction 
system.</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">I 
found this hard to do because of the RolapConnection/RolapCube constructors 
calling each other somehow (can't remember the details).</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">&nbsp;</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">Michael</DIV>
<DIV 
style="FONT-SIZE: 12pt; FONT-FAMILY: times new roman, new york, times, serif">----- 
Message d'origine ----<BR>De : Julian Hyde &lt;julianhyde@speakeasy.net&gt;<BR>À 
: Mondrian developer mailing list &lt;mondrian@pentaho.org&gt;<BR>Envoyé le : 
Mardi, 23 Janvier 2007, 11h57mn 24s<BR>Objet&nbsp;: RE: [Mondrian] Re: 
VirtualCubeTest.testCalculatedMemberAcrossCubesfailing on SMP<BR><BR>
<DIV dir=ltr align=left><SPAN class=200204710-23012007><FONT face=Verdana 
color=#000080 size=2>I think the problem is with how mondrian evaluates members 
using multiple passes. When the measures are coming from a virtual cube, of 
course there are multiple real cubes, and each of those has a cell reader. But 
the code in RolapResult assumes there is only one cell 
reader.</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=200204710-23012007><FONT face=Verdana 
color=#000080 size=2></FONT></SPAN>&nbsp;</DIV>
<DIV dir=ltr align=left><SPAN class=200204710-23012007><FONT face=Verdana 
color=#000080 size=2>Mondrian should check the cell readers for all applicable 
cubes, and only emit a result when all cell readers have been 
populated.</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=200204710-23012007><FONT face=Verdana 
color=#000080 size=2></FONT></SPAN>&nbsp;</DIV>
<DIV dir=ltr align=left><SPAN class=200204710-23012007><FONT face=Verdana 
color=#000080 size=2>I haven't implemented the fix yet, but this cause seems 
very plausible to me.</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=200204710-23012007><FONT face=Verdana 
color=#000080 size=2></FONT></SPAN>&nbsp;</DIV>
<DIV dir=ltr align=left><SPAN class=200204710-23012007><FONT face=Verdana 
color=#000080 size=2>I'm not exactly sure why this problem surfaced after Bart's 
change&nbsp;- maybe thread-local caches increased the chances of one cache being 
populated and another not - or why it appears on SMP 
machines.</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=200204710-23012007><FONT face=Verdana 
color=#000080 size=2></FONT></SPAN>&nbsp;</DIV>
<DIV dir=ltr align=left><SPAN class=200204710-23012007><FONT face=Verdana 
color=#000080 size=2>By the way, in an effort to get this working, I removed 
Bart's RolapStarAggregationKey (a compound key of BitKey and thread id) and 
moved to a two-tier hashing scheme. The first tier is a ThreadLocal of maps, and 
the second tier is a map. Threads which want access to the global map just skip 
the first tier. Given the difficulties obtaining a unique id for a thread, using 
a ThreadLocal seemed cleaner. So, even though this didn't fix the bug, I'm going 
to check in.</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=200204710-23012007><FONT face=Verdana 
color=#000080 size=2></FONT></SPAN>&nbsp;</DIV>
<DIV dir=ltr align=left><SPAN class=200204710-23012007><FONT face=Verdana 
color=#000080 size=2>Julian</FONT></SPAN></DIV></DIV></DIV><BR>
<HR SIZE=1>
Découvrez une nouvelle façon d'obtenir des réponses à toutes vos questions ! 
Profitez des connaissances, des opinions et des expériences des internautes sur 
<A href="http://fr.rd.yahoo.com/evt=42054/*http://fr.answers.yahoo.com">Yahoo! 
Questions/Réponses</A>. 
<BR>______________________________________________________________________<BR>This 
email has been scanned by the Email Security 
System.<BR>______________________________________________________________________<BR></BODY></HTML>