<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="weebly" -->
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" >

<channel><title><![CDATA[Distributed Information System (DIS) - The blog]]></title><link><![CDATA[http://www.disnetwork.info/the-blog.html]]></link><description><![CDATA[The blog]]></description><pubDate>Tue, 09 Jun 2009 13:17:35 +0700</pubDate><generator>Weebly</generator><item><title><![CDATA[Median value selection algorithm]]></title><link><![CDATA[http://www.disnetwork.info/1/post/2009/06/median-value-selection-algorithm.html]]></link><comments><![CDATA[http://www.disnetwork.info/1/post/2009/06/median-value-selection-algorithm.html#comments]]></comments><pubDate>Tue, 09 Jun 2009 13:11:15 +0700</pubDate><category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://www.disnetwork.info/1/post/2009/06/median-value-selection-algorithm.html</guid><description><![CDATA[At work I'm currently working on tomographic reconstruction algorithms. I have to implement a Bayesian iterative algorithm that requires to select the median value in a set of the 27 float values from a cube of 3x3x3 voxels. This operation must be performed for each voxel and for each iteration. We have to expect 256 million voxels to process for each iteration, but "only" 60 to 100 iterations. Trying to find the most efficient algorithm I came up with [...] ]]></description><content:encoded><![CDATA[<p  style=" text-align: left; ">At work I'm currently working on tomographic reconstruction algorithms. I have to implement a Bayesian iterative algorithm that requires to select the median value in a set of the 27 float values from a cube of 3x3x3 voxels. This operation must be performed for each voxel and for each iteration. We have to expect 256 million voxels to process for each iteration, but "only" 60 to 100 iterations. <br /><br />Trying to find the most efficient algorithm I came up with a new algorithm considering the one described on the <a href="http://en.wikipedia.org/wiki/Selection_algorithm.">select algorithm page of wikipedia</a>. I then submitted a question on <a href="http://stackoverflow.com/questions/810657/fastest-code-c-c-to-select-the-median-in-a-set-of-27-floating-point-values">StackOverflow</a> to get some feedback. And I did get valuable feedback. I was first pointed to the C++ nth_element function I didn't know at the time. It was also suggest to optimize by sharing intermediate information which is indeed a smart thing to do to get a better initial guess on the median value. <br /><br />After multiple tests and changes to the code I finally reached what seem to be a very efficient algorithm. The ratio is so good that I'm still unsure about it, but I checked everything. It could be due to memory cache or particularly favorable parallelization opportunities with sse instructions. I don't know. <br /><br />Here is the outline of the algorithm. We have 27 values and have to find the value that split the set in two with 13 values smaller or equal to it and 13 values bigger or equal to it. This value is called the median value. <br /><br />The fundamental idea of the algorithm is to use a heap data structure which has its smallest or biggest value at the top. Such data structure is very efficient for adding an element or to extract its top most element. It can also be very easily mapped into an array. <br /><br />The algorithm uses two heaps initially empty, with a common top value which is the median value. Each heap has a capacity of at most 14 elements, where one is common to the two heaps, their top value and also the median value.<br />The algorithm proceed in two phases. In the first phase, the algorithm picks a value as initial median value guess. Subsequent values are then compare with this median value and added to the corresponding heap until one heap becomes full and contains 14 elements. <br /><br />At this point the median value is a value in the full heap or in the remaining set of values to process. The second phase of the algorithm then starts where the remaining values are processed. Values that would not be inserted in the full heap are ignored. The other values are inserted in the full heap after deleting its top most value. The heap then gets a new top most value and thus also a new median value. When all the remaining elements have been processed, the median of the 27 value set is the top most value of the full heap. <br /><br />Here are some benchmark results. See <a href="http://stackoverflow.com/questions/810657/fastest-code-c-c-to-select-the-median-in-a-set-of-27-floating-point-values">StackOverflow</a> for more detailed information.<br /><br /><span>HeapSort</span><span> &nbsp; &nbsp;&nbsp; &nbsp; </span><span>:</span><span>2.287</span><span>&nbsp; <br /></span><span>QuickSort</span><span> &nbsp; &nbsp;&nbsp;&nbsp; </span><span>:</span><span>2.297</span><span>&nbsp; </span><span><br />QuickMedian1 </span><span>:</span><span>0.967&nbsp; </span><span><br />HeapMedian1 &nbsp;</span><span>:</span><span>0.858</span><span>&nbsp; <br /></span><span>NthElement</span><span> &nbsp;&nbsp;&nbsp; </span><span>:</span><span>0.616</span><span>&nbsp; </span><span><br />QuickMedian2 </span><span>:</span><span>1.178</span><span>&nbsp; </span><span><br />HeapMedian2 &nbsp;</span><span>:</span><span>0.597</span><span>&nbsp; </span><span><br />HeapMedian3 &nbsp;</span><span>:</span><span>0.015</span><span>&nbsp; </span><span>&lt;--</span><span> best</span><br /><br />It thus seem that HeapMedian3 is 33 times faster than NthElement. I used a 3GHz Intel E8400 processor and the Intel C++ compiler with options -03 and -xS for benchmarking. <br /><br />Here is the code :<br /><br /><span>// return the median value in a vector of 27 floats pointed to by a</span><span><br />float</span><span> heapMedian3</span><span>( </span><span>float</span><span>*</span><span>a </span><span>)<br /></span><span>{</span><span><br />&nbsp; &nbsp;</span><span>float</span><span> left</span><span>[</span><span>14</span><span>],</span><span> right</span><span>[</span><span>14</span><span>],</span><span> median</span><span>,</span><span>*</span><span>p</span><span>;</span><span><br />&nbsp; &nbsp;</span><span>unsigned</span><span> char</span><span> nLeft</span><span>,</span><span> nRight</span><span>;</span><span><br /><br />&nbsp; &nbsp;</span><span>// pick first value as median candidate</span><span><br />&nbsp; &nbsp;p </span><span>=</span><span> a</span><span>;</span><span><br />&nbsp; &nbsp;median </span><span>=</span><span> *</span><span>p</span><span>++;</span><span><br />&nbsp; &nbsp;nLeft </span><span>=</span><span> nRight </span><span>=</span><span>1</span><span>;</span><span><br /><br />&nbsp; &nbsp;</span><span>for</span><span>(;;)</span><span><br />&nbsp; &nbsp;</span><span>{</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp;</span><span>// get next value</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp;</span><span>float</span><span> val </span><span>= </span><span>*</span><span>p</span><span>++;</span><span><br /><br />&nbsp; &nbsp; &nbsp; &nbsp;</span><span>// if value is smaller than median, append to left heap</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp;</span><span>if</span><span>(</span><span> val </span><span>&lt;</span><span> median </span><span>)</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp;</span><span>{</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>// move biggest value to the heap top</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>unsigned</span><span> char</span><span> child </span><span>=</span><span> nLeft</span><span>++,</span><span> parent </span><span>= </span><span>(</span><span>child </span><span>-</span><span>1</span><span>)</span><span>/</span><span>2</span><span>;</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>while</span><span>(</span><span> parent </span><span>&amp;&amp;</span><span> val </span><span>&gt;</span><span> left</span><span>[</span><span>parent</span><span>]</span><span> )</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>{</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;left</span><span>[</span><span>child</span><span>]</span><span> =</span><span> left</span><span>[</span><span>parent</span><span>];</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;child </span><span>=</span><span> parent</span><span>;</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;parent </span><span>=</span><span>(</span><span>parent </span><span>-</span><span>1</span><span>)</span><span>/</span><span>2</span><span>;</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>}</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;left</span><span>[</span><span>child</span><span>]</span><span> =</span><span> val</span><span>;</span><span><br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>// if left heap is full</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>if</span><span>(</span><span> nLeft </span><span>== </span><span>14</span><span>)</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>{</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>// for each remaining value</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>for</span><span>(</span><span> unsigned</span><span> char</span><span> nVal </span><span>=</span><span> 27</span><span>-</span><span>(</span><span>p </span><span>-</span><span> a</span><span>);</span><span> nVal</span><span>;</span><span> --</span><span>nVal </span><span>)</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>{</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>// get next value</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;val </span><span>=</span><span> *</span><span>p</span><span>++;</span><span><br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>// if value is to be inserted in the left heap</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>if</span><span>(</span><span> val </span><span>&lt;</span><span> median </span><span>)</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>{</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;child </span><span>=</span><span> left</span><span>[</span><span>2</span><span>] </span><span>&gt;</span><span> left</span><span>[</span><span>1</span><span>] </span><span>? </span><span>2 </span><span>: </span><span>1</span><span>;</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>if</span><span>(</span><span> val </span><span>&gt;=</span><span> left</span><span>[</span><span>child</span><span>]</span><span>)</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;median </span><span>=</span><span> val</span><span>;</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>else</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>{</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;median </span><span>=</span><span> left</span><span>[</span><span>child</span><span>];</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;parent </span><span>=</span><span> child</span><span>;</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;child </span><span>=</span><span> parent</span><span>*</span><span>2</span><span> + </span><span>1</span><span>;</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>while</span><span>(</span><span> child </span><span>&lt;</span><span>14</span><span> )</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>{</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>if</span><span>(</span><span> child </span><span>&lt;</span><span> 13 </span><span>&amp;&amp;</span><span> left</span><span>[</span><span>child</span><span>+</span><span>1</span><span>]</span><span> &gt;</span><span> left</span><span>[</span><span>child</span><span>] </span><span>)</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>++</span><span>child</span><span>;</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>if</span><span>(</span><span> val </span><span>&gt;=</span><span> left</span><span>[</span><span>child</span><span>] </span><span>)</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>break</span><span>;</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;left</span><span>[</span><span>parent</span><span>]</span><span> =</span><span> left</span><span>[</span><span>child</span><span>];</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;parent </span><span>=</span><span> child</span><span>;</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;child </span><span>=</span><span> parent</span><span>*</span><span>2</span><span> + </span><span>1</span><span>;</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>}</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;left</span><span>[</span><span>parent</span><span>]</span><span> =</span><span> val</span><span>;</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>}</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>}</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>}</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>return</span><span> median</span><span>;</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>}</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp;</span><span>}</span><span><br /><br />&nbsp; &nbsp; &nbsp; &nbsp;</span><span>// else append to right heap</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp;</span><span>else</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp;</span><span>{</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>// move smallest value to the heap top</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>unsigned</span><span> char</span><span> child </span><span>=</span><span> nRight</span><span>++,</span><span> parent </span><span>=</span><span> (</span><span>child </span><span>-</span><span>1</span><span>)</span><span>/</span><span>2</span><span>;</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>while</span><span>(</span><span> parent </span><span>&amp;&amp;</span><span> val </span><span>&lt;</span><span> right</span><span>[</span><span>parent</span><span>]</span><span> )</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>{</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;right</span><span>[</span><span>child</span><span>] </span><span>=</span><span> right</span><span>[</span><span>parent</span><span>];</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;child </span><span>=</span><span> parent</span><span>;</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;parent </span><span>=</span><span> (</span><span>parent </span><span>-</span><span>1</span><span>)</span><span>/</span><span>2</span><span>;</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>}</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;right</span><span>[</span><span>child</span><span>]</span><span> =</span><span> val</span><span>;</span><span><br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>// if right heap is full</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>if</span><span>(</span><span> nRight </span><span>==</span><span> 14 </span><span>)</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>{</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>// for each remaining value</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>for</span><span>(</span><span> unsigned</span><span> char</span><span> nVal </span><span>=</span><span> 27</span><span>-</span><span>(</span><span>p </span><span>-</span><span> a</span><span>);</span><span> nVal</span><span>;</span><span> --</span><span>nVal </span><span>)</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>{</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>// get next value</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;val </span><span>= </span><span>*</span><span>p</span><span>++;</span><span><br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>// if value is to be inserted in the right heap</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>if</span><span>(</span><span> val </span><span>&gt;</span><span> median </span><span>)</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>{</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;child </span><span>=</span><span> right</span><span>[</span><span>2</span><span>]</span><span> &lt;</span><span> right</span><span>[</span><span>1</span><span>]</span><span> ?</span><span> 2</span><span> :</span><span> 1</span><span>;</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>if</span><span>(</span><span> val </span><span>&lt;=</span><span> right</span><span>[</span><span>child</span><span>] </span><span>)</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;median </span><span>=</span><span> val</span><span>;</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>else</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>{</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;median </span><span>=</span><span> right</span><span>[</span><span>child</span><span>];</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;parent </span><span>=</span><span> child</span><span>;</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;child </span><span>=</span><span> parent</span><span>*</span><span>2</span><span> +</span><span> 1</span><span>;</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>while</span><span>(</span><span> child </span><span>&lt;</span><span>14 </span><span>)</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>{</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>if</span><span>(</span><span> child </span><span>&lt;</span><span> 13</span><span> &amp;&amp;</span><span> right</span><span>[</span><span>child</span><span>+</span><span>1</span><span>] </span><span>&lt;</span><span> right</span><span>[</span><span>child</span><span>] </span><span>)</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>++</span><span>child</span><span>;</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>if</span><span>(</span><span> val </span><span>&lt;=</span><span> right</span><span>[</span><span>child</span><span>]</span><span> )</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>break</span><span>;</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;right</span><span>[</span><span>parent</span><span>]</span><span> =</span><span> right</span><span>[</span><span>child</span><span>];</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;parent </span><span>=</span><span> child</span><span>;</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;child </span><span>=</span><span> parent</span><span>*</span><span>2 </span><span>+ </span><span>1</span><span>;</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>}</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;right</span><span>[</span><span>parent</span><span>]</span><span> =</span><span> val</span><span>;</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>}</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>}</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>}</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>return</span><span> median</span><span>;</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span>}</span><span><br />&nbsp; &nbsp; &nbsp; &nbsp;</span><span>}</span><span><br />&nbsp; &nbsp;</span><span>}<br /></span><span>}</span><br /><br /></p>]]></content:encoded></item><item><title><![CDATA[Post Title.]]></title><link><![CDATA[http://www.disnetwork.info/1/post/2009/05/post-title-click-and-type-to-edit1.html]]></link><comments><![CDATA[http://www.disnetwork.info/1/post/2009/05/post-title-click-and-type-to-edit1.html#comments]]></comments><pubDate>Sun, 17 May 2009 23:23:48 +0700</pubDate><category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://www.disnetwork.info/1/post/2009/05/post-title-click-and-type-to-edit1.html</guid><description><![CDATA[When sketching out your business model or marketing strategy, read the following blog note or referenced book. There are easy ways to increase your efficiency. Yes! 50 Scientifically Proven Ways to Be&nbsp;Persuasive. [...] ]]></description><content:encoded><![CDATA[<p  style=" text-align: left; ">When sketching out your business model or marketing strategy, read the following blog note or referenced book. There are easy ways to increase your efficiency. <br /><br /><a href="http://www.moskalyuk.com/blog/yes-50-scientifically-proven-ways-to-be-persuasive/1624">Yes! 50 Scientifically Proven Ways to Be&nbsp;Persuasive<span style="text-decoration: underline;">.</span></a></p>]]></content:encoded></item><item><title><![CDATA[Object deserialization handling]]></title><link><![CDATA[http://www.disnetwork.info/1/post/2009/02/object-deserialization-handling.html]]></link><comments><![CDATA[http://www.disnetwork.info/1/post/2009/02/object-deserialization-handling.html#comments]]></comments><pubDate>Sat, 07 Feb 2009 05:27:52 +0700</pubDate><category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://www.disnetwork.info/1/post/2009/02/object-deserialization-handling.html</guid><description><![CDATA[In the last month I rewrote the IDR prototype from scratch and translated the IDR specification document in English. During this process I made a few enhancements in the IDR encoding. I removed an ambiguity with exceptions decoding in some very unlikely situations. The other change was to integrate the update of IEEE 754 specification in 2008 that now defines four types of floating point values, 2 Bytes,  [...] ]]></description><content:encoded><![CDATA[<p  style=" text-align: left; ">In the last month I rewrote the IDR prototype from scratch and translated the IDR specification document in English. During this process I made a few enhancements in the IDR encoding. I removed an ambiguity with exceptions decoding in some very unlikely situations. The other change was to integrate the update of IEEE 754 specification in 2008 that now defines four types of floating point values, <a href="http://en.wikipedia.org/wiki/Half_precision">2 Bytes</a>, <a href="http://en.wikipedia.org/wiki/Single_precision">4 Bytes</a>, <a href="http://en.wikipedia.org/wiki/Double_precision">8 Bytes</a> and <a href="http://en.wikipedia.org/wiki/Quadruple_precision">16 Bytes</a>. It may take some time until these types reach your desk, but IDR should better stick to the standards. So these will be the floating point encodings supported by IDR. <br /><br />Beside these, there was a much bigger problem left in the API of object deserialization. The problem is to determine what to do when the decoder doesn't recognize the class type of a serialized object. The solution I came up is very satisfying since it matches all the requirements I had. It remains to check its usage convenience with real examples. <br /><br /><span style="font-weight: bold;">The problem</span><br /><br />Object deserialization is a process in which the decoder reconstruct the serialized object aggregate. To do so it has to reconstruct each object of the aggregate and&nbsp; restore their pointers to each other. Objects are reconstructed by using object factories, a classic in design pattern. An object factory is an object that "knows" how to reconstruct some types of objects. <br /><br />The decoder has thus a collection of factories to which it delegates the reconstruction of the different types of objects found in the serialized aggregate. But what happens if the decoder can't find an appropriate factory for some type of serialized object ? In some use case this should be considered as an error, but in others it might be an acceptable and even desirable situation.&nbsp; <br /><br />Consider for instance exceptions. In IDR an exception is an object and handled as such. There is no point, and even impossible,  for a decoder to have a factory for all possible exceptions in the world. It is enough for the decoder to have a factory for the common exception base classes and, of course, the one it has to deal with. It should then be enough to reconstruct the object as an instance of the parent class it has a factory for, a process called <span style="font-style: italic;">object slicing</span>. <br /><br />The worst case is when the decoder may not even slice the object because none of the parent class is "known" by the decoder. In this case the best the decoder can do is to ignore the object and set all references to it to NULL. We'll call this process <span style="font-style: italic;">object pruning</span>. As for slicing, it may be considered as an acceptable and even desirable behavior with some use cases (i.e optional properties), and an error in others since the lobotomized data structured may end up too crippled or even invalid. <br /><br />The problem is thus to define the appropriate behaviour of the decoder when a slicing or pruning occurs. In some case it is an error, in others not, and in some case it depends on what part of the aggregate the slicing or pruning took place. <br /><br /><span style="font-weight: bold;">The solution</span><br /><br />The decision whether it is an error or not is obviously context specific and have thus to be put in the hands of the user. So the problem boiled down to determine how the user would able to select the appropriate behavior. <br /><br />The solution I came up was to provide three object deserialization methods. <br /><br />1. A strict object decoder that would throw an exception and abort object decoding as soon as a missing object factory is detected. With this you get an exact reconstruction or a failure. <br /><br />2. A lax object decoder that would slice and prune at will and return whatever comes out of it, and nothing else. This object decoder would for instance be used for exceptions. <br /><br />3. Another lax object decoder, like the previous one, but that would also return a feedback on the missing object factories. The feedback on slicing would be an associative index mapping sliced object references to the list of their unrecognized classs types. The feedback on pruning would be a list of the different types of pruned object with a list of the unrecognized class type and the number of instance pruned. <br /><br />The later method would make it possible and easy for the user to determine if slicing and pruning occurred, what are the missing factories and test for specific objects if slicing took place and to what extend. Since this method would give an easy way to test if slicing or pruning took place, the strict object decoder may seem unnecessary. The reason of its presence is that it may stop the decoding process as soon as a missing factory is detected and thus avoid wasting resources when an exact reconstruction is required and no feedback is needed. <br /><br />I'm very satisfied by this solution because it keeps the API simple with only a small effort on the decoder implementation. What I still need to validate is how convenient it is to use. <br /></p>]]></content:encoded></item><item><title><![CDATA[StackOverflow: general purpose binary protocols]]></title><link><![CDATA[http://www.disnetwork.info/1/post/2009/01/stackoverflow-general-purpose-binary-protocols.html]]></link><comments><![CDATA[http://www.disnetwork.info/1/post/2009/01/stackoverflow-general-purpose-binary-protocols.html#comments]]></comments><pubDate>Sat, 10 Jan 2009 03:13:46 +0700</pubDate><category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://www.disnetwork.info/1/post/2009/01/stackoverflow-general-purpose-binary-protocols.html</guid><description><![CDATA[I just found a relevant question on StackOverflow asking for a good general purpose binary protocol. If you are interested in distributed information systems and their protocols, this topic might be a good read.  [...] ]]></description><content:encoded><![CDATA[<p  style=" text-align: left; ">I just found a relevant question on <a href="http://stackoverflow.com/">StackOverflow</a> asking for a good general purpose binary protocol. If you are interested in distributed information systems and their protocols, <a href="http://stackoverflow.com/questions/352433/general-purpose-binary-protocols">this topic</a> might be a good read. <br /></p>]]></content:encoded></item><item><title><![CDATA[DIS development roadmap]]></title><link><![CDATA[http://www.disnetwork.info/1/post/2008/11/dis-development-roadmap.html]]></link><comments><![CDATA[http://www.disnetwork.info/1/post/2008/11/dis-development-roadmap.html#comments]]></comments><pubDate>Wed, 12 Nov 2008 05:34:51 +0700</pubDate><category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://www.disnetwork.info/1/post/2008/11/dis-development-roadmap.html</guid><description><![CDATA[The following figure shows the kernel components of the Distributed Information System, the road map and how far I am today. The items in black are implemented and operational and the items in gray still needs to be implemented. Progress is going clockwise :). [...] ]]></description><content:encoded><![CDATA[<p  style=" text-align: left; ">The following figure shows the kernel components of the <span style="font-weight: bold;">Distributed Information System</span>, the road map and how far I am today. The items in black are implemented and operational and the items in gray still needs to be implemented. Progress is going clockwise :).<br /></p><div ><div style="text-align: center;"><a><img src="/uploads/3/8/0/1/38014/7514476.png?248x252" style="margin-top: 0; margin-bottom: 0; margin-left: 0; margin-right: 10px; border: none;" /></a></div></div><p  style=" text-align: left; "><big style="color: rgb(0, 0, 0);"><big><span style="font-weight: bold;">OID</span></big></big> An OID is to DIS what the URL is to the web. It is a unique, binary encoded  and non reusable reference to an information published in the distributed information system. It was the first tile I designed and implemented. Its simplicity is inversely proportional to the time and effort required to invent it because I had to explore and compare many different possible and existing solutions. <br /><br /><big style="color: rgb(0, 0, 0);"><big><span style="font-weight: bold;">IDR</span></big></big> It is to DIS what HTML or XML is to the web. IDR is the Information Data Representation used in DIS. It is a stream oriented encoding with support of object serialization and exceptions. The prototype implementation is currently being fully rewritten. It still miss the ability to specify the encoding version or a formalization of data description. The later is required to be able to display data in a human readable format or to automatically generate data manipulation functions or containers mapped to different programming languages. <br /><br /><big style="color: rgb(0, 0, 0);"><big><span style="font-weight: bold;">DITP</span></big></big> It is to DIS what HTTP is to the web. It is the protocol used to exchange information or invoke remote actions in DIS. It is very simple, modular and extensible through the use of dynamically configurable data processing tasks. Support of compression, authentication or encryption is then provided by some kinds of plugins. The protocol use the object oriented model with remote method invocation. The current prototype does not yet support concurrent asynchronous method invocation. <br /><br /><big style="color: rgb(0, 0, 0);"><big><span style="font-weight: bold;">DIS</span></big></big> DIS stands here for Distributed Information Service and is not to be confused with Distributed Information System. It is fundamental to DIS, so a confusion is not really a problem. This service combines the properties of DNS and LDAP and would be a new kind of service on the Internet. I can't disclose more&nbsp; on it because it is still in development. A first prototype has been implemented unfortunately proving the need to support data description. <br /><br /><big style="color: rgb(0, 0, 0);"><big><span style="font-weight: bold;">SEC</span></big></big> This part covers authentication and access control in DIS. It requires a functional DIS service. An interesting feature is that it is designed to scale up so that a service could cope with millions of different users without having to keep track of million accounts and passwords.<br /><br /><big style="color: rgb(0, 0, 0);"><big><span style="font-weight: bold;">IDX</span></big></big> It is a service simply mapping human readable UTF8 strings to OID references. It is equivalent to the list of named entries in a directory. Like any other services, its access is controlled by ACL and can thus be modified remotely with appropriate privileges. An index may be huge with multiple alternate entry point, exactly like the DNS but exclusively as a flat name space. The OID associated to the UTF8 string is stored in an object so that polymorphism allow to associate images (icons) and other informations to entries by extension.<br /><br /><big style="color: rgb(0, 0, 0);"><big><span style="font-weight: bold;">DIR</span></big></big> It is a graph of IDX services with one root entry. Services or information published in DIS can then be referenced by a humanly readable path in the IDX graph relative to the root.<br /><br /><br /><br />It is an ambitious project but, I am convinced, its added value is worth the effort. I wish I could work full time on this project with the help of some other developers, but this would require funding I don't have access to for now. <br /><br />An application would help demonstrating the added value of the system. I'm still looking for one with an optimal balance in development effort and success potential. <br /></p>]]></content:encoded></item><item><title><![CDATA[Debugging DIS]]></title><link><![CDATA[http://www.disnetwork.info/1/post/2008/09/debugging-dis.html]]></link><comments><![CDATA[http://www.disnetwork.info/1/post/2008/09/debugging-dis.html#comments]]></comments><pubDate>Mon, 08 Sep 2008 06:28:50 +0700</pubDate><category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://www.disnetwork.info/1/post/2008/09/debugging-dis.html</guid><description><![CDATA[While developing a prototype of DIS to check and validate it, I'm frequently confronted to bugs. One reason is that the complexity of the program is comparable to a compiler. Individual encodin [...] ]]></description><content:encoded><![CDATA[<span  style=" float: left; z-index: 10; "><a href='http://www.freefoto.com'><img src="/uploads/3/8/0/1/38014/7702956.png" style="margin-top: 5px; margin-bottom: 10px; margin-left: 0px; margin-right: 10px; border: none; z-index: 10;" /></a></span><p  style=" text-align: left; display: block; ">While developing a prototype of DIS to check and validate it, I'm frequently confronted to bugs. <br /><br />One reason is that the complexity of the program is comparable to a compiler. Individual encoding rules are simple, but they can be used in an infinite set of combinations. <br /></p><hr  style=" visibility: hidden; clear: both; width: 100%; "></hr><p  style=" text-align: left; ">After testing many different debuggers on Linux, my conclusion is that none of them is as good as the one of Visual C++ on Windows. So when I have to develop new code which may require debugging, I always develop it with Visual C++. Once it is validated, I move it on Linux. <br /><br />The biggest difference is in the capability to explore data structures, STL containers, and other application specific data. If there wasn't Visual C++, I would have completely dropped Windows. It was thus a very smart marketing move of Microsoft to make Visual C++ available for free. <br /><br />But Visual C++ is not yet perfect. So when not debugging, I prefer working on Linux. On feature I'm really missing in Visual C++ is one provided in Eclipse. <br /><br />With object oriented programming, one usually store one class per file. I guess it is to simplify locating the class definition information. Simply look for a file with the same name as the class. The back side of this is that we end up with the code spread in many files. But when browsing the code, I often met a method call and would like to see its implementation. <br /><br />To do this I have to switch to, or open, the corresponding file, locate the method definition in the file. Once examined, I may want to go back to where I was before.<br /><br />Eclipse has this smart and powerful ability to change an identifier into a hyper text link. One simply move the pointer over the identifier and press the control key at the same time. The identifier changes into a hyper text link (underlined blue text) and a click moves you directly on the method implementation.<br /><br />In visual, you get a context menu when clicking on an identifier and then you have to locate and click the "go to definition" menu command. Two clicks.<br /></p>]]></content:encoded></item><item><title><![CDATA[Making DITP flexible, versatile and simple]]></title><link><![CDATA[http://www.disnetwork.info/1/post/2008/09/making-ditp-flexible-versatile-and-simple.html]]></link><comments><![CDATA[http://www.disnetwork.info/1/post/2008/09/making-ditp-flexible-versatile-and-simple.html#comments]]></comments><pubDate>Thu, 04 Sep 2008 13:22:47 +0700</pubDate><category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://www.disnetwork.info/1/post/2008/09/making-ditp-flexible-versatile-and-simple.html</guid><description><![CDATA[DITP is flexible, versatile and simple because it uses the inter-object communication model. Not only for the user needs to communicate with its service, but also to setup and configure the connecti [...] ]]></description><content:encoded><![CDATA[<span  style=" float: left; z-index: 10; "><a href='http://www.freefoto.com'><img src="/uploads/3/8/0/1/38014/4319212.jpg?167x110" style="margin-top: 0px; margin-bottom: 5px; margin-left: 0px; margin-right: 10px; border: none; z-index: 10;" /></a></span><p  style=" text-align: left; display: block; ">DITP is flexible, versatile and simple because it uses the inter-object communication model. Not only for the user needs to communicate with its service, but also to setup and configure the connection data processing (i.e. authentication, encryption, compression, logging, tunneling,...).<br /></p><hr  style=" clear: both; width: 100%; visibility: hidden; "></hr><p  style=" text-align: left; "><span style="font-weight: bold;">Inter-object communication</span><br /><br />By adopting the inter-object communication model users can create any type of service (remote object) they want. They can also extend or refine their capabilities by using inheritance with the polymorphism property and preserve backward compatibility at the same time. <br /><br />This makes DITP versatile and flexible, but any other inter-object communication protocol could claim the same. <br /><br /><span style="font-weight: bold;">Configuring and setting up the connection<br /><br /></span>What makes DITP different is that the connection configuration and setup are also performed by using the object oriented model. The different algorithms used are controlled by specific services and the client controls them by invoking the appropriate methods. <br /><br />This makes the protocol very flexible and versatile since the algorithm can be combined and configured in any way. It is easy to add support for new algorithms and there is no constrain on the transaction polka required to configure them.<br /><br />This design choice basically factorizes and parameterizes the protocol. What is left for DITP to define is how to open a connection, how to exchange messages between client and services and how to setup a new client-service binding. <br /><br /><span style="font-weight: bold;">Opening the DITP connection</span><br /><br />Opening a DITP connection implies a very simple transaction where the client and the service side exchange a four byte message. If both message contain the expected value, the connection is considered opened. It can hardly be made simpler. <br /><br />When the connection is opened the client and service implicitly attach a <span style="font-style: italic;">channel control service</span> to the connection. This service has very few methods. One is used to close the connection and the other to request the attachment of another service whose type and identity are given as argument. <br /><br />That is all it takes to have an operational DITP server. The exchanged messages have also a very simple structure, but will be described in another note because they have another original feature allowing to minimize latency. <br /><br />Once the connection is opened, if the client wants to secure the connection by adding authentication or encryption, he request the attachment of the corresponding services and configure them by calling their methods. <br /><br /><br />This is why I claim that DITP is versatile, flexible and simple. <br /></p>]]></content:encoded></item><item><title><![CDATA[Optimizing DITP connection open]]></title><link><![CDATA[http://www.disnetwork.info/1/post/2008/08/optimizing-ditp-connection-open.html]]></link><comments><![CDATA[http://www.disnetwork.info/1/post/2008/08/optimizing-ditp-connection-open.html#comments]]></comments><pubDate>Mon, 25 Aug 2008 09:52:14 +0700</pubDate><category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://www.disnetwork.info/1/post/2008/08/optimizing-ditp-connection-open.html</guid><description><![CDATA[The DITP protocol has been designed to minimize the time required to setup an operational connection. This is achieved by a simple method which is made explicit in the following figure.In common protocols, like HTTP and SMTP, [...] ]]></description><content:encoded><![CDATA[<p  style=" text-align: left; ">The DITP protocol has been designed to minimize the time required to setup an operational connection. This is achieved by a simple method which is made explicit in the following figure.<br /></p><div ><div style="text-align: center;"><a><img src="/uploads/3/8/0/1/38014/705893.png?490x241" style="margin-top: 0; margin-bottom: 0; margin-left: 0; margin-right: 0; border: none;" /></a></div></div><p  style=" text-align: left; ">In common protocols, like HTTP and SMTP, the server is expected to send a greeting before the client can respond and proceed by sending its first request. <br /><br />The time the client has to wait for this greeting message is usually dominated by the round trip time. In a LAN the round trip time is less than a millisecond, but on Internet it will take many tens of milliseconds and sometime hundreds of millisecond if the server is on another continent. <br /><br />By simply swapping the DITP open transaction orientation, we save one round trip time delay before the client can sent its first transaction request. Another advantage of this method is that the server can use a very narrow timeout window for the arrival of the DITP connection setup request. This protects against some type of DOS attacks. <br /><br />There are two additional things we can observe from the previous figure. <br /><br />1.- The HTTP or SMTP protocol could be optimized by allowing the client to send its first data without having to wait for the server greeting. <br /><br />2.- The round trip time due to TCP could be avoided if we could combine it with the DITP connection set up and the two first requests. There is clearly room for improvement on this layer, but this is out of scope regarding this project. <br /></p>]]></content:encoded></item><item><title><![CDATA["8 Reasons why XML sucks"]]></title><link><![CDATA[http://www.disnetwork.info/1/post/2008/07/8-reasons-why-xml-sucks.html]]></link><comments><![CDATA[http://www.disnetwork.info/1/post/2008/07/8-reasons-why-xml-sucks.html#comments]]></comments><pubDate>Tue, 15 Jul 2008 14:26:37 +0700</pubDate><category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://www.disnetwork.info/1/post/2008/07/8-reasons-why-xml-sucks.html</guid><description><![CDATA[The choice to make IDR a binary data representation was not easy to make because it is not in the current trend. The following very interesting article comfort me in my choice "8 Reasons why XML sucks". [...] ]]></description><content:encoded><![CDATA[<p  style=" text-align: left; ">The choice to make IDR a binary data representation was not easy to make because it is not in the current trend. The following very interesting article comfort me in my choice <a href="http://firstclassthoughts.co.uk/xml/why_xml_sucks.html">"8 Reasons why XML sucks"</a>.</p>]]></content:encoded></item><item><title><![CDATA[Time value encoding in DIS ]]></title><link><![CDATA[http://www.disnetwork.info/1/post/2008/05/time-value-encoding-in-dis.html]]></link><comments><![CDATA[http://www.disnetwork.info/1/post/2008/05/time-value-encoding-in-dis.html#comments]]></comments><pubDate>Mon, 26 May 2008 05:51:19 +0700</pubDate><category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://www.disnetwork.info/1/post/2008/05/time-value-encoding-in-dis.html</guid><description><![CDATA[One fundamental question is the encoding of a time value. A time value has two types of use. One is as time stamp and the other is just as a general time reference.RequirementsOn one hand, a time stamp has the requirement to have a well defined and controlled precision, while the covered time span can be limited (i.e. +/- 200 years).&nbsp; On the other hand, a general time reference needs to be applic [...] ]]></description><content:encoded><![CDATA[<p  style=" text-align: left; ">One fundamental question is the encoding of a time value. A time value has two types of use. One is as time stamp and the other is just as a general time reference.<br /><br /><span style="font-weight: bold;">Requirements</span><br /><br />On one hand, a time stamp has the requirement to have a well defined and controlled precision, while the covered time span can be limited (i.e. +/- 200 years).&nbsp; On the other hand, a general time reference needs to be applicable to a very large time span, with less constrains on the precision limit. <br /><br /><span style="font-weight: bold;">Options<br /><br /></span>For the time reference value one could use a  double precision float representation with seconds as units. All arithmetic operations are provided right out of the box and generally hardwired in the processor. Conversion to calendar time is trivial since one simply has to extract the integer part of the value and convert it to a time_t value. From there one can use the common calendar time conversion and formatting functions.<br /><br />For time stamps, using integers seems preferable. But we still have a choice between a split encoding like the <span style="font-style: italic;">timeval</span> structure, a 64bit fixed point encoding, or an integer with very small time unit (i.e. nanoseconds). <br /><br /><span style="font-weight: bold;">Discussion<br /> </span><br />There is not much to discuss about the absolute time. Using a double precision float is an optimal solution. For time stamps however we have three different solutions. <br /><br />From my experience, I've seen that split time encoding like the <span style="font-style: italic;">timeval</span> structure is not convenient to use when dealing with time arithmetics. It is even error prone if the user has to program the operations himself.<br /><br />I also tried to implement a fixed point time encoding class with the decimal point between bit 29 and 30. But this is tricky to get right and some operations are not trivial to implement correctly. This is because fractional computation requires normalization and optimal rounding errors handling. <br /><br />A 64bit&nbsp; integer using&nbsp; nanoseconds as time units is apparently the most simple and straightforward time stamp encoding. Converting to seconds is done with a simple 64bit integer division which is also hardwired in most recent processors. Conversion to other time units like microseconds, milliseconds, days or week is as accurate and simple. Multiplication or division with decimal scalar values is also trivial. <br /><br />Another advantage of the 64bit integer nanosecond values is that there is no need of special functions to do the conversions or operations. A programmer can easily figure out what to do and use conventional arithmetic operations.<br /><br />With a 64 bit signed integers with nanosecond units, the covered time span is over +/- 292 years range. One can thus afford keep the current time_t January 1970 epoch and push back the wrapping limit far away.&nbsp;<br /><br /><span style="font-weight: bold;">Conclusion </span><br /><br />In DIS, we'll thus use a double precision float for general time reference value and a 64bit integer with nanosecond units for time stamps and delays encoding. <br /><br /><span style="font-style: italic;">Note</span>: I've seen the use of a double precision float for time encoding in some Windows operating system API. I still have to see the use of a 64bit signed integer with nanosecond units. It would make sense as an upgrade of time_t which is required since we are getting close to the wrapping limit.<span style="font-weight: bold; font-style: italic;">Update </span><span style="font-weight: bold;">:</span> It has been brought to my attention that Java stores time values in a signed 64bit integer with milliseconds as time units relative to  January 1, 1970. The covered time span is thus +/- 290 million years. I'll stay with the nanosecond units for time stamps. <br /> </p>]]></content:encoded></item></channel></rss>
