<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:georss="http://www.georss.org/georss" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" version="2.0">
  <channel>
    <title>Nesterovsky bros - Thinking aloud</title>
    <link>http://www.nesterovsky-bros.com/weblog/</link>
    <description />
    <language>en-us</language>
    <copyright>Nesterovsky bros</copyright>
    <lastBuildDate>Fri, 26 Jan 2024 13:27:16 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.3.12105.0</generator>
    <managingEditor>contact@nesterovsky-bros.com</managingEditor>
    <webMaster>contact@nesterovsky-bros.com</webMaster>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=371a8329-d392-4d20-bcbc-db9503816f26</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,371a8329-d392-4d20-bcbc-db9503816f26.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=371a8329-d392-4d20-bcbc-db9503816f26</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <h4>Introduction
</h4>
        <p>
We migrate code out of MF to Azure. Tool we use produces plain good functionally equivalent
C# code. But it turns it's not enough!
</p>
        <p>
So, what's the problem?
</p>
        <p>
Converted code is very slow, especially for batch processing, where MF completes job,
say in 30 minutes, while converted code finishes in 8 hours.
</p>
        <p>
At this point usually someone appears and whispers in the ear:
</p>
        <blockquote>
          <p>
Look, those old technologies are proven by the time. It worth to stick to old good
Cobol, or better to Assembler if you want to do the real thing.
</p>
        </blockquote>
        <p>
We're curious though: why is there a difference?
</p>
        <p>
Turns out the issue lies in differences of network topology between MF and Azure solutions.
On MF all programs, database and file storage virtually sit in a single box, thus
network latency is negligible. 
</p>
        <p>
It's rather usual to see chatty SQL programs on MF that are doing a lot of small
SQL queries.
</p>
        <p>
In Azure - programs, database, file storage are different services most certainly
sitting in different phisical boxes. You should be thankfull if they are co-located
in a single datacenter. So, network latency immediately becomes a factor. Even if
it just adds 1 millisecond per SQL roundtrip, it adds up in loops, and turns in the
showstopper.
</p>
        <p>
There is no easy workaround on the hardware level.
</p>
        <p>
People advice to write programs differently: "<a href="https://learn.microsoft.com/en-us/azure/azure-sql/database/performance-guidance">Tune
applications and databases for performance in Azure SQL Database</a>".
</p>
        <p>
That's a good advice for a new development but discouraging for migration done
by a tool.
</p>
        <p>
So, what is the way forward?
</p>
        <p>
Well, there is one. While accepting weak sides of Azure we can exploit its strong
sides.
</p>
        <h4>Parallel refactoring
</h4>
        <p>
Before continuing let's consider a <a href="https://github.com/nesterovsky-bros/parallel-refactoring/tree/master/Services/SerialProcessor.cs#L5-L29">code</a> demoing
the problem:
</p>
        <pre>
          <code class="lang-C#">
            <span class="hljs-keyword">public</span>
            <span class="hljs-literal">void</span> CreateReport(StringWriter
writer) { <span class="hljs-built_in">var</span> index = <span class="hljs-number">0</span>;
foreach(<span class="hljs-built_in">var</span> transaction <span class="hljs-keyword">in</span> dataService.
GetTransactions(). OrderBy(item =&gt; (item.At, item.SourceAccountId))) { <span class="hljs-built_in">var</span> sourceAccount
= dataService.GetAccount(transaction.SourceAccountId); <span class="hljs-built_in">var</span> targetAccount
= transaction.TargetAccountId != <span class="hljs-built_in">null</span> ? dataService.GetAccount(transaction.TargetAccountId)
: <span class="hljs-built_in">null</span>; ++index; <span class="hljs-keyword">if</span> (index
% <span class="hljs-number">100</span> == <span class="hljs-number">0</span>) { Console.WriteLine(index);
} writer.WriteLine($<span class="hljs-string">"{index},{transaction.Id},{ transaction.At},{transaction.Type},{transaction.Amount},{
transaction.SourceAccountId},{sourceAccount?.Name},{ transaction.TargetAccountId},{targetAccount?.Name}"</span>);
} } </code>
        </pre>
        <p>
This cycle queries transactions, along with two more small queries to get source and
target accounts for each transaction. Results are printed into a report.
</p>
        <p>
If we assume query latency just 1 millisecond, and try to run such code for 100K transactions
we easily come to 200+ seconds of execution. 
</p>
        <p>
Reality turns to be much worse. Program spends most of its lifecycle waiting for database
results, and iterations don't advance until all work of previous iterations is
complete.
</p>
        <p>
We could do better even without trying to rewrite all code! Let's articulate our
goals:
</p>
        <ol>
          <li>
To make code fast.</li>
          <li>
To leave code recognizable.</li>
        </ol>
        <p>
The idea is to form two processing pipelines:
</p>
        <ul>
          <li>
(a) one that processes data in parallel out of order;</li>
          <li>
(b) other that processes data serially, in original order;</li>
        </ul>
        <p>
Each pipeline may post sub-tasks to the other, so (a) runs its tasks in parallel unordered,
while (b) runs its tasks as if everything was running serially.
</p>
        <p>
So, parallel plan would be like this:
</p>
        <ol>
          <li>
Queue parallel sub-tasks (a) for each transaction.</li>
          <li>
Parallel sub-task in (a) reads source and target accounts, and queues serial sub-task
(b) passing transaction and accounts.</li>
          <li>
Serial sub-task (b) increments index, and writes report record.</li>
          <li>
Wait for all tasks to complete.</li>
        </ol>
        <p>
To reduce burden of task piplelines we use <a href="https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/dataflow-task-parallel-library">Dataflow
(Task Parallel Library)</a>, and encapsulate everything in a small wrapper.
</p>
        <p>
Consider refactored <a href="https://github.com/nesterovsky-bros/parallel-refactoring/tree/master/Services/ParallelProcessor.cs#L14-L48">code</a>:
</p>
        <pre>
          <code class="lang-C#">
            <span class="hljs-keyword">public</span>
            <span class="hljs-literal">void</span> CreateReport(StringWriter
writer) { using <span class="hljs-built_in">var</span> parallel = <span class="hljs-literal">new</span> Parallel(options.Value.Parallelism); <span class="hljs-comment">//
⬅️ 1</span><span class="hljs-built_in">var</span> index = <span class="hljs-number">0</span>;
parallel.ForEachAsync( <span class="hljs-comment">// ⬅️ 2</span> dataService. GetTransactions().
OrderBy(item =&gt; (item.At, item.SourceAccountId)), transaction =&gt; <span class="hljs-comment">//
⬅️ 3</span> { <span class="hljs-built_in">var</span> sourceAccount = dataService.GetAccount(transaction.SourceAccountId); <span class="hljs-built_in">var</span> targetAccount
= transaction.TargetAccountId != <span class="hljs-built_in">null</span> ? dataService.GetAccount(transaction.TargetAccountId)
: <span class="hljs-built_in">null</span>; parallel.PostSync( <span class="hljs-comment">//
⬅️ 4</span> (transaction, sourceAccount, targetAccount), <span class="hljs-comment">//
⬅️ 5</span><span class="hljs-built_in">data</span> =&gt; { <span class="hljs-built_in">var</span> (transaction,
sourceAccount, targetAccount) = <span class="hljs-built_in">data</span>; <span class="hljs-comment">//
⬅️ 6</span> ++index; <span class="hljs-keyword">if</span> (index % <span class="hljs-number">100</span> == <span class="hljs-number">0</span>)
{ Console.WriteLine(index); } writer.WriteLine($<span class="hljs-string">"{index},{transaction.Id},{
transaction.At},{transaction.Type},{transaction.Amount},{ transaction.SourceAccountId},{sourceAccount?.Name},{
transaction.TargetAccountId},{targetAccount?.Name}"</span>); }); }); } </code>
        </pre>
        <p>
Consider ⬅️ points:
</p>
        <ol>
          <li>
We create <code>Parallel</code> utility class passing degree of parallelism requested.</li>
          <li>
We iterate transactions using <code>parallel.ForEachAsync()</code> that queues parallel
sub-tasks for each transaction, and then waits until all tasks are complete.</li>
          <li>
Each parallel sub-task recieves a transaction. It may be called from a different thread.</li>
          <li>
Having recieved required accounts we queue a sub-task for synchronous execution using <code>parallel.PostSync()</code>,
and</li>
          <li>
Pass there data collected in parallel sub-task: transaction and accounts.</li>
          <li>
We deconstruct data passed into variables, and then proceed with serial logic.</li>
        </ol>
        <p>
What we achieve with this refactoring:
</p>
        <ol>
          <li>
Top level query that brings transactions is done and iterated serially.</li>
          <li>
But each iteration body is run in parallel. By default we set it up to allow up to
100 parallel executions. All those parallel sub-task do not wait on each other so
their waitings do not add up.</li>
          <li>
Sync sub-tasks are queued and executed in order of their serial appearance, so increments
and report records are not a subject of race conditions, nor a subject of reordering
of output records.</li>
        </ol>
        <p>
We think that such refactored code is still recognizible.
</p>
        <p>
As for performance this is what log shows:
</p>
        <pre>
          <code class="lang-log">
            <span class="hljs-selector-tag">Serial</span>
            <span class="hljs-selector-tag">test</span> 100
... <span class="hljs-selector-tag">Execution</span><span class="hljs-selector-tag">time</span>:
00<span class="hljs-selector-pseudo">:01</span><span class="hljs-selector-pseudo">:33.8152540</span><span class="hljs-selector-tag">Parallel</span><span class="hljs-selector-tag">test</span> 100
... <span class="hljs-selector-tag">Execution</span><span class="hljs-selector-tag">time</span>:
00<span class="hljs-selector-pseudo">:00</span><span class="hljs-selector-pseudo">:05.8705468</span></code>
        </pre>
        <h4>Reference
</h4>
        <p>
Please take a look at project to understand implementation details, and in particular <a href="https://github.com/nesterovsky-bros/parallel-refactoring/tree/master/Services/Parallel.cs"><code>Parallel</code></a> class
implementing API to post parallel and serial tasks, run cycles and some more.
</p>
        <p>
Please continue reading on <a href="https://github.com/nesterovsky-bros/parallel-refactoring/tree/master?tab=readme-ov-file#parallel-refactoring">GitHub</a>.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=371a8329-d392-4d20-bcbc-db9503816f26" />
      </body>
      <title>Experience of parallel refactoring</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,371a8329-d392-4d20-bcbc-db9503816f26.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2024/01/26/ExperienceOfParallelRefactoring.aspx</link>
      <pubDate>Fri, 26 Jan 2024 13:27:16 GMT</pubDate>
      <description>&lt;h4&gt;Introduction
&lt;/h4&gt;
&lt;p&gt;
We migrate code out of MF to Azure. Tool we use produces plain good functionally equivalent
C# code. But it turns it&amp;#39;s not enough!
&lt;/p&gt;
&lt;p&gt;
So, what&amp;#39;s the problem?
&lt;/p&gt;
&lt;p&gt;
Converted code is very slow, especially for batch processing, where MF completes job,
say in 30 minutes, while converted code finishes in 8 hours.
&lt;/p&gt;
&lt;p&gt;
At this point usually someone appears and whispers in the ear:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
Look, those old technologies are proven by the time. It worth to stick to old good
Cobol, or better to Assembler if you want to do the real thing.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
We&amp;#39;re curious though: why is there a difference?
&lt;/p&gt;
&lt;p&gt;
Turns out the issue lies in differences of network topology between MF and Azure solutions.
On MF all programs, database and file storage virtually sit in a single box, thus
network latency is negligible. 
&lt;/p&gt;
&lt;p&gt;
It&amp;#39;s rather usual to see chatty SQL programs on MF that are doing a lot of small
SQL queries.
&lt;/p&gt;
&lt;p&gt;
In Azure - programs, database, file storage are different services most certainly
sitting in different phisical boxes. You should be thankfull if they are co-located
in a single datacenter. So, network latency immediately becomes a factor. Even if
it just adds 1 millisecond per SQL roundtrip, it adds up in loops, and turns in the
showstopper.
&lt;/p&gt;
&lt;p&gt;
There is no easy workaround on the hardware level.
&lt;/p&gt;
&lt;p&gt;
People advice to write programs differently: &amp;quot;&lt;a href="https://learn.microsoft.com/en-us/azure/azure-sql/database/performance-guidance"&gt;Tune
applications and databases for performance in Azure SQL Database&lt;/a&gt;&amp;quot;.
&lt;/p&gt;
&lt;p&gt;
That&amp;#39;s a good advice for a new development but discouraging for migration done
by a tool.
&lt;/p&gt;
&lt;p&gt;
So, what is the way forward?
&lt;/p&gt;
&lt;p&gt;
Well, there is one. While accepting weak sides of Azure we can exploit its strong
sides.
&lt;/p&gt;
&lt;h4&gt;Parallel refactoring
&lt;/h4&gt;
&lt;p&gt;
Before continuing let&amp;#39;s consider a &lt;a href="https://github.com/nesterovsky-bros/parallel-refactoring/tree/master/Services/SerialProcessor.cs#L5-L29"&gt;code&lt;/a&gt; demoing
the problem:
&lt;/p&gt;
&lt;pre&gt;&lt;code class="lang-C#"&gt; &lt;span class="hljs-keyword"&gt;public&lt;/span&gt; &lt;span class="hljs-literal"&gt;void&lt;/span&gt; CreateReport(StringWriter
writer) { &lt;span class="hljs-built_in"&gt;var&lt;/span&gt; index = &lt;span class="hljs-number"&gt;0&lt;/span&gt;;
foreach(&lt;span class="hljs-built_in"&gt;var&lt;/span&gt; transaction &lt;span class="hljs-keyword"&gt;in&lt;/span&gt; dataService.
GetTransactions(). OrderBy(item =&amp;gt; (item.At, item.SourceAccountId))) { &lt;span class="hljs-built_in"&gt;var&lt;/span&gt; sourceAccount
= dataService.GetAccount(transaction.SourceAccountId); &lt;span class="hljs-built_in"&gt;var&lt;/span&gt; targetAccount
= transaction.TargetAccountId != &lt;span class="hljs-built_in"&gt;null&lt;/span&gt; ? dataService.GetAccount(transaction.TargetAccountId)
: &lt;span class="hljs-built_in"&gt;null&lt;/span&gt;; ++index; &lt;span class="hljs-keyword"&gt;if&lt;/span&gt; (index
% &lt;span class="hljs-number"&gt;100&lt;/span&gt; == &lt;span class="hljs-number"&gt;0&lt;/span&gt;) { Console.WriteLine(index);
} writer.WriteLine($&lt;span class="hljs-string"&gt;"{index},{transaction.Id},{ transaction.At},{transaction.Type},{transaction.Amount},{
transaction.SourceAccountId},{sourceAccount?.Name},{ transaction.TargetAccountId},{targetAccount?.Name}"&lt;/span&gt;);
} } &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
This cycle queries transactions, along with two more small queries to get source and
target accounts for each transaction. Results are printed into a report.
&lt;/p&gt;
&lt;p&gt;
If we assume query latency just 1 millisecond, and try to run such code for 100K transactions
we easily come to 200+ seconds of execution. 
&lt;/p&gt;
&lt;p&gt;
Reality turns to be much worse. Program spends most of its lifecycle waiting for database
results, and iterations don&amp;#39;t advance until all work of previous iterations is
complete.
&lt;/p&gt;
&lt;p&gt;
We could do better even without trying to rewrite all code! Let&amp;#39;s articulate our
goals:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
To make code fast.&lt;/li&gt;
&lt;li&gt;
To leave code recognizable.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
The idea is to form two processing pipelines:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
(a) one that processes data in parallel out of order;&lt;/li&gt;
&lt;li&gt;
(b) other that processes data serially, in original order;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Each pipeline may post sub-tasks to the other, so (a) runs its tasks in parallel unordered,
while (b) runs its tasks as if everything was running serially.
&lt;/p&gt;
&lt;p&gt;
So, parallel plan would be like this:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Queue parallel sub-tasks (a) for each transaction.&lt;/li&gt;
&lt;li&gt;
Parallel sub-task in (a) reads source and target accounts, and queues serial sub-task
(b) passing transaction and accounts.&lt;/li&gt;
&lt;li&gt;
Serial sub-task (b) increments index, and writes report record.&lt;/li&gt;
&lt;li&gt;
Wait for all tasks to complete.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
To reduce burden of task piplelines we use &lt;a href="https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/dataflow-task-parallel-library"&gt;Dataflow
(Task Parallel Library)&lt;/a&gt;, and encapsulate everything in a small wrapper.
&lt;/p&gt;
&lt;p&gt;
Consider refactored &lt;a href="https://github.com/nesterovsky-bros/parallel-refactoring/tree/master/Services/ParallelProcessor.cs#L14-L48"&gt;code&lt;/a&gt;:
&lt;/p&gt;
&lt;pre&gt;&lt;code class="lang-C#"&gt; &lt;span class="hljs-keyword"&gt;public&lt;/span&gt; &lt;span class="hljs-literal"&gt;void&lt;/span&gt; CreateReport(StringWriter
writer) { using &lt;span class="hljs-built_in"&gt;var&lt;/span&gt; parallel = &lt;span class="hljs-literal"&gt;new&lt;/span&gt; Parallel(options.Value.Parallelism); &lt;span class="hljs-comment"&gt;//
⬅️ 1&lt;/span&gt; &lt;span class="hljs-built_in"&gt;var&lt;/span&gt; index = &lt;span class="hljs-number"&gt;0&lt;/span&gt;;
parallel.ForEachAsync( &lt;span class="hljs-comment"&gt;// ⬅️ 2&lt;/span&gt; dataService. GetTransactions().
OrderBy(item =&amp;gt; (item.At, item.SourceAccountId)), transaction =&amp;gt; &lt;span class="hljs-comment"&gt;//
⬅️ 3&lt;/span&gt; { &lt;span class="hljs-built_in"&gt;var&lt;/span&gt; sourceAccount = dataService.GetAccount(transaction.SourceAccountId); &lt;span class="hljs-built_in"&gt;var&lt;/span&gt; targetAccount
= transaction.TargetAccountId != &lt;span class="hljs-built_in"&gt;null&lt;/span&gt; ? dataService.GetAccount(transaction.TargetAccountId)
: &lt;span class="hljs-built_in"&gt;null&lt;/span&gt;; parallel.PostSync( &lt;span class="hljs-comment"&gt;//
⬅️ 4&lt;/span&gt; (transaction, sourceAccount, targetAccount), &lt;span class="hljs-comment"&gt;//
⬅️ 5&lt;/span&gt; &lt;span class="hljs-built_in"&gt;data&lt;/span&gt; =&amp;gt; { &lt;span class="hljs-built_in"&gt;var&lt;/span&gt; (transaction,
sourceAccount, targetAccount) = &lt;span class="hljs-built_in"&gt;data&lt;/span&gt;; &lt;span class="hljs-comment"&gt;//
⬅️ 6&lt;/span&gt; ++index; &lt;span class="hljs-keyword"&gt;if&lt;/span&gt; (index % &lt;span class="hljs-number"&gt;100&lt;/span&gt; == &lt;span class="hljs-number"&gt;0&lt;/span&gt;)
{ Console.WriteLine(index); } writer.WriteLine($&lt;span class="hljs-string"&gt;"{index},{transaction.Id},{
transaction.At},{transaction.Type},{transaction.Amount},{ transaction.SourceAccountId},{sourceAccount?.Name},{
transaction.TargetAccountId},{targetAccount?.Name}"&lt;/span&gt;); }); }); } &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
Consider ⬅️ points:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
We create &lt;code&gt;Parallel&lt;/code&gt; utility class passing degree of parallelism requested.&lt;/li&gt;
&lt;li&gt;
We iterate transactions using &lt;code&gt;parallel.ForEachAsync()&lt;/code&gt; that queues parallel
sub-tasks for each transaction, and then waits until all tasks are complete.&lt;/li&gt;
&lt;li&gt;
Each parallel sub-task recieves a transaction. It may be called from a different thread.&lt;/li&gt;
&lt;li&gt;
Having recieved required accounts we queue a sub-task for synchronous execution using &lt;code&gt;parallel.PostSync()&lt;/code&gt;,
and&lt;/li&gt;
&lt;li&gt;
Pass there data collected in parallel sub-task: transaction and accounts.&lt;/li&gt;
&lt;li&gt;
We deconstruct data passed into variables, and then proceed with serial logic.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
What we achieve with this refactoring:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Top level query that brings transactions is done and iterated serially.&lt;/li&gt;
&lt;li&gt;
But each iteration body is run in parallel. By default we set it up to allow up to
100 parallel executions. All those parallel sub-task do not wait on each other so
their waitings do not add up.&lt;/li&gt;
&lt;li&gt;
Sync sub-tasks are queued and executed in order of their serial appearance, so increments
and report records are not a subject of race conditions, nor a subject of reordering
of output records.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
We think that such refactored code is still recognizible.
&lt;/p&gt;
&lt;p&gt;
As for performance this is what log shows:
&lt;/p&gt;
&lt;pre&gt;&lt;code class="lang-log"&gt;&lt;span class="hljs-selector-tag"&gt;Serial&lt;/span&gt; &lt;span class="hljs-selector-tag"&gt;test&lt;/span&gt; 100
... &lt;span class="hljs-selector-tag"&gt;Execution&lt;/span&gt; &lt;span class="hljs-selector-tag"&gt;time&lt;/span&gt;:
00&lt;span class="hljs-selector-pseudo"&gt;:01&lt;/span&gt;&lt;span class="hljs-selector-pseudo"&gt;:33.8152540&lt;/span&gt; &lt;span class="hljs-selector-tag"&gt;Parallel&lt;/span&gt; &lt;span class="hljs-selector-tag"&gt;test&lt;/span&gt; 100
... &lt;span class="hljs-selector-tag"&gt;Execution&lt;/span&gt; &lt;span class="hljs-selector-tag"&gt;time&lt;/span&gt;:
00&lt;span class="hljs-selector-pseudo"&gt;:00&lt;/span&gt;&lt;span class="hljs-selector-pseudo"&gt;:05.8705468&lt;/span&gt; &lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Reference
&lt;/h4&gt;
&lt;p&gt;
Please take a look at project to understand implementation details, and in particular &lt;a href="https://github.com/nesterovsky-bros/parallel-refactoring/tree/master/Services/Parallel.cs"&gt;&lt;code&gt;Parallel&lt;/code&gt;&lt;/a&gt; class
implementing API to post parallel and serial tasks, run cycles and some more.
&lt;/p&gt;
&lt;p&gt;
Please continue reading on &lt;a href="https://github.com/nesterovsky-bros/parallel-refactoring/tree/master?tab=readme-ov-file#parallel-refactoring"&gt;GitHub&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=371a8329-d392-4d20-bcbc-db9503816f26" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,371a8329-d392-4d20-bcbc-db9503816f26.aspx</comments>
      <category>.NET</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=0977bf46-abc6-41fe-9767-de673ef5de8b</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,0977bf46-abc6-41fe-9767-de673ef5de8b.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=0977bf46-abc6-41fe-9767-de673ef5de8b</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
As we wrote some time ago, we started to use AI and ML APIs in our applications, but
this time we've tried to use Bing chat as a tool.
</p>
        <p>
The initial task was to collect sequences of integer numbers and return a list of
pairs integers where the first number is a range's start and the second one is a count
of values in the range. For example, for sequence 1, 2, 3, 5, 8, 9 we'd like to get
the following results: 1, 3 5, 1 8, 2 
</p>
        <p>
We both started to solve this issue. My brother started to play with SSMS using his
deep knowledges in SQL and analytic functions, whereas me started to play with Bing
chat. Looking ahead, I can state that we both solved the issue using almost the same
SQL statement almost in the same time.
</p>
        <p>
Here are my prompts and Bing's answers:
</p>
        <dl>
          <dt style="font-weight: bold;">Prompt:</dt>
          <dd>
Act as database analyst and software engineer. Given the table (T) with a numeric
field (N), which values are orderd ranges of integers. In a range each next value
is greater than previous one on 1. When value differs from the previous one more than
on 1 then in belongs to another range. Generate select statement that returns rows
with two fields. The first field (R) is a number from which a range starts and the
second field (C) is count elements of that range: 
</dd>
          <dt style="font-weight: bold;">Answer:</dt>
          <dd style="white-space: normal;">
Sure, I can help with that. Here's a SQL query that should do the trick. This query
uses a self-join to identify the start of each range, and then groups by the start
of the range to count the number of elements. <code style="white-space: pre; margin: 1em; font-family: monospace;"> ```sql
SELECT start_of_range AS R, COUNT(*) AS C FROM ( SELECT N, N - ROW_NUMBER() OVER (ORDER
BY N) AS start_of_range FROM T ) subquery GROUP BY start_of_range ORDER BY start_of_range;
``` </code> In this query, `start_of_range` is calculated as the difference between
the current value of `N` and its row number (when ordered by `N`). This difference
will be the same for all `N` in the same range. Then we group by `start_of_range`
to get the count of elements in each range. The outer query selects the start of each
range (`R`) and the count of elements in that range (`C`). 
</dd>
          <dt style="padding: 1em; font-weight: 400;"> Me, scratching the head, hmmm... </dt>
          <dt style="font-weight: bold;"> Question: </dt>
          <dd style="white-space: pre;">
This is a bit incorrect SQL select. For example for values 1, 2, 3, 5, 8, 9 I'd like
to get the following results: 1, 3 5, 1 8, 2 What a SQL select shall I use to get
such results? 
</dd>
          <dt style="font-weight: bold;">Answer:</dt>
          <dd>
I apologize for the confusion earlier. You're right, the previous query doesn't handle
the scenario you've described correctly. Here's a corrected SQL query that should
give you the desired output. This query uses a window function to compare each row
with the previous one and identify the start of a new range. Then it groups by the
start of the range to count the elements. <code style="white-space: pre;font-family: monospace;"> ```sql
WITH ranges AS ( SELECT N, CASE WHEN N - LAG(N, 1, N) OVER (ORDER BY N) &gt; 1 THEN 1
ELSE 0 END AS is_start_of_range FROM T ), range_groups AS ( SELECT N, SUM(is_start_of_range)
OVER (ORDER BY N) AS range_group FROM ranges ) SELECT MIN(N) AS R, COUNT(*) AS C FROM
range_groups GROUP BY range_group ORDER BY R; ``` </code> In this query, `is_start_of_range`
is a flag that indicates the start of a new range (when the difference between the
current and previous `N` is more than 1). `range_group` is a running total of `is_start_of_range`
that serves as a unique identifier for each range. The outer query then groups by
`range_group` to get the start (`R`) and count (`C`) of each range. I hope this helps!
Let me know if you have any other questions. 
</dd>
        </dl>
        <p>
That answer more satisfied me, and I've checked the following example:
</p>
        <code style="white-space: pre; font-family: monospace;"> with T as ( select 10 N union
all select 11 N union all select 30 N union all select 31 N union all select 32 N
union all select 50 N union all select 80 N union all select 81 N union all select
82 N union all select 83 N union all select 90 N ), ranges AS ( SELECT N, CASE WHEN
N - LAG(N, 1, N) OVER (ORDER BY N) &gt; 1 THEN 1 ELSE 0 END AS is_start_of_range FROM
T ), range_groups AS ( SELECT N, SUM(is_start_of_range) OVER (ORDER BY N) AS range_group
FROM ranges ) SELECT MIN(N) AS R, COUNT(*) AS C FROM range_groups GROUP BY range_group
ORDER BY R; </code>
        <p>
The result was:
</p>
        <code style="white-space: pre; font-family: monospace;"> R C ------------ 10 2 30
3 50 1 80 4 90 1 </code>
        <p>
          <b>Conclusion:</b>
          <br />
Nowdays, using AI as a tool, you may improve your performance to the expert level
and, may be, study something new... 
</p>
        <p>
          <b>P.S.</b> Don't fool youself that AI can replace a developer (see the first answer
of the chat), but together they can be much stornger than separatelly. 
</p>
        <p>
          <b>P.P.S.</b> Another interesting solution gave us our colleague. She used an additional
field to avoid using analytics function, and she reached the same result: 
</p>
        <code style="white-space: pre; font-family: monospace;"> with T as ( select 10 ID,
1 N union all select 11 ID, 1 N union all select 30 ID, 1 N union all select 31 ID,
1 N union all select 32 ID, 1 N union all select 50 ID, 1 N union all select 80 ID,
1 N union all select 81 ID, 1 N union all select 82 ID, 1 N union all select 83 ID,
1 N union all select 90 ID, 1 N ), Groups AS ( SELECT ID, N, ROW_NUMBER() OVER (ORDER
BY ID) - ID AS GroupNumber FROM T ) SELECT MIN(ID) AS R, SUM(N) AS C FROM Groups GROUP
BY GroupNumber ORDER BY StartID; </code>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=0977bf46-abc6-41fe-9767-de673ef5de8b" />
      </body>
      <title>Using Bing chat as a tool.</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,0977bf46-abc6-41fe-9767-de673ef5de8b.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2024/01/01/UsingBingChatAsATool.aspx</link>
      <pubDate>Mon, 01 Jan 2024 14:02:01 GMT</pubDate>
      <description>    &lt;p&gt;
As we wrote some time ago, we started to use AI and ML APIs in our applications, but
this time we've tried to use Bing chat as a tool.
&lt;/p&gt;
&lt;p&gt;
The initial task was to collect sequences of integer numbers and return a list of
pairs integers where the first number is a range's start and the second one is a count
of values in the range. For example, for sequence 1, 2, 3, 5, 8, 9 we'd like to get
the following results: 1, 3 5, 1 8, 2 
&lt;/p&gt;
&lt;p&gt;
We both started to solve this issue. My brother started to play with SSMS using his
deep knowledges in SQL and analytic functions, whereas me started to play with Bing
chat. Looking ahead, I can state that we both solved the issue using almost the same
SQL statement almost in the same time.
&lt;/p&gt;
&lt;p&gt;
Here are my prompts and Bing's answers:
&lt;/p&gt;
&lt;dl&gt;
&lt;dt style="font-weight: bold;"&gt;Prompt:&lt;/dt&gt; 
&lt;dd&gt;
Act as database analyst and software engineer. Given the table (T) with a numeric
field (N), which values are orderd ranges of integers. In a range each next value
is greater than previous one on 1. When value differs from the previous one more than
on 1 then in belongs to another range. Generate select statement that returns rows
with two fields. The first field (R) is a number from which a range starts and the
second field (C) is count elements of that range: 
&lt;/dd&gt;
&lt;dt style="font-weight: bold;"&gt;Answer:&lt;/dt&gt; 
&lt;dd style="white-space: normal;"&gt;
Sure, I can help with that. Here's a SQL query that should do the trick. This query
uses a self-join to identify the start of each range, and then groups by the start
of the range to count the number of elements. &lt;code style="white-space: pre; margin: 1em; font-family: monospace;"&gt; ```sql
SELECT start_of_range AS R, COUNT(*) AS C FROM ( SELECT N, N - ROW_NUMBER() OVER (ORDER
BY N) AS start_of_range FROM T ) subquery GROUP BY start_of_range ORDER BY start_of_range;
``` &lt;/code&gt; In this query, `start_of_range` is calculated as the difference between
the current value of `N` and its row number (when ordered by `N`). This difference
will be the same for all `N` in the same range. Then we group by `start_of_range`
to get the count of elements in each range. The outer query selects the start of each
range (`R`) and the count of elements in that range (`C`). 
&lt;/dd&gt;
&lt;dt style="padding: 1em; font-weight: 400;"&gt; Me, scratching the head, hmmm... &lt;/dt&gt; &lt;dt style="font-weight: bold;"&gt; Question: &lt;/dt&gt; 
&lt;dd style="white-space: pre;"&gt;
This is a bit incorrect SQL select. For example for values 1, 2, 3, 5, 8, 9 I'd like
to get the following results: 1, 3 5, 1 8, 2 What a SQL select shall I use to get
such results? 
&lt;/dd&gt;
&lt;dt style="font-weight: bold;"&gt;Answer:&lt;/dt&gt; 
&lt;dd&gt;
I apologize for the confusion earlier. You're right, the previous query doesn't handle
the scenario you've described correctly. Here's a corrected SQL query that should
give you the desired output. This query uses a window function to compare each row
with the previous one and identify the start of a new range. Then it groups by the
start of the range to count the elements. &lt;code style="white-space: pre;font-family: monospace;"&gt; ```sql
WITH ranges AS ( SELECT N, CASE WHEN N - LAG(N, 1, N) OVER (ORDER BY N) &gt; 1 THEN 1
ELSE 0 END AS is_start_of_range FROM T ), range_groups AS ( SELECT N, SUM(is_start_of_range)
OVER (ORDER BY N) AS range_group FROM ranges ) SELECT MIN(N) AS R, COUNT(*) AS C FROM
range_groups GROUP BY range_group ORDER BY R; ``` &lt;/code&gt; In this query, `is_start_of_range`
is a flag that indicates the start of a new range (when the difference between the
current and previous `N` is more than 1). `range_group` is a running total of `is_start_of_range`
that serves as a unique identifier for each range. The outer query then groups by
`range_group` to get the start (`R`) and count (`C`) of each range. I hope this helps!
Let me know if you have any other questions. 
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;
That answer more satisfied me, and I've checked the following example:
&lt;/p&gt;
&lt;code style="white-space: pre; font-family: monospace;"&gt; with T as ( select 10 N union
all select 11 N union all select 30 N union all select 31 N union all select 32 N
union all select 50 N union all select 80 N union all select 81 N union all select
82 N union all select 83 N union all select 90 N ), ranges AS ( SELECT N, CASE WHEN
N - LAG(N, 1, N) OVER (ORDER BY N) &gt; 1 THEN 1 ELSE 0 END AS is_start_of_range FROM
T ), range_groups AS ( SELECT N, SUM(is_start_of_range) OVER (ORDER BY N) AS range_group
FROM ranges ) SELECT MIN(N) AS R, COUNT(*) AS C FROM range_groups GROUP BY range_group
ORDER BY R; &lt;/code&gt; 
&lt;p&gt;
The result was:
&lt;/p&gt;
&lt;code style="white-space: pre; font-family: monospace;"&gt; R C ------------ 10 2 30
3 50 1 80 4 90 1 &lt;/code&gt; 
&lt;p&gt;
&lt;b&gt;Conclusion:&lt;/b&gt;
&lt;br /&gt;
Nowdays, using AI as a tool, you may improve your performance to the expert level
and, may be, study something new... 
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;P.S.&lt;/b&gt; Don't fool youself that AI can replace a developer (see the first answer
of the chat), but together they can be much stornger than separatelly. 
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;P.P.S.&lt;/b&gt; Another interesting solution gave us our colleague. She used an additional
field to avoid using analytics function, and she reached the same result: 
&lt;/p&gt;
&lt;code style="white-space: pre; font-family: monospace;"&gt; with T as ( select 10 ID,
1 N union all select 11 ID, 1 N union all select 30 ID, 1 N union all select 31 ID,
1 N union all select 32 ID, 1 N union all select 50 ID, 1 N union all select 80 ID,
1 N union all select 81 ID, 1 N union all select 82 ID, 1 N union all select 83 ID,
1 N union all select 90 ID, 1 N ), Groups AS ( SELECT ID, N, ROW_NUMBER() OVER (ORDER
BY ID) - ID AS GroupNumber FROM T ) SELECT MIN(ID) AS R, SUM(N) AS C FROM Groups GROUP
BY GroupNumber ORDER BY StartID; &lt;/code&gt;&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=0977bf46-abc6-41fe-9767-de673ef5de8b" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,0977bf46-abc6-41fe-9767-de673ef5de8b.aspx</comments>
      <category>AI</category>
      <category>SQL Server puzzle</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=591417c2-7649-4f5a-9355-0bd240853bd5</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,591417c2-7649-4f5a-9355-0bd240853bd5.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,591417c2-7649-4f5a-9355-0bd240853bd5.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=591417c2-7649-4f5a-9355-0bd240853bd5</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Many years ago we implemented <a href="/weblog/2015/12/16/AkinatorLikeEngine.aspx">Akinator
like engine</a> purely within SQL Server.
</p>
        <p>
Today we use exactly the same technique to implement vector database.
</p>
        <p>
Please see our GitHub repo: <a href="https://github.com/nesterovsky-bros/vector-database/tree/main">vector-database</a>.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=591417c2-7649-4f5a-9355-0bd240853bd5" />
      </body>
      <title>Vector database</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,591417c2-7649-4f5a-9355-0bd240853bd5.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2023/06/22/VectorDatabase.aspx</link>
      <pubDate>Thu, 22 Jun 2023 22:01:45 GMT</pubDate>
      <description>&lt;p&gt;
Many years ago we implemented &lt;a href="/weblog/2015/12/16/AkinatorLikeEngine.aspx"&gt;Akinator
like engine&lt;/a&gt; purely within SQL Server.
&lt;/p&gt;
&lt;p&gt;
Today we use exactly the same technique to implement vector database.
&lt;/p&gt;
&lt;p&gt;
Please see our GitHub repo: &lt;a href="https://github.com/nesterovsky-bros/vector-database/tree/main"&gt;vector-database&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=591417c2-7649-4f5a-9355-0bd240853bd5" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,591417c2-7649-4f5a-9355-0bd240853bd5.aspx</comments>
      <category>Announce</category>
      <category>SQL Server puzzle</category>
      <category>Thinking aloud</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=8f1b7b65-e15e-459f-82bb-0f50058805cd</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,8f1b7b65-e15e-459f-82bb-0f50058805cd.aspx</pingback:target>
      <dc:creator>Arthur Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=8f1b7b65-e15e-459f-82bb-0f50058805cd</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Last few days we play with OpenAI API and out of pure interest have asked about few
slogans for our team. As an input we fed info from "About us" page. And as one of
the first slogans we've gotten the following slogan that catgh our eyes: 
</p>
        <h3 style="padding-left: 3em;">
          <i>Excellence Through Experience: Nesterovsky Bros.</i>
        </h3>
        <p>
ChatGPT is not a bad copywriter at all... 
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=8f1b7b65-e15e-459f-82bb-0f50058805cd" />
      </body>
      <title>ChatGPT</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,8f1b7b65-e15e-459f-82bb-0f50058805cd.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2023/03/23/ChatGPT.aspx</link>
      <pubDate>Thu, 23 Mar 2023 11:30:03 GMT</pubDate>
      <description>&lt;p&gt;
Last few days we play with OpenAI API and out of pure interest have asked about few
slogans for our team. As an input we fed info from "About us" page. And as one of
the first slogans we've gotten the following slogan that catgh our eyes: 
&lt;/p&gt;
&lt;h3 style="padding-left: 3em;"&gt;&lt;i&gt;Excellence Through Experience: Nesterovsky Bros.&lt;/i&gt;
&lt;/h3&gt;
&lt;p&gt;
ChatGPT is not a bad copywriter at all... 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=8f1b7b65-e15e-459f-82bb-0f50058805cd" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,8f1b7b65-e15e-459f-82bb-0f50058805cd.aspx</comments>
      <category>Thinking aloud</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=fdbaf9f5-827b-4a1f-9e52-4ec569801784</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,fdbaf9f5-827b-4a1f-9e52-4ec569801784.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=fdbaf9f5-827b-4a1f-9e52-4ec569801784</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Xslt is oftentimes thought as a tool to take input xml, and run transformation to
get html or some xml on output. Our use case is more complex, and is closer to a data
mining of big data in batch. Our transformation pipelines often take hour or more
to run even with SSD disks and with CPU cores fully loaded with work.
</p>
        <p>
So, we're looking for performance opportunities, and xml vs json might be promising.
</p>
        <p>
Here are our hypotheses:
</p>
        <ul>
          <li>
json is lighter than xml to serialize and deserialize;</li>
          <li>
json stored as map(*), array(*) and other items() are ligher than node() at runtime,
in particular subtree copy is zero cost in json;</li>
          <li>
templates with match patterns are efficiently can be implemented with maps();</li>
          <li>
there is incremental way forward from use of xml to use of json.</li>
        </ul>
        <p>
If it pays off we might be switching xml format to json all over, even though it is
a development effort.
</p>
        <p>
But to proceed we need to commit an experiment to measure processing speed of xml
vs json in xslt.
</p>
        <p>
Now our task is to find an isolated small representative sample to prove or reject
our hypotheses. 
</p>
        <p>
Better to start off with some existing transformation, and change it from use of xml
to json. 
</p>
        <p>
The question is whether there is such a candidate.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=fdbaf9f5-827b-4a1f-9e52-4ec569801784" />
      </body>
      <title>xml vs json</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,fdbaf9f5-827b-4a1f-9e52-4ec569801784.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2022/04/16/xmlVsJson.aspx</link>
      <pubDate>Sat, 16 Apr 2022 19:03:04 GMT</pubDate>
      <description>&lt;p&gt;
Xslt is oftentimes thought as a tool to take input xml, and run transformation to
get html or some xml on output. Our use case is more complex, and is closer to a data
mining of big data in batch. Our transformation pipelines often take hour or more
to run even with SSD disks and with CPU cores fully loaded with work.
&lt;/p&gt;
&lt;p&gt;
So, we&amp;#39;re looking for performance opportunities, and xml vs json might be promising.
&lt;/p&gt;
&lt;p&gt;
Here are our hypotheses:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
json is lighter than xml to serialize and deserialize;&lt;/li&gt;
&lt;li&gt;
json stored as map(*), array(*) and other items() are ligher than node() at runtime,
in particular subtree copy is zero cost in json;&lt;/li&gt;
&lt;li&gt;
templates with match patterns are efficiently can be implemented with maps();&lt;/li&gt;
&lt;li&gt;
there is incremental way forward from use of xml to use of json.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
If it pays off we might be switching xml format to json all over, even though it is
a development effort.
&lt;/p&gt;
&lt;p&gt;
But to proceed we need to commit an experiment to measure processing speed of xml
vs json in xslt.
&lt;/p&gt;
&lt;p&gt;
Now our task is to find an isolated small representative sample to prove or reject
our hypotheses. 
&lt;/p&gt;
&lt;p&gt;
Better to start off with some existing transformation, and change it from use of xml
to json. 
&lt;/p&gt;
&lt;p&gt;
The question is whether there is such a candidate.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=fdbaf9f5-827b-4a1f-9e52-4ec569801784" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,fdbaf9f5-827b-4a1f-9e52-4ec569801784.aspx</comments>
      <category>Thinking aloud</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=5440bb74-6b87-4ec5-9119-715b3e16b9a7</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,5440bb74-6b87-4ec5-9119-715b3e16b9a7.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=5440bb74-6b87-4ec5-9119-715b3e16b9a7</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">Couple of days ago, while integrating with
someones C# library, we had to debug it, as something went wrong. The code is big
and obscure but for the integration purposes it's rather simple: you just create
and call a class, that's all. Yet, something just did not work. We had to prove
that it's not our fault, as the other side is uncooperative and would not run
common debug session to resolve the problem. 
<p></p><p>
To simplify the matter as much as possible here is the case: 
</p><blockquote><pre>var input = ...
var x = new X();
var output = x.Execute(input);
</pre></blockquote><p>
You pass correct input, and get correct output. Simple, right? But it did not work!
So, we delved into the foreign code, and this is what we have seen: 
</p><blockquote><pre>class X: Y
{
  public Output Execute(Input input)
  {
    return Perform(input);
  }

  protected override Output Run(Input input)
  { 
    ...

     return output;
  }
}

class Y: Z
{
  ...
}

class Z
{
  protected Output Perform(Input input)
  {
    return Run(Input);
  }
        
  protected virtual Output Run(Input input)
  {
    return null;
  }
}</pre></blockquote><p></p><p>
Do you see, still flow is simple, right? We call <code>X.Execute()</code>, it calls <code>Z.Perform()</code>,
which in turn calls overriden <code>X.Run()</code> that returns the result. 
</p><p>
But to our puzzlement we got <code>null</code> on output, as if <code>Z.Run()</code> was
called! 
</p><p>
We stepped through the code in debugger and confirmed that <code>Z.Perform()</code> calls <code>Z.Run()</code>,
even though "<code>this</code>" instance is of type <code>X</code>. 
</p><p>
How can it be? It's a nonsence! Yet, no overriden method was ever called. 
</p><p>
No matter how much scrunity we applied to sources <code>X</code> and <code>Z</code> it
just did not work. 
</p><p></p><p>
We verified that the signature of <code>X.Run()</code> matches the signature of <code>Z.Run()</code>,
so it overrides the method. 
</p><p>
Then what do we see here? 
</p><p>
And then enlightenment come! Yes, <code>X.Run()</code> overrides the method, but what
method? 
</p><p>
We looked closely at class <code>Y</code>, and bingo, we can see there following: 
</p><blockquote><pre>class Y: Z
{
  ...

  protected virtual Output Run(Input input)
  {
    return null;
  }
      
  ...
}</pre></blockquote><p>
So, <code>X.Run()</code> overrides <code>Y.Run()</code> and not <code>Z.Run()</code>! 
</p><p>
Per .NET <code>Y.Run()</code> and <code>Z.Run()</code> are two independant virtual
methods, where <code>Y.Run()</code> in addition hides <code>Z.Run()</code>. 
</p><p>
IDE even issued a warning that it's better declare <code>Y.Run()</code> as: 
</p><blockquote><pre>protected new virtual Output Run(Input input)
{
  return null;
}</pre></blockquote><p>
So, someones code was plainly wrong: <code>Y.Run()</code> had to use <code><b>override</b></code> rather
than <code><b>virtual</b></code>. 
</p><p>
We won, right? 
</p><p>
Well, it's hard to call it a win. 
</p><p>
We spent a hour looking at someones ugly code just to prove we're still sane. 
</p><p></p><p>
So, what is conclusion of this story? 
</p><p>
We think here it is: 
</p><ul><li>
be cautious while looking at someones code;</li><li>
look at IDE warnings, don't disregard them, and try to resolve all of them in
your code base;</li><li>
try to write simple code.</li></ul><img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=5440bb74-6b87-4ec5-9119-715b3e16b9a7" /></body>
      <title>Bad code</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,5440bb74-6b87-4ec5-9119-715b3e16b9a7.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2022/01/15/BadCode.aspx</link>
      <pubDate>Sat, 15 Jan 2022 13:55:08 GMT</pubDate>
      <description>Couple of days ago, while integrating with someones C# library, we had to debug it, as something went wrong.
        The code is big and obscure but for the integration purposes it&amp;#39;s rather simple: you just create and call a class, that&amp;#39;s all.
        Yet, something just did not work. We had to prove that it&amp;#39;s not our fault, as the other side is uncooperative and would not run common debug session to resolve the problem.
    &lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
To simplify the matter as much as possible here is the case: 
&lt;/p&gt;
&lt;blockquote&gt; &lt;pre&gt;var input = ...
var x = new X();
var output = x.Execute(input);
&lt;/pre&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
You pass correct input, and get correct output. Simple, right? But it did not work!
So, we delved into the foreign code, and this is what we have seen: 
&lt;/p&gt;
&lt;blockquote&gt; &lt;pre&gt;class X: Y
{
  public Output Execute(Input input)
  {
    return Perform(input);
  }

  protected override Output Run(Input input)
  { 
    ...

     return output;
  }
}

class Y: Z
{
  ...
}

class Z
{
  protected Output Perform(Input input)
  {
    return Run(Input);
  }
        
  protected virtual Output Run(Input input)
  {
    return null;
  }
}&lt;/pre&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Do you see, still flow is simple, right? We call &lt;code&gt;X.Execute()&lt;/code&gt;, it calls &lt;code&gt;Z.Perform()&lt;/code&gt;,
which in turn calls overriden &lt;code&gt;X.Run()&lt;/code&gt; that returns the result. 
&lt;/p&gt;
&lt;p&gt;
But to our puzzlement we got &lt;code&gt;null&lt;/code&gt; on output, as if &lt;code&gt;Z.Run()&lt;/code&gt; was
called! 
&lt;/p&gt;
&lt;p&gt;
We stepped through the code in debugger and confirmed that &lt;code&gt;Z.Perform()&lt;/code&gt; calls &lt;code&gt;Z.Run()&lt;/code&gt;,
even though &amp;quot;&lt;code&gt;this&lt;/code&gt;&amp;quot; instance is of type &lt;code&gt;X&lt;/code&gt;. 
&lt;/p&gt;
&lt;p&gt;
How can it be? It&amp;#39;s a nonsence! Yet, no overriden method was ever called. 
&lt;/p&gt;
&lt;p&gt;
No matter how much scrunity we applied to sources &lt;code&gt;X&lt;/code&gt; and &lt;code&gt;Z&lt;/code&gt; it
just did not work. 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
We verified that the signature of &lt;code&gt;X.Run()&lt;/code&gt; matches the signature of &lt;code&gt;Z.Run()&lt;/code&gt;,
so it overrides the method. 
&lt;/p&gt;
&lt;p&gt;
Then what do we see here? 
&lt;/p&gt;
&lt;p&gt;
And then enlightenment come! Yes, &lt;code&gt;X.Run()&lt;/code&gt; overrides the method, but what
method? 
&lt;/p&gt;
&lt;p&gt;
We looked closely at class &lt;code&gt;Y&lt;/code&gt;, and bingo, we can see there following: 
&lt;/p&gt;
&lt;blockquote&gt; &lt;pre&gt;class Y: Z
{
  ...

  protected virtual Output Run(Input input)
  {
    return null;
  }
      
  ...
}&lt;/pre&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
So, &lt;code&gt;X.Run()&lt;/code&gt; overrides &lt;code&gt;Y.Run()&lt;/code&gt; and not &lt;code&gt;Z.Run()&lt;/code&gt;! 
&lt;/p&gt;
&lt;p&gt;
Per .NET &lt;code&gt;Y.Run()&lt;/code&gt; and &lt;code&gt;Z.Run()&lt;/code&gt; are two independant virtual
methods, where &lt;code&gt;Y.Run()&lt;/code&gt; in addition hides &lt;code&gt;Z.Run()&lt;/code&gt;. 
&lt;/p&gt;
&lt;p&gt;
IDE even issued a warning that it&amp;#39;s better declare &lt;code&gt;Y.Run()&lt;/code&gt; as: 
&lt;/p&gt;
&lt;blockquote&gt; &lt;pre&gt;protected new virtual Output Run(Input input)
{
  return null;
}&lt;/pre&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
So, someones code was plainly wrong: &lt;code&gt;Y.Run()&lt;/code&gt; had to use &lt;code&gt;&lt;b&gt;override&lt;/b&gt;&lt;/code&gt; rather
than &lt;code&gt;&lt;b&gt;virtual&lt;/b&gt;&lt;/code&gt;. 
&lt;/p&gt;
&lt;p&gt;
We won, right? 
&lt;/p&gt;
&lt;p&gt;
Well, it&amp;#39;s hard to call it a win. 
&lt;/p&gt;
&lt;p&gt;
We spent a hour looking at someones ugly code just to prove we&amp;#39;re still sane. 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
So, what is conclusion of this story? 
&lt;/p&gt;
&lt;p&gt;
We think here it is: 
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
be cautious while looking at someones code;&lt;/li&gt;
&lt;li&gt;
look at IDE warnings, don&amp;#39;t disregard them, and try to resolve all of them in
your code base;&lt;/li&gt;
&lt;li&gt;
try to write simple code.&lt;/li&gt;
&lt;/ul&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=5440bb74-6b87-4ec5-9119-715b3e16b9a7" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,5440bb74-6b87-4ec5-9119-715b3e16b9a7.aspx</comments>
      <category>.NET</category>
      <category>Thinking aloud</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=3042e60d-8943-47f0-9595-0d8e9cfb268c</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,3042e60d-8943-47f0-9595-0d8e9cfb268c.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=3042e60d-8943-47f0-9595-0d8e9cfb268c</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Lately we work great deal of time with <a href="https://en.wikipedia.org/wiki/Cosmos_DB">Azure's
CosmosDB</a>.
</p>
        <p>
This is how it's defined:
</p>
        <blockquote>
          <i>"It is schema-agnostic, horizontally scalable, and generally classified
as a <a href="https://en.wikipedia.org/wiki/NoSQL">NoSQL</a> database."</i>
        </blockquote>
        <p>
This, unconfident in itself, quote below is clarified as:
</p>
        <blockquote>
          <i>"The SQL API lets clients create, update and delete containers and
items. Items can be queried with a read-only, JSON-friendly SQL dialect."</i>
        </blockquote>
        <p>
To be honest this SQL API made us favor CosmosDB.
</p>
        <p>
So, we started a development with CosmosDB as a data storage.
</p>
        <p>
The next development ingredient we learned the hard way is to try to refrain from
clever techniques. 
</p>
        <p>
The lesson we learned is simple: after you finish with a project, provided it's
not a toy, you give it to people who will be supporting it. You should think about
those future developers before you're going to insert some cleverness in you code.
</p>
        <p>
With this common sense we selected <a href="https://en.wikipedia.org/wiki/Entity_Framework">EF
Core</a> as a library that will serve as an interface between C# and the database.
</p>
        <p>
Initialy all went well until we needed to store a list of strings as a document property
and found it's not possible.
</p>
        <p>
Why? - was a naive question.
</p>
        <p>
Answer puzzled us a lot - because string is not an "Entity" (what ever it
means), and EF is about framework of entities.
</p>
        <p>
You could argue with this argument as long as you like, it just does not work. It
is especially bad if you need to store a class that you do not directly control e.g.
structures returned from other services.
</p>
        <p>
Next pothole with EF was when we tried to run an innocent query that joins the data
from document: e.g. document contains items, and you want to query some items from
some documents.
</p>
        <p>
Guess what?
</p>
        <p>
Right, EF Core does not support it.
</p>
        <p>
Why?
</p>
        <p>
Because!
</p>
        <p>
Later we have found that many other constructs and functions that you easily use in
SQL dialect of CosmosDB are not possible or supported in EF Core.
</p>
        <p>
We were very upset with those crutches and came to a conclusion that EF Core harms
more than helps when you work with CosmosDB.
</p>
        <p>
We went on and looked at how you work directly with CosmosDB client, and have found
that it has all features ready:
</p>
        <ul>
          <li>
you may give it SQL and bind parameters;</li>
          <li>
you may convert result items to objects;</li>
          <li>
you may create, delete, update and query data;</li>
        </ul>
        <p>
So, do we need EF Core? 
</p>
        <p>
We answered, no.
</p>
        <p>
This does not mean we reject the value of EF Core but here our conclusion was that
this API layer just complicated things instead making them simpler. It might be that
EF Core for CosmosDB is not mature enough at this time.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=3042e60d-8943-47f0-9595-0d8e9cfb268c" />
      </body>
      <title>CosmosDB with EF Core</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,3042e60d-8943-47f0-9595-0d8e9cfb268c.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2021/10/20/CosmosDBWithEFCore.aspx</link>
      <pubDate>Wed, 20 Oct 2021 16:11:39 GMT</pubDate>
      <description>&lt;p&gt;
Lately we work great deal of time with &lt;a href="https://en.wikipedia.org/wiki/Cosmos_DB"&gt;Azure&amp;#39;s
CosmosDB&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
This is how it&amp;#39;s defined:
&lt;/p&gt;
&lt;blockquote&gt;&lt;i&gt;"It is schema-agnostic, horizontally scalable, and generally classified
as a &lt;a href="https://en.wikipedia.org/wiki/NoSQL"&gt;NoSQL&lt;/a&gt; database."&lt;/i&gt;&lt;/blockquote&gt; 
&lt;p&gt;
This, unconfident in itself, quote below is clarified as:
&lt;/p&gt;
&lt;blockquote&gt;&lt;i&gt;"The SQL API lets clients create, update and delete containers and
items. Items can be queried with a read-only, JSON-friendly SQL dialect."&lt;/i&gt;&lt;/blockquote&gt; 
&lt;p&gt;
To be honest this SQL API made us favor CosmosDB.
&lt;/p&gt;
&lt;p&gt;
So, we started a development with CosmosDB as a data storage.
&lt;/p&gt;
&lt;p&gt;
The next development ingredient we learned the hard way is to try to refrain from
clever techniques. 
&lt;/p&gt;
&lt;p&gt;
The lesson we learned is simple: after you finish with a project, provided it&amp;#39;s
not a toy, you give it to people who will be supporting it. You should think about
those future developers before you&amp;#39;re going to insert some cleverness in you code.
&lt;/p&gt;
&lt;p&gt;
With this common sense we selected &lt;a href="https://en.wikipedia.org/wiki/Entity_Framework"&gt;EF
Core&lt;/a&gt; as a library that will serve as an interface between C# and the database.
&lt;/p&gt;
&lt;p&gt;
Initialy all went well until we needed to store a list of strings as a document property
and found it&amp;#39;s not possible.
&lt;/p&gt;
&lt;p&gt;
Why? - was a naive question.
&lt;/p&gt;
&lt;p&gt;
Answer puzzled us a lot - because string is not an &amp;quot;Entity&amp;quot; (what ever it
means), and EF is about framework of entities.
&lt;/p&gt;
&lt;p&gt;
You could argue with this argument as long as you like, it just does not work. It
is especially bad if you need to store a class that you do not directly control e.g.
structures returned from other services.
&lt;/p&gt;
&lt;p&gt;
Next pothole with EF was when we tried to run an innocent query that joins the data
from document: e.g. document contains items, and you want to query some items from
some documents.
&lt;/p&gt;
&lt;p&gt;
Guess what?
&lt;/p&gt;
&lt;p&gt;
Right, EF Core does not support it.
&lt;/p&gt;
&lt;p&gt;
Why?
&lt;/p&gt;
&lt;p&gt;
Because!
&lt;/p&gt;
&lt;p&gt;
Later we have found that many other constructs and functions that you easily use in
SQL dialect of CosmosDB are not possible or supported in EF Core.
&lt;/p&gt;
&lt;p&gt;
We were very upset with those crutches and came to a conclusion that EF Core harms
more than helps when you work with CosmosDB.
&lt;/p&gt;
&lt;p&gt;
We went on and looked at how you work directly with CosmosDB client, and have found
that it has all features ready:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
you may give it SQL and bind parameters;&lt;/li&gt;
&lt;li&gt;
you may convert result items to objects;&lt;/li&gt;
&lt;li&gt;
you may create, delete, update and query data;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
So, do we need EF Core? 
&lt;/p&gt;
&lt;p&gt;
We answered, no.
&lt;/p&gt;
&lt;p&gt;
This does not mean we reject the value of EF Core but here our conclusion was that
this API layer just complicated things instead making them simpler. It might be that
EF Core for CosmosDB is not mature enough at this time.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=3042e60d-8943-47f0-9595-0d8e9cfb268c" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,3042e60d-8943-47f0-9595-0d8e9cfb268c.aspx</comments>
      <category>Azure</category>
      <category>Thinking aloud</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=9121c6f9-e622-4d71-b25b-58763fa5d88e</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,9121c6f9-e622-4d71-b25b-58763fa5d88e.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=9121c6f9-e622-4d71-b25b-58763fa5d88e</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Recently we have found that <a href="https://docs.microsoft.com/en-us/dotnet/api/system.runtime.serialization.formatters.binary.binaryformatter.serialize?view=net-5.0">BinaryFormatter.Serialize</a> and <a href="https://docs.microsoft.com/en-us/dotnet/api/system.runtime.serialization.formatters.binary.binaryformatter.deserialize?view=net-5.0">BinaryFormatter.Deserialize</a> methods
are marked as obsolete in .NET 5.0, and are declared dangerous:
</p>
        <blockquote>
          <i>The <strong>BinaryFormatter</strong> type is dangerous and is <strong>not</strong> recommended
for data processing. Applications should stop using BinaryFormatter as soon as possible,
even if they believe the data they're processing to be trustworthy. BinaryFormatter
is insecure and can't be made secure.</i>
        </blockquote>
        <p>
See <a href="https://docs.microsoft.com/en-us/dotnet/standard/serialization/binaryformatter-security-guide">BinaryFormatter
security guide</a> for more details.
</p>
        <p>
That guide along with its links go and expand on what problems BinaryFormatter poses.
The schema of dangeous use cases, we have seen so far, is like that:
</p>
        <ul>
          <li>
two different sides communicate to each other;</li>
          <li>
one side supplies input in BinaryFormatter's format;</li>
          <li>
other side reads input using BinaryFormatter and instantiates classes.</li>
        </ul>
        <p>
A threat arises when two sides cannot trust to each other or cannot establish trusted
communication chanel. In these cases malign input can be supplied to a side reading
the data, which might lead to unexpected code execution, deny of service, data exposure
and to other bad consequences.
</p>
        <p>
Arguing like this, today's maintainers of .NET concluded that it's better to tear
down BinaryFormatter and similar APIs out of the framework.
</p>
        <p>
Note that they don't claim BinaryFormatter itself, or Reflection API that it uses,
as a core of the problem. They blame on communication.
</p>
        <p>
Spelling out clearly what are concerns could help to everyone to better understand
how to address it. In the area of security of communication there are a lot of ready
solutions like:
</p>
        <ul>
          <li>
use signature to avoid tampering the data;</li>
          <li>
use encription to avoid spying the data;</li>
          <li>
use access rights to avoid even access to the data;</li>
          <li>
use secure communication channels.</li>
        </ul>
        <p>
We can surely state that without applying these solutions no other serialization format
is reliable and is subject of the same vulnerabilities.
</p>
        <p>
 
</p>
        <p>
After all it looked like an attempt to throw out the baby with the bath water. The
good news is that thankfully to now modular structure of .NET runtime we're able
to access binary serialization library, which are (and will be) available on nugets
repositories. So, it's futile effort to erase this usefull API. 
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=9121c6f9-e622-4d71-b25b-58763fa5d88e" />
      </body>
      <title>Binary serialization in .NET 5.0</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,9121c6f9-e622-4d71-b25b-58763fa5d88e.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2021/02/02/BinarySerializationInNET50.aspx</link>
      <pubDate>Tue, 02 Feb 2021 12:39:37 GMT</pubDate>
      <description>&lt;p&gt;
Recently we have found that &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.runtime.serialization.formatters.binary.binaryformatter.serialize?view=net-5.0"&gt;BinaryFormatter.Serialize&lt;/a&gt; and &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.runtime.serialization.formatters.binary.binaryformatter.deserialize?view=net-5.0"&gt;BinaryFormatter.Deserialize&lt;/a&gt; methods
are marked as obsolete in .NET 5.0, and are declared dangerous:
&lt;/p&gt;
&lt;blockquote&gt;&lt;i&gt;The &lt;strong&gt;BinaryFormatter&lt;/strong&gt; type is dangerous and is &lt;strong&gt;not&lt;/strong&gt; recommended
for data processing. Applications should stop using BinaryFormatter as soon as possible,
even if they believe the data they're processing to be trustworthy. BinaryFormatter
is insecure and can't be made secure.&lt;/i&gt;&lt;/blockquote&gt; 
&lt;p&gt;
See &lt;a href="https://docs.microsoft.com/en-us/dotnet/standard/serialization/binaryformatter-security-guide"&gt;BinaryFormatter
security guide&lt;/a&gt; for more details.
&lt;/p&gt;
&lt;p&gt;
That guide along with its links go and expand on what problems BinaryFormatter poses.
The schema of dangeous use cases, we have seen so far, is like that:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
two different sides communicate to each other;&lt;/li&gt;
&lt;li&gt;
one side supplies input in BinaryFormatter&amp;#39;s format;&lt;/li&gt;
&lt;li&gt;
other side reads input using BinaryFormatter and instantiates classes.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
A threat arises when two sides cannot trust to each other or cannot establish trusted
communication chanel. In these cases malign input can be supplied to a side reading
the data, which might lead to unexpected code execution, deny of service, data exposure
and to other bad consequences.
&lt;/p&gt;
&lt;p&gt;
Arguing like this, today's maintainers of .NET concluded that it's better to tear
down BinaryFormatter and similar APIs out of the framework.
&lt;/p&gt;
&lt;p&gt;
Note that they don&amp;#39;t claim BinaryFormatter itself, or Reflection API that it uses,
as a core of the problem. They blame on communication.
&lt;/p&gt;
&lt;p&gt;
Spelling out clearly what are concerns could help to everyone to better understand
how to address it. In the area of security of communication there are a lot of ready
solutions like:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
use signature to avoid tampering the data;&lt;/li&gt;
&lt;li&gt;
use encription to avoid spying the data;&lt;/li&gt;
&lt;li&gt;
use access rights to avoid even access to the data;&lt;/li&gt;
&lt;li&gt;
use secure communication channels.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
We can surely state that without applying these solutions no other serialization format
is reliable and is subject of the same vulnerabilities.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
After all it looked like an attempt to throw out the baby with the bath water. The
good news is that thankfully to now modular structure of .NET runtime we&amp;#39;re able
to access binary serialization library, which are (and will be) available on nugets
repositories. So, it&amp;#39;s futile effort to erase this usefull API. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=9121c6f9-e622-4d71-b25b-58763fa5d88e" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,9121c6f9-e622-4d71-b25b-58763fa5d88e.aspx</comments>
      <category>.NET</category>
      <category>Thinking aloud</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=b69227a9-de75-4062-aa5b-82c8dff548e1</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,b69227a9-de75-4062-aa5b-82c8dff548e1.aspx</pingback:target>
      <dc:creator>Arthur Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=b69227a9-de75-4062-aa5b-82c8dff548e1</wfw:commentRss>
      <title>Collecting public data from Internet</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,b69227a9-de75-4062-aa5b-82c8dff548e1.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2021/01/01/CollectingPublicDataFromInternet.aspx</link>
      <pubDate>Fri, 01 Jan 2021 14:34:37 GMT</pubDate>
      <description>&lt;p&gt;
Earlier we wrote that recently we've gotten few tasks related to Machine Learning.
The prerequisites to such task is to collect and prepare the input data. Usually the
required data is scattered across public sites, some of them are in plain text format
(or close to it), but others are accessible as output of public applications. To obtain
the required data for such sites you have to navigate thourgh pages, which often requires
keeping state between navigations. 
&lt;/p&gt;
&lt;p&gt;
In order to implement this task you need some kind of crawler/scraper of the websites.
Fortunately, there are a lot of frameworks, libraries and tools in C# (and in other
languages too) that allow to do this (visit &lt;a href="https://nugetmusthaves.com/Tag/crawler" target="_blank"&gt;this&lt;/a&gt; or &lt;a href="https://prowebscraper.com/blog/50-best-open-source-web-crawlers/" target="_blank"&gt;this&lt;/a&gt; site
to see most popular of them), for example: 
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
ScrapySharp&lt;/li&gt;
&lt;li&gt;
ABot&lt;/li&gt;
&lt;li&gt;
HtmlAgilityPack&lt;/li&gt;
&lt;li&gt;
DotnetSpider&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
There are pros and cons of using these libraries. Most crucial cons is a lack of support
of rich UI based on heavy client-side scripts and client-side state support. Since
not all such libraries implement fully browser emulation and even more, some of them
do not support Javascript execution. So, they suit for gathering information from
simple web pages, but no library allows to easy navigate to some page of a web application
that keeps rich client-side state. Even best of them, like ScrapySharp, require heavy
programming to achieve the result.
&lt;/p&gt;
&lt;p&gt;
Then, suddenly, we've recalled that already for several years we're using Selenium
and web drivers to automate web tests for AngularJS/Angular projects. After short
discussion we came to conclusion that there is no big difference between testing web
application and collecting data, since one of testing stages is collecting of actual
results (data) from the tested page, and usually our tests consist of chains of actions
performed on consequently visited pages. 
&lt;/p&gt;
&lt;p&gt;
This way we came to idea to use WebDriver API implemented by &lt;a href="https://www.selenium.dev/documentation/en/" target="_blank"&gt;Selenium
project&lt;/a&gt;. There are implementations of this API in different languages, and in
C# too.
&lt;/p&gt;
&lt;p&gt;
Using WebDriver we easily implement cumbersome navigation of a complex web application
and can collect required data. Moreover, it allows to run WebDriver in screenless
mode. Some of its features allow to create a snapshots of virtual screen and store
HTML sources that would resulted of Javascript execution. These features are very
useful during run-time troubleshooting. To create a complex web application navigation
we need only a bit more knowledge than usual web application's user - we need to identify
somehow pages' elements for example by CSS selectors or by id of HTML elements (as
we do this for tests). All the rest, like coockies, view state (if any), value of
hidden fields, some Javascript events will be transparent in this case. 
&lt;/p&gt;
&lt;p&gt;
Although one may say that approach with Selenium is rather fat, it's ought to mention
that it is rather scalable. You may either to run several threads with different WebDriver
instances in each thread or run several processes simultaneously. 
&lt;/p&gt;
&lt;p&gt;
However, beside pros there are cons in the solution with Selenium. They will appear
when you'll decide to publish it, e.g. to Azure environment. Take a note that approach
with Selenium requires a browser on the server, there is also a problem with Azure
itself, as it's Microsoft's platform and Selenium is a product of their main competitor
Google... So, some issues aren't techincals. The only possible solution is to use
PaaS approach instead of SaaS, but in this case you have to support everything by
yourself... 
&lt;/p&gt;
&lt;p&gt;
The other problem is that if your application will implement rather aggressive crawling,
so either servers where you gather data or your own host might ban it. So, be gentle,
play nice, and implement delays between requests. 
&lt;/p&gt;
&lt;p&gt;
Also, take into account that when you're implementing any crawler some problems may
appear on law level, since not all web sites allow pull anything you want. Many sites
use terms &amp; conditions that defines rules for the site users (that you cralwer should
follow to), otherwise legal actions may be used against them (or their owners in case
of crawler). There is &lt;a href="https://www.c-sharpcorner.com/article/web-crawling-with-c-sharp/" targte="_blank"&gt;very
interesting article&lt;/a&gt; that describes many pitfalls when you implement your own crawler. 
&lt;/p&gt;
&lt;p&gt;
To summarize everything we told early, the Selenium project could be used in many
scenarios, and one of them is to create a powerful crawler. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=b69227a9-de75-4062-aa5b-82c8dff548e1" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,b69227a9-de75-4062-aa5b-82c8dff548e1.aspx</comments>
      <category>ML.NET</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=799a45cc-83c0-4057-baaa-5089f8ffb484</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,799a45cc-83c0-4057-baaa-5089f8ffb484.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=799a45cc-83c0-4057-baaa-5089f8ffb484</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
While doing <a href="https://www.oneadvanced.com/services/ca-gen-modernisation/">Cool:GEN
migratiotions to Java and C#</a> we produce rather big Angular applications.
</p>
        <p>
Everything is fine: server runs a REST APIs, and client is an Angular application
with components per each window, dialog or screen. The only problem is with the word
big.
</p>
        <p>
We observe that enterprises that used Cool:GEN to develop their workflow come to migration
stage with applications containing thousands of windows. In simple cases, after assessment,
clients are able to split their monolith workflow into a set of independent applications.
But even then we are dealing with Angular applications containing hundreds to many
thousands components.
</p>
        <p>
Now, lets look at Angular world. <a href="https://angular.io/guide/ivy">Best practices</a> advice
to (and actually almost force you to) use Ahead Of Time, Ivy compilation of all components
and their templates.
</p>
        <p>
Naive attempt to build such monolith Angular application will most surely fail. Angular
uses <a href="https://nodejs.org/en/">nodejs</a> for build, and chances are close
to 100% of nodejs to run out of memory during the <code>ng build</code>. 
</p>
        <p>
You may fight and throw at it a capable build machine with 16 or better with 32GB
of RAM, and instruct nodejs to use all of it. 
</p>
        <p>
Well, it's rather poor and extensive way of dealing with scale problems but it
works.
</p>
        <p>
Next hurdle you run into is time. We know it might take days just to build it. 
</p>
        <p>
You may ask why?
</p>
        <p>
Well, angular is doing its best to <a href="https://angular.io/guide/template-typecheck">validate
templates</a>! 
</p>
        <p>
Unfortunately the only viable workaround is to switch this nice feature off for such
a big project.
</p>
        <p>
With such setup you're able to build angular project in just 20-30 minutes!
</p>
        <p>
Well, this is a big progress if you compare complete failure vs something that at
least passes the build.
</p>
        <p>
But what's next?
</p>
        <p>
Sure, there are next problems:
</p>
        <ul>
          <li>
scripts both development and production are of nonsense size: like several dozen megabytes
for production, and some even higher number for development.</li>
          <li>
            <code>ng serve</code> eats even more memory and builds even longer making nightmare
out of development and support of such an application;</li>
          <li>
startup of such application, if it will start at all, is very slow.</li>
        </ul>
        <p>
So, what can be done? How can we create a manageable Angular application containing
that many components?
</p>
        <p>
Angular advices <a href="https://angular.io/guide/lazy-loading-ngmodules">Lazy-loading
feature modules</a>.
</p>
        <p>
That's reasonable advice!
</p>
        <p>
We can create coarse grained modules containing subsets of components or fine grained
modules containing one component.
</p>
        <p>
So, does it help?
</p>
        <p>
Yes, but it does not solve all problems:
</p>
        <ul>
          <li>
            <code>ng build</code> and <code>ng serve</code> are still very slow;</li>
          <li>
build produces multiple small scripts that are loaded on demand, so at least application
works in browser.</li>
        </ul>
        <p>
Yet, other important problem is still there: we have multiple severly separated server
REST controllers with components that represent them.
</p>
        <p>
On the server side we have Java or C# REST controllers hosting business logic. They
are separated per multiple projects probably managed by separate teams, and probably
kept in separate GITs (or whatever). On the client side we have a fat angular project
storing everything kept in single source repository.
</p>
        <p>
This is not going to work from management perspective.
</p>
        <p>
So the next step is try to split fat Angular project into multiple small projects.
So, let's say we shall have 100 small angular libraries combinded by master project.
</p>
        <p>
This is not going to work either due to nature of npm projects, as it will requre
terabytes of cloned node_modules folders for each library, and many hours to build
each of them.
</p>
        <p>
It seems there is a room for improvments in npm area. There is no point to make dedicated
copies of node_modules. It's much easier to have a local cache of artifacts.
</p>
        <p>
So, what is the direction? How to create big angular project after all?
</p>
        <p>
What we have here is:
</p>
        <ul>
          <li>
a big enterprise level application;</li>
          <li>
it is modular but modules must work together to form desired workflow;</li>
          <li>
different modules are supported by different teams (both server and client side);</li>
          <li>
client Angular components correspond to REST controllers on the server.</li>
          <li>
all pages use the same styles and the same set of UI controls;</li>
        </ul>
        <p>
Looking from this perspective all development can be seen as:
</p>
        <ul>
          <li>
development and support of unified styles and ui components that must be reused through
the application;</li>
          <li>
development of server side and REST controllers that implement business logic;</li>
          <li>
development of templates of components (note that components themselves do nothing
except expose their templates).</li>
        </ul>
        <p>
Studying this design suggests important and independent role of templates just like
it is in AngularJS!
</p>
        <p>
In contrast Angular templates are only a tool used by components. It's not obvious
how to use thousands of templates without first building thousands components; neither
it's obvious how to dynamically host those templates (routes do not help here).
</p>
        <p>
Though not obvious it's still possible to do it though it requires use a bit lower
level API than tutorials suggest. Ingredients are:
</p>
        <ul>
          <li>
use of Just In Time (in contrast to Ahead Of Time) compilation, and use View Enginev
(in contrast to Ivy);</li>
          <li>
use <a href="https://angular.io/api/core/ViewContainerRef#viewcontainerref">ViewContainerRef</a> to
host components dynamically;</li>
          <li>
Dynamic components and modules that you can create on demand using templates loaded
e.g. through <code>HttpClient</code>.</li>
        </ul>
        <p>
To make things short we shall show the example of dynamic components in next article.
</p>
        <p>
Here we shall emphasize that such design allows us to create small angular application
that builds under 20 seconds with component templates served along with the REST controllers,
and stored in the same Git. 
</p>
        <p>
So, if you say have a server subproject exposing REST controller say in the form:
api/area/MyComponent then its template may be exposed as resource: page/area/MyComponent.
Templates are loaded and compiled on demand at runtime thus making application light.
At the same time templates may be cached in browser cache thus reducing number of
roundtrips to the server.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=799a45cc-83c0-4057-baaa-5089f8ffb484" />
      </body>
      <title>Big Angular applications</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,799a45cc-83c0-4057-baaa-5089f8ffb484.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2020/12/29/BigAngularApplications.aspx</link>
      <pubDate>Tue, 29 Dec 2020 18:15:25 GMT</pubDate>
      <description>  &lt;p&gt;
While doing &lt;a href="https://www.oneadvanced.com/services/ca-gen-modernisation/"&gt;Cool:GEN
migratiotions to Java and C#&lt;/a&gt; we produce rather big Angular applications.
&lt;/p&gt;
&lt;p&gt;
Everything is fine: server runs a REST APIs, and client is an Angular application
with components per each window, dialog or screen. The only problem is with the word
big.
&lt;/p&gt;
&lt;p&gt;
We observe that enterprises that used Cool:GEN to develop their workflow come to migration
stage with applications containing thousands of windows. In simple cases, after assessment,
clients are able to split their monolith workflow into a set of independent applications.
But even then we are dealing with Angular applications containing hundreds to many
thousands components.
&lt;/p&gt;
&lt;p&gt;
Now, lets look at Angular world. &lt;a href="https://angular.io/guide/ivy"&gt;Best practices&lt;/a&gt; advice
to (and actually almost force you to) use Ahead Of Time, Ivy compilation of all components
and their templates.
&lt;/p&gt;
&lt;p&gt;
Naive attempt to build such monolith Angular application will most surely fail. Angular
uses &lt;a href="https://nodejs.org/en/"&gt;nodejs&lt;/a&gt; for build, and chances are close
to 100% of nodejs to run out of memory during the &lt;code&gt;ng build&lt;/code&gt;. 
&lt;/p&gt;
&lt;p&gt;
You may fight and throw at it a capable build machine with 16 or better with 32GB
of RAM, and instruct nodejs to use all of it. 
&lt;/p&gt;
&lt;p&gt;
Well, it&amp;#39;s rather poor and extensive way of dealing with scale problems but it
works.
&lt;/p&gt;
&lt;p&gt;
Next hurdle you run into is time. We know it might take days just to build it. 
&lt;/p&gt;
&lt;p&gt;
You may ask why?
&lt;/p&gt;
&lt;p&gt;
Well, angular is doing its best to &lt;a href="https://angular.io/guide/template-typecheck"&gt;validate
templates&lt;/a&gt;! 
&lt;/p&gt;
&lt;p&gt;
Unfortunately the only viable workaround is to switch this nice feature off for such
a big project.
&lt;/p&gt;
&lt;p&gt;
With such setup you&amp;#39;re able to build angular project in just 20-30 minutes!
&lt;/p&gt;
&lt;p&gt;
Well, this is a big progress if you compare complete failure vs something that at
least passes the build.
&lt;/p&gt;
&lt;p&gt;
But what&amp;#39;s next?
&lt;/p&gt;
&lt;p&gt;
Sure, there are next problems:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
scripts both development and production are of nonsense size: like several dozen megabytes
for production, and some even higher number for development.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ng serve&lt;/code&gt; eats even more memory and builds even longer making nightmare
out of development and support of such an application;&lt;/li&gt;
&lt;li&gt;
startup of such application, if it will start at all, is very slow.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
So, what can be done? How can we create a manageable Angular application containing
that many components?
&lt;/p&gt;
&lt;p&gt;
Angular advices &lt;a href="https://angular.io/guide/lazy-loading-ngmodules"&gt;Lazy-loading
feature modules&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
That&amp;#39;s reasonable advice!
&lt;/p&gt;
&lt;p&gt;
We can create coarse grained modules containing subsets of components or fine grained
modules containing one component.
&lt;/p&gt;
&lt;p&gt;
So, does it help?
&lt;/p&gt;
&lt;p&gt;
Yes, but it does not solve all problems:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ng build&lt;/code&gt; and &lt;code&gt;ng serve&lt;/code&gt; are still very slow;&lt;/li&gt;
&lt;li&gt;
build produces multiple small scripts that are loaded on demand, so at least application
works in browser.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Yet, other important problem is still there: we have multiple severly separated server
REST controllers with components that represent them.
&lt;/p&gt;
&lt;p&gt;
On the server side we have Java or C# REST controllers hosting business logic. They
are separated per multiple projects probably managed by separate teams, and probably
kept in separate GITs (or whatever). On the client side we have a fat angular project
storing everything kept in single source repository.
&lt;/p&gt;
&lt;p&gt;
This is not going to work from management perspective.
&lt;/p&gt;
&lt;p&gt;
So the next step is try to split fat Angular project into multiple small projects.
So, let&amp;#39;s say we shall have 100 small angular libraries combinded by master project.
&lt;/p&gt;
&lt;p&gt;
This is not going to work either due to nature of npm projects, as it will requre
terabytes of cloned node_modules folders for each library, and many hours to build
each of them.
&lt;/p&gt;
&lt;p&gt;
It seems there is a room for improvments in npm area. There is no point to make dedicated
copies of node_modules. It&amp;#39;s much easier to have a local cache of artifacts.
&lt;/p&gt;
&lt;p&gt;
So, what is the direction? How to create big angular project after all?
&lt;/p&gt;
&lt;p&gt;
What we have here is:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
a big enterprise level application;&lt;/li&gt;
&lt;li&gt;
it is modular but modules must work together to form desired workflow;&lt;/li&gt;
&lt;li&gt;
different modules are supported by different teams (both server and client side);&lt;/li&gt;
&lt;li&gt;
client Angular components correspond to REST controllers on the server.&lt;/li&gt;
&lt;li&gt;
all pages use the same styles and the same set of UI controls;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Looking from this perspective all development can be seen as:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
development and support of unified styles and ui components that must be reused through
the application;&lt;/li&gt;
&lt;li&gt;
development of server side and REST controllers that implement business logic;&lt;/li&gt;
&lt;li&gt;
development of templates of components (note that components themselves do nothing
except expose their templates).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Studying this design suggests important and independent role of templates just like
it is in AngularJS!
&lt;/p&gt;
&lt;p&gt;
In contrast Angular templates are only a tool used by components. It&amp;#39;s not obvious
how to use thousands of templates without first building thousands components; neither
it&amp;#39;s obvious how to dynamically host those templates (routes do not help here).
&lt;/p&gt;
&lt;p&gt;
Though not obvious it&amp;#39;s still possible to do it though it requires use a bit lower
level API than tutorials suggest. Ingredients are:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
use of Just In Time (in contrast to Ahead Of Time) compilation, and use View Enginev
(in contrast to Ivy);&lt;/li&gt;
&lt;li&gt;
use &lt;a href="https://angular.io/api/core/ViewContainerRef#viewcontainerref"&gt;ViewContainerRef&lt;/a&gt; to
host components dynamically;&lt;/li&gt;
&lt;li&gt;
Dynamic components and modules that you can create on demand using templates loaded
e.g. through &lt;code&gt;HttpClient&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
To make things short we shall show the example of dynamic components in next article.
&lt;/p&gt;
&lt;p&gt;
Here we shall emphasize that such design allows us to create small angular application
that builds under 20 seconds with component templates served along with the REST controllers,
and stored in the same Git. 
&lt;/p&gt;
&lt;p&gt;
So, if you say have a server subproject exposing REST controller say in the form:
api/area/MyComponent then its template may be exposed as resource: page/area/MyComponent.
Templates are loaded and compiled on demand at runtime thus making application light.
At the same time templates may be cached in browser cache thus reducing number of
roundtrips to the server.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=799a45cc-83c0-4057-baaa-5089f8ffb484" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,799a45cc-83c0-4057-baaa-5089f8ffb484.aspx</comments>
      <category>Angular</category>
      <category>AngularJS</category>
      <category>Thinking aloud</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=ec795ede-3e18-473f-bff9-204ea1cecf49</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,ec795ede-3e18-473f-bff9-204ea1cecf49.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=ec795ede-3e18-473f-bff9-204ea1cecf49</wfw:commentRss>
      <title>Groups in SQL</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,ec795ede-3e18-473f-bff9-204ea1cecf49.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2020/08/05/GroupsInSQL.aspx</link>
      <pubDate>Wed, 05 Aug 2020 07:44:07 GMT</pubDate>
      <description>  &lt;p&gt;
Recently our colleague turned to us and asked to help to deal with some complex query.
&lt;/p&gt;
&lt;p&gt;
It has turned out that the complex part was to understand what he wants to achieve.
&lt;/p&gt;
&lt;p&gt;
After listening to him we have forumulated the task in our words and have confirmed
that that is what he wants.
&lt;/p&gt;
&lt;p&gt;
So, that&amp;#39;s the task in our formulation:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Assume you have events. 
&lt;/li&gt;
&lt;li&gt;
Each event acts upon one or more accounts.&lt;/li&gt;
&lt;li&gt;
Find all events that act on the same set of accounts.&lt;/li&gt;
&lt;li&gt;
Note we deal with mutiple millions of events and accounts.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Data is defined like this:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;create table dbo.Event
(
  EventID bigint not null,
  AccountID varchar(18) not null,
  primary key(EventID, AccountID)
);&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
Requested query turned out to be very simple, yet, not as simple as one would think
to account big amout of data:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt; S2.EventID and
    S1.Items = S2.Items and
    S1.Hash = S2.Hash and
    not exists
    (
      select AccountID from D where EventID = S1.EventID
      except
      select AccountID from D where EventID = S2.EventID
    );&lt;/pre&gt;with D as
(
  select * from dbo.Event
),
S as
(
  select
    EventID,
    count(*) Items,
    checksum_agg(checksum(AccountID)) Hash
  from
    D
  group by
    EventID
)
select
  S1.EventID, S2.EventID
from
  S S1
  inner join
  S S2
  on
    S1.EventID 
&lt;/blockquote&gt; 
&lt;p&gt;
The idea is to:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
calculate a hash derived from list of accounts for each group;&lt;/li&gt;
&lt;li&gt;
join groups with the same hash;&lt;/li&gt;
&lt;li&gt;
verify that matched groups fit perfectly.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Even simpler solution that does not use hashes is not scaleable, as it&amp;#39;s performance
is slower than O(N^2), where N - is a number of events. It has unacceptable time with
N ~1e4, nothing to say about N ~1e7.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
At this point our colleague was already satisfied, as he got result in couple of minutes
for a task that he could not even formalize as SQL.
&lt;/p&gt;
&lt;p&gt;
But we felt it could be even better.
&lt;/p&gt;
&lt;p&gt;
We looked at statistics:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;
with D as
(
  select * from dbo.Event
),
S as
(
  select
    EventID,
    count(*) Items
  from
    D
  group by
    EventID
)
select
  Items, count(*) EventCount
from
  S
group by
  Items
order by
  EventCount desc;&lt;/pre&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
and have seen that most of the events, about 90%, deal with single account, and all
other with two and more (some of them act upon big number of accounts).
&lt;/p&gt;
&lt;p&gt;
The nature of the dataset gave us a hint of more verbose but more fast query:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt; S2.EventID and
    S1.Items = 1 and
    S2.Items = 1 and
    S1.AccountID = S2.AccountID
union all
select
  S1.EventID, S2.EventID
from
  S S1
  inner join
  S S2
  on
    S1.EventID &lt; S2.EventID and
    S1.Items &gt;with D as
(
  select * from dbo.Event
),
S as
(
  select
    EventID,
    min(AccountID) AccountID,
    count(*) Items,
    checksum_agg(checksum(AccountID)) Hash
  from
    D
  group by
    EventID
)
select
  S1.EventID, S2.EventID
from
  S S1
  inner join
  S S2
  on
    S1.EventID  1 and
    S2.Items &gt; 1 and
    S1.Items = S2.Items and
    S1.Hash = S2.Hash and
    not exists
    (
      select AccountID from D where EventID = S1.EventID
      except
      select AccountID from D where EventID = S2.EventID
    );&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
This query produced results in twenty seconds instead of couple of minutes for a dataset
with ~1e7 rows.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=ec795ede-3e18-473f-bff9-204ea1cecf49" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,ec795ede-3e18-473f-bff9-204ea1cecf49.aspx</comments>
      <category>SQL Server puzzle</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=8a79cdd8-4d17-416b-a82c-6b597dd36728</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,8a79cdd8-4d17-416b-a82c-6b597dd36728.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=8a79cdd8-4d17-416b-a82c-6b597dd36728</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
While working on algorithm to trace <a href="https://en.wikipedia.org/wiki/Biconnected_component">Biconnected
components</a> for <a href="https://github.com/nesterovsky-bros/xslt-graph">Graph
API in the XSLT</a>  we realized that we implemented it unconventionally.
</p>
        <h3>A pseudocode in <a href="https://en.wikipedia.org/wiki/Biconnected_component">Wikipedia</a> is:
</h3>
        <pre>GetArticulationPoints(i, d)
    visited[i] := true
    depth[i] := d
    low[i] := d
    childCount := 0
    isArticulation := false

    <b>for
each</b> ni <b>in</b> adj[i] <b>do</b><b>if</b> not visited[ni] <b>then</b> parent[ni]
:= i GetArticulationPoints(ni, d + 1) childCount := childCount + 1 <b>if</b> low[ni]
≥ depth[i] <b>then</b> isArticulation := true low[i] := Min (low[i], low[ni]) <b>else
if</b> ni ≠ parent[i] <b>then</b> low[i] := Min (low[i], depth[ni]) <b>if</b> (parent[i]
≠ <b>null</b><b>and</b> isArticulation) <b>or</b> (parent[i] = <b>null</b><b>and</b> childCount
&gt; 1) <b>then</b> Output i as articulation point</pre>
        <p>
That algorithm is based on the fact that connected graph can be represented as a tree
of biconnected components. Vertices of such <b>tree</b> are called articulation points.
Implementation deals with a depth of each vertex, and with a lowpoint parameter that
is also related to vertex depth during Depth-First-Search.
</p>
        <p>
Out of interest we approached to the problem from different perspective. A vertex
is an articulation point if it has neighbors that cannot be combined into a path not
containing this vertex. As well as classical algorithm we use Depth-First-Search to
navigate the graph, but in contrast we collect cycles that pass through each vertex.
If during back pass of Depth-First-Search we find not cycle from "child"
to "ancestor" then it is necessary an articulation point.
</p>
        <h3>Here is pseudocode:
</h3>
        <pre>GetArticulationPoints(v, p) -&gt; result
    index = index + 1
    visited[v] = index 
    result = index
    articulation = p = null ? -1 : 0

    <b>for
each</b> n <b>in</b> neighbors of v <b>except</b> p <b>do</b><b>if</b> visited[n]
= 0 <b>then</b> nresult = GetArticulationPoints(n, v) result = min(result, nresult) <b>if</b> nresult
&gt;= visited[v] <b>then</b> articulation = articulation + 1 <b>else</b> result =
min(result, visited[n]) <b>if</b> articulation &gt; 0 <b>then</b> Output v as articulation
point</pre>
        <p>
Algorithms' complexity are the same.
</p>
        <p>
What is interesting is that we see no obvious way to transform one algorithm into
the other except from starting from Graph theory.
</p>
        <p>
More is on <a href="https://github.com/nesterovsky-bros/xslt-graph/wiki/Algorithm-for-Biconnected-components">Wiki</a>.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=8a79cdd8-4d17-416b-a82c-6b597dd36728" />
      </body>
      <title>Algorithm for Biconnected components</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,8a79cdd8-4d17-416b-a82c-6b597dd36728.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2020/05/24/AlgorithmForBiconnectedComponents.aspx</link>
      <pubDate>Sun, 24 May 2020 12:15:02 GMT</pubDate>
      <description>  &lt;p&gt;
While working on algorithm to trace &lt;a href="https://en.wikipedia.org/wiki/Biconnected_component"&gt;Biconnected
components&lt;/a&gt; for &lt;a href="https://github.com/nesterovsky-bros/xslt-graph"&gt;Graph
API in the XSLT&lt;/a&gt;&amp;nbsp; we realized that we implemented it unconventionally.
&lt;/p&gt;
&lt;h3&gt;A pseudocode in &lt;a href="https://en.wikipedia.org/wiki/Biconnected_component"&gt;Wikipedia&lt;/a&gt; is:
&lt;/h3&gt;
&lt;pre&gt;GetArticulationPoints(i, d)
    visited[i] := true
    depth[i] := d
    low[i] := d
    childCount := 0
    isArticulation := false

    &lt;b&gt;for
each&lt;/b&gt; ni &lt;b&gt;in&lt;/b&gt; adj[i] &lt;b&gt;do&lt;/b&gt; &lt;b&gt;if&lt;/b&gt; not visited[ni] &lt;b&gt;then&lt;/b&gt; parent[ni]
:= i GetArticulationPoints(ni, d + 1) childCount := childCount + 1 &lt;b&gt;if&lt;/b&gt; low[ni]
≥ depth[i] &lt;b&gt;then&lt;/b&gt; isArticulation := true low[i] := Min (low[i], low[ni]) &lt;b&gt;else
if&lt;/b&gt; ni ≠ parent[i] &lt;b&gt;then&lt;/b&gt; low[i] := Min (low[i], depth[ni]) &lt;b&gt;if&lt;/b&gt; (parent[i]
≠ &lt;b&gt;null&lt;/b&gt; &lt;b&gt;and&lt;/b&gt; isArticulation) &lt;b&gt;or&lt;/b&gt; (parent[i] = &lt;b&gt;null&lt;/b&gt; &lt;b&gt;and&lt;/b&gt; childCount
&amp;gt; 1) &lt;b&gt;then&lt;/b&gt; Output i as articulation point&lt;/pre&gt;
&lt;p&gt;
That algorithm is based on the fact that connected graph can be represented as a tree
of biconnected components. Vertices of such &lt;b&gt;tree&lt;/b&gt; are called articulation points.
Implementation deals with a depth of each vertex, and with a lowpoint parameter that
is also related to vertex depth during Depth-First-Search.
&lt;/p&gt;
&lt;p&gt;
Out of interest we approached to the problem from different perspective. A vertex
is an articulation point if it has neighbors that cannot be combined into a path not
containing this vertex. As well as classical algorithm we use Depth-First-Search to
navigate the graph, but in contrast we collect cycles that pass through each vertex.
If during back pass of Depth-First-Search we find not cycle from &amp;quot;child&amp;quot;
to &amp;quot;ancestor&amp;quot; then it is necessary an articulation point.
&lt;/p&gt;
&lt;h3&gt;Here is pseudocode:
&lt;/h3&gt;
&lt;pre&gt;GetArticulationPoints(v, p) -&amp;gt; result
    index = index + 1
    visited[v] = index 
    result = index
    articulation = p = null ? -1 : 0

    &lt;b&gt;for
each&lt;/b&gt; n &lt;b&gt;in&lt;/b&gt; neighbors of v &lt;b&gt;except&lt;/b&gt; p &lt;b&gt;do&lt;/b&gt; &lt;b&gt;if&lt;/b&gt; visited[n]
= 0 &lt;b&gt;then&lt;/b&gt; nresult = GetArticulationPoints(n, v) result = min(result, nresult) &lt;b&gt;if&lt;/b&gt; nresult
&amp;gt;= visited[v] &lt;b&gt;then&lt;/b&gt; articulation = articulation + 1 &lt;b&gt;else&lt;/b&gt; result =
min(result, visited[n]) &lt;b&gt;if&lt;/b&gt; articulation &amp;gt; 0 &lt;b&gt;then&lt;/b&gt; Output v as articulation
point&lt;/pre&gt;
&lt;p&gt;
Algorithms&amp;#39; complexity are the same.
&lt;/p&gt;
&lt;p&gt;
What is interesting is that we see no obvious way to transform one algorithm into
the other except from starting from Graph theory.
&lt;/p&gt;
&lt;p&gt;
More is on &lt;a href="https://github.com/nesterovsky-bros/xslt-graph/wiki/Algorithm-for-Biconnected-components"&gt;Wiki&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=8a79cdd8-4d17-416b-a82c-6b597dd36728" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,8a79cdd8-4d17-416b-a82c-6b597dd36728.aspx</comments>
      <category>Thinking aloud</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=c7ab748a-9b08-425c-83be-907ab4b7fef3</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,c7ab748a-9b08-425c-83be-907ab4b7fef3.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=c7ab748a-9b08-425c-83be-907ab4b7fef3</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Michael Key's <a href="http://www.saxonica.com/papers/xmlprague-2020mhk.pdf">"A
Proposal for XSLT 4.0"</a> has spinned our interest in what could be added or
changed in XSLT. This way we decided to implement <a href="https://github.com/nesterovsky-bros/xslt-graph">Graph
API purely in xslt</a>. Our goal was to prove that:
</p>
        <ul>
          <li>
it's possible to provide efficient implementation of different Graph Algorithms in
XSLT;</li>
          <li>
to build Graph API the way that engine could provide native implementations of Grahp
Algorithms.</li>
          <li>
to find through an experiments what could be added to XSLT as a language.</li>
        </ul>
        <p>
At present we may confirm that first <a href="https://github.com/nesterovsky-bros/xslt-graph">two
goals are reachable</a>; and experiments have shown that XSLT could provide more help
to make program better, e.g. we have seen that language could simplify coding cycles.
</p>
        <p>
Graph algorithms are often expressed with while cycles, e.g <a href="https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm">"Dijkstra's
algorithm"</a> has:
</p>
        <pre>12      while Q is not empty:
13          u ← vertex in Q with min dist[u]  
</pre>
        <p>
body is executed when condition is satisfied, but condition is impacted by body itself.
</p>
        <p>
In xslt 3.0 we did this with simple recursion:
</p>
        <pre>
&lt;xsl:template name="f:while" as="item()*"&gt;
  &lt;xsl:param name="condition" as="function(item()*) as xs:boolean"/&gt;
  &lt;xsl:param name="action" as="function(item()*) as item()*"/&gt;
  &lt;xsl:param name="next" as="function(item()*, item()*) as item()*"/&gt;
  &lt;xsl:param name="state" as="item()*"/&gt;

  &lt;xsl:if test="$condition($state)"&gt;
    &lt;xsl:variable name="items" as="item()*" select="$action($state)"/&gt;

    &lt;xsl:sequence select="$items"/&gt;

    &lt;xsl:call-template name="f:while"&gt;
      &lt;xsl:with-param name="condition" select="$condition"/&gt;
      &lt;xsl:with-param name="action" select="$action"/&gt;
      &lt;xsl:with-param name="next" select="$next"/&gt;
      &lt;xsl:with-param name="state" select="$next($state, $items)"/&gt;
    &lt;/xsl:call-template&gt;
  &lt;/xsl:if&gt;
&lt;/xsl:template&gt;
</pre>
        <p>
But here is the point. It could be done in more comprehended way. E.g. to let <code>xsl:iterate</code> without <code>select</code> to
cycle until <code>xsl:break</code> is reached.
</p>
        <pre>&lt;xsl:iterate&gt;
  &lt;xsl:param name="name" as="..." value="..."/&gt;
  
  &lt;xsl:if test="..."&gt;
    &lt;xsl:break/&gt;
  &lt;/xsl:if&gt;

  ...
&lt;/xsl:iterate&gt;</pre>
        <p>
So, what we propose is to let <code>xsl:iterate/@select</code> to be optional, and
change the behavior of processor when the attribute is missing from compilation error
to a valid behavior. This should not impact on any existing valid XSLT 3.0 program. 
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=c7ab748a-9b08-425c-83be-907ab4b7fef3" />
      </body>
      <title>On XSLT 4</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,c7ab748a-9b08-425c-83be-907ab4b7fef3.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2020/05/19/OnXSLT4.aspx</link>
      <pubDate>Tue, 19 May 2020 07:00:25 GMT</pubDate>
      <description>&lt;p&gt;
Michael Key&amp;#39;s &lt;a href="http://www.saxonica.com/papers/xmlprague-2020mhk.pdf"&gt;&amp;quot;A
Proposal for XSLT 4.0&amp;quot;&lt;/a&gt; has spinned our interest in what could be added or
changed in XSLT. This way we decided to implement &lt;a href="https://github.com/nesterovsky-bros/xslt-graph"&gt;Graph
API purely in xslt&lt;/a&gt;. Our goal was to prove that:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
it's possible to provide efficient implementation of different Graph Algorithms in
XSLT;&lt;/li&gt;
&lt;li&gt;
to build Graph API the way that engine could provide native implementations of Grahp
Algorithms.&lt;/li&gt;
&lt;li&gt;
to find through an experiments what could be added to XSLT as a language.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
At present we may confirm that first &lt;a href="https://github.com/nesterovsky-bros/xslt-graph"&gt;two
goals are reachable&lt;/a&gt;; and experiments have shown that XSLT could provide more help
to make program better, e.g. we have seen that language could simplify coding cycles.
&lt;/p&gt;
&lt;p&gt;
Graph algorithms are often expressed with while cycles, e.g &lt;a href="https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm"&gt;&amp;quot;Dijkstra&amp;#39;s
algorithm&amp;quot;&lt;/a&gt; has:
&lt;/p&gt;
&lt;pre&gt;12      while Q is not empty:
13          u ← vertex in Q with min dist[u]  
&lt;/pre&gt;
&lt;p&gt;
body is executed when condition is satisfied, but condition is impacted by body itself.
&lt;/p&gt;
&lt;p&gt;
In xslt 3.0 we did this with simple recursion:
&lt;/p&gt;
&lt;pre&gt;
&amp;lt;xsl:template name="f:while" as="item()*"&gt;
  &amp;lt;xsl:param name="condition" as="function(item()*) as xs:boolean"/&gt;
  &amp;lt;xsl:param name="action" as="function(item()*) as item()*"/&gt;
  &amp;lt;xsl:param name="next" as="function(item()*, item()*) as item()*"/&gt;
  &amp;lt;xsl:param name="state" as="item()*"/&gt;

  &amp;lt;xsl:if test="$condition($state)"&gt;
    &amp;lt;xsl:variable name="items" as="item()*" select="$action($state)"/&gt;

    &amp;lt;xsl:sequence select="$items"/&gt;

    &amp;lt;xsl:call-template name="f:while"&gt;
      &amp;lt;xsl:with-param name="condition" select="$condition"/&gt;
      &amp;lt;xsl:with-param name="action" select="$action"/&gt;
      &amp;lt;xsl:with-param name="next" select="$next"/&gt;
      &amp;lt;xsl:with-param name="state" select="$next($state, $items)"/&gt;
    &amp;lt;/xsl:call-template&gt;
  &amp;lt;/xsl:if&gt;
&amp;lt;/xsl:template&gt;
&lt;/pre&gt;
&lt;p&gt;
But here is the point. It could be done in more comprehended way. E.g. to let &lt;code&gt;xsl:iterate&lt;/code&gt; without &lt;code&gt;select&lt;/code&gt; to
cycle until &lt;code&gt;xsl:break&lt;/code&gt; is reached.
&lt;/p&gt;
&lt;pre&gt;&amp;lt;xsl:iterate&amp;gt;
  &amp;lt;xsl:param name=&amp;quot;name&amp;quot; as=&amp;quot;...&amp;quot; value=&amp;quot;...&amp;quot;/&amp;gt;
  
  &amp;lt;xsl:if test=&amp;quot;...&amp;quot;&amp;gt;
    &amp;lt;xsl:break/&amp;gt;
  &amp;lt;/xsl:if&amp;gt;

  ...
&amp;lt;/xsl:iterate&amp;gt;&lt;/pre&gt;
&lt;p&gt;
So, what we propose is to let &lt;code&gt;xsl:iterate/@select&lt;/code&gt; to be optional, and
change the behavior of processor when the attribute is missing from compilation error
to a valid behavior. This should not impact on any existing valid XSLT 3.0 program. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=c7ab748a-9b08-425c-83be-907ab4b7fef3" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,c7ab748a-9b08-425c-83be-907ab4b7fef3.aspx</comments>
      <category>Thinking aloud</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=57573dd7-7ec0-47e3-891e-aa186277e0f2</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,57573dd7-7ec0-47e3-891e-aa186277e0f2.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=57573dd7-7ec0-47e3-891e-aa186277e0f2</wfw:commentRss>
      <title>Graphs in XSLT</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,57573dd7-7ec0-47e3-891e-aa186277e0f2.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2020/05/12/GraphsInXSLT.aspx</link>
      <pubDate>Tue, 12 May 2020 06:08:51 GMT</pubDate>
      <description>  &lt;p&gt;
Recently we've read an article &lt;a href="http://www.saxonica.com/papers/xmlprague-2020mhk.pdf"&gt;&amp;quot;A
Proposal for XSLT 4.0&amp;quot;&lt;/a&gt;, and thought it worth to suggest one more idea. We
have written a &lt;a href="https://saxonica.plan.io/boards/2/topics/7870"&gt;message&lt;/a&gt; to
Michael Kay, author of this proposal. Here it is: 
&lt;/p&gt;
&lt;blockquote style="font-style: italic"&gt; &lt;b&gt;A&amp;V&lt;/b&gt; 
&lt;p&gt;
Historically xslt, xquery and xpath were dealing with trees. Nowadays it became much
common to process graphs. Many tasks can be formulated in terms of graphs, and in
particular any task processing trees is also graph task. 
&lt;/p&gt;
&lt;p&gt;
I suggest to take a deeper look in this direction. 
&lt;/p&gt;
&lt;p&gt;
As an inspiration I may suggest to look at &lt;a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1709r2.pdf"&gt;&amp;quot;P1709R2:
Graph Library&amp;quot;&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;- the C++ proposal. 
&lt;/p&gt;
&lt;br /&gt;
&lt;b&gt;Michael Kay&lt;/b&gt; 
&lt;p&gt;
I have for many years found it frustrating that XML is confined to hierarchic relationships
(things like IDREF and XLink are clumsy workarounds); also the fact that the arbitrary
division of data into &amp;quot;documents&amp;quot; plays such a decisive role: documents
should only exist in the serialized representation of the model, not in the model
itself. 
&lt;/p&gt;
&lt;p&gt;
I started my career working with the Codasyl-defined network data model. It&amp;#39;s
a fine and very flexible data model; its downfall was the (DOM-like) procedural navigation
language. So I&amp;#39;ve often wondered what one could do trying to re-invent the Codasyl
model in a more modern idiom, coupling it with an XPath-like declarative access language
extended to handle networks (graphs) rather than hierarchies. 
&lt;/p&gt;
&lt;p&gt;
I&amp;#39;ve no idea how close a reinventiion of Codasyl would be to some of the modern
graph data models; it would be interesting to see. The other interesting aspect of
this is whether you can make it work for schema-less data. 
&lt;/p&gt;
&lt;p&gt;
But I don&amp;#39;t think that would be an incremental evolution of XSLT; I think it would
be something completely new. 
&lt;/p&gt;
&lt;br /&gt;
&lt;b&gt;A&amp;V&lt;/b&gt; 
&lt;p&gt;
I was not so radical in my thoughts. &lt;img alt=":-)" src="http://www.nesterovsky-bros.com/weblog/smilies/happy.gif"&gt; 
&lt;/p&gt;
&lt;p&gt;
Even C++ API is not so radical, as they do not impose hard requirements on internal
graph representation but rather define template API that will work both with third
party representations (they even mention Fortran) or several built-in implementations
that uses standard vectors. 
&lt;/p&gt;
&lt;p&gt;
Their strong point is in algorithms provided as part of library and not graph internal
structure (I think authors of that paper have structured it not the best way). E.g.
in the second part they list graph algorithms: Depth First Search (DFS); Breadth First
Search (BFS); Topological Sort (TopoSort); Shortest Paths Algorithms; Dijkstra Algorithms;
and so on. 
&lt;/p&gt;
&lt;p&gt;
If we shall try to map it to xpath world them graph on API level might be represented
as a user function or as a map of user functions. 
&lt;/p&gt;
&lt;p&gt;
On a storage level user may implement graph using a sequence of maps or map of maps,
or even using xdm elements. 
&lt;/p&gt;
&lt;p&gt;
So, my approach is evolutional. In fact I suggest pure API that could even be implemented
now. 
&lt;/p&gt;
&lt;br /&gt;
&lt;b&gt;Michael Kay&lt;/b&gt; 
&lt;p&gt;
Yes, there&amp;#39;s certainly scope for graph-oriented functions such as &lt;code&gt;closure($origin,
$function)&lt;/code&gt; and &lt;code&gt;is-reachable($origin, $function)&lt;/code&gt; and &lt;code&gt;find-path($origin,
$destination, $function)&lt;/code&gt; where we use the existing data model, treating any
item as a node in a graph, and representing the arcs using functions. There are a
few complications, e.g. what&amp;#39;s the identity comparison between arbitrary items,
but it can probably be done. 
&lt;/p&gt;
&lt;br /&gt;
&lt;b&gt;A&amp;V&lt;/b&gt; &lt;blockquote&gt; &gt; There are a few complications, e.g. what&amp;#39;s the identity
comparison between arbitrary items, but it can probably be done. &lt;/blockquote&gt; 
&lt;p&gt;
One approach to address this is through definition of graph API. E.g. to define graph
as a map (interface analogy) of functions, with equality functions, if required: 
&lt;/p&gt;
&lt;pre&gt;map
{
  vertices: function(),
  edges: function(),
  value: function(vertex),
  in-vertex: function(edge),
  out-vertex: function(edge),
  edges: function(vertex),
  is-in-vertex: function(edge, vertex),
  is-out-vertex: function(edge, vertex)
  ...
}&lt;/pre&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Not sure how far this will go but who knows. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=57573dd7-7ec0-47e3-891e-aa186277e0f2" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,57573dd7-7ec0-47e3-891e-aa186277e0f2.aspx</comments>
      <category>Thinking aloud</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=2aaf8fdd-8795-43a8-a35d-c2710d017607</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,2aaf8fdd-8795-43a8-a35d-c2710d017607.aspx</pingback:target>
      <dc:creator>Arthur Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=2aaf8fdd-8795-43a8-a35d-c2710d017607</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
It's not a secret that COVID-19 epidemic will change our world significantly. <img alt="picture more than 30 years ago" src="https://phasechange.ai/wp-content/uploads/2018/10/are-you-a-cobol-programmer-dinosaur-11-4-97_20181012_tje.png" style="float: left; width: 350px;" />It
impacts on economics and public services, especially on social services of our countries.
We saw this in our country and now the same happens in US. Probably the same thing
happens in all countries all over the world that suffer from COVID-19.
</p>
        <p>
Usually, nowadays, such services are exposed online, but nobody expected such extreme
loading of these services. And they start molder under such load. Programs start crash...
and somebody has to fix them. It's just a temporary technical inconvenience when there
is staff that familiar with such programs and technologies, but what about situation
when programs and technologies are obsolete? When staff that may support them are
about to retire due to ages, when knowledge were almost lost... It's very scary when
such applications rules very important spheres of our life such social services, finances,
medicine, defence etc. Something similar happened in US, so US government asked IBM
about a help with their stuff written in COBOL.
</p>
        <p>
Probably, in short term, they'll close the gaps, but taking in account the fact that
epidemic won't dissolve in a month, there is a risk to still in the same hole... There
are two ways to solve this issue in long term:
</p>
        <ol>
          <li>
to make COBOL widely used program language and to teach enough programmers that will
use it. This is exactly what IBM tries to do, see <a href="https://www.techspot.com/news/84796-us-states-desperate-cobol-programmers-ibm-offering-free.html" target="_blank">this
article</a>, but this way to nowhere, since it is not too popular in society of software
developers. 
</li>
          <li>
to migrate such application to new technologies and new platform (e.g. Java or C#
on UNIX/Windows). In this case organizations obtain scalable applications and ability
to find human resources that may fix/modernize such applications step by step, in
spare time, without loosing existing functionality. This is what our company <a href="http://www.oneadvanced.com" target="_blank"><b>Advanced</b></a> may
provide. And we are not alone. There are many such companies that may implement such
migration on high level of quality. 
</li>
        </ol>
        <p>
And many professionals (even those that deal with COBOL on day by day basis) think
that only 2nd way is viable. Let's see what will happen... More about the issue, see <a href="https://arstechnica.com/tech-policy/2020/04/ibm-scrambles-to-find-or-train-more-cobol-programmers-to-help-states" target="_blank">here</a>.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=2aaf8fdd-8795-43a8-a35d-c2710d017607" />
      </body>
      <title>COBOL - raise from the dead or RIP?</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,2aaf8fdd-8795-43a8-a35d-c2710d017607.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2020/04/15/COBOLRaiseFromTheDeadOrRIP.aspx</link>
      <pubDate>Wed, 15 Apr 2020 06:00:51 GMT</pubDate>
      <description>&lt;p&gt;
It's not a secret that COVID-19 epidemic will change our world significantly. &lt;img alt="picture more than 30 years ago" src="https://phasechange.ai/wp-content/uploads/2018/10/are-you-a-cobol-programmer-dinosaur-11-4-97_20181012_tje.png" style="float: left; width: 350px;" /&gt;It
impacts on economics and public services, especially on social services of our countries.
We saw this in our country and now the same happens in US. Probably the same thing
happens in all countries all over the world that suffer from COVID-19.
&lt;/p&gt;
&lt;p&gt;
Usually, nowadays, such services are exposed online, but nobody expected such extreme
loading of these services. And they start molder under such load. Programs start crash...
and somebody has to fix them. It's just a temporary technical inconvenience when there
is staff that familiar with such programs and technologies, but what about situation
when programs and technologies are obsolete? When staff that may support them are
about to retire due to ages, when knowledge were almost lost... It's very scary when
such applications rules very important spheres of our life such social services, finances,
medicine, defence etc. Something similar happened in US, so US government asked IBM
about a help with their stuff written in COBOL.
&lt;/p&gt;
&lt;p&gt;
Probably, in short term, they'll close the gaps, but taking in account the fact that
epidemic won't dissolve in a month, there is a risk to still in the same hole... There
are two ways to solve this issue in long term:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
to make COBOL widely used program language and to teach enough programmers that will
use it. This is exactly what IBM tries to do, see &lt;a href="https://www.techspot.com/news/84796-us-states-desperate-cobol-programmers-ibm-offering-free.html" target="_blank"&gt;this
article&lt;/a&gt;, but this way to nowhere, since it is not too popular in society of software
developers. 
&lt;/li&gt;
&lt;li&gt;
to migrate such application to new technologies and new platform (e.g. Java or C#
on UNIX/Windows). In this case organizations obtain scalable applications and ability
to find human resources that may fix/modernize such applications step by step, in
spare time, without loosing existing functionality. This is what our company &lt;a href="http://www.oneadvanced.com" target="_blank"&gt;&lt;b&gt;Advanced&lt;/b&gt;&lt;/a&gt; may
provide. And we are not alone. There are many such companies that may implement such
migration on high level of quality. 
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
And many professionals (even those that deal with COBOL on day by day basis) think
that only 2nd way is viable. Let's see what will happen... More about the issue, see &lt;a href="https://arstechnica.com/tech-policy/2020/04/ibm-scrambles-to-find-or-train-more-cobol-programmers-to-help-states" target="_blank"&gt;here&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=2aaf8fdd-8795-43a8-a35d-c2710d017607" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,2aaf8fdd-8795-43a8-a35d-c2710d017607.aspx</comments>
      <category>Thinking aloud</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=2d7b9eb9-ad1b-40fa-9a55-f5afa260b2a8</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,2d7b9eb9-ad1b-40fa-9a55-f5afa260b2a8.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=2d7b9eb9-ad1b-40fa-9a55-f5afa260b2a8</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
People compare these two technologies, and it seems an established fact is that Angular
is evolutionally more advanced framework. We're not going to contradict, contrary,
we agree with it, but it's better for an opinion to be grounded on facts that
one can evaluate and verify.
</p>
        <p>
Fortunately we got a chance to make such a comparison.
</p>
        <p>
We support conversions of <a href="https://en.wikipedia.org/wiki/CA_Gen">Cool:GEN</a> (a
legacy <a href="https://en.wikipedia.org/wiki/Computer-aided_software_engineering">CASE</a> tool
with roots in 80th) to java or C#. In its time Cool:GEN allowed to greatly automate
enterprise development using Mainframes as a server side and Mainframe terminals or
Win32 GUIs as clients.
</p>
        <p>
The legacy of this tool are probably hundreds of business and database models, milions
of programs generated on COBOL on Mainframes and on C or Java on Windows and Linux.
All this runs to this time in many econimic sectors.
</p>
        <p>
Usually the client is some enterprise that invested a lot into design, development
and support of their business model using Cool:GEN but now most such clients a trying
not to lose this legacy but to convert it into something that goes in parallel with
todays technologies.
</p>
        <p>
As original technology is sound, so it is possible to map it to todays Java or C#
on server, REST or SOAP as a transport, and Angular, AngularJS or some other on client.
Such automatic conversion is an essense of our conversions efforts.
</p>
        <p>
To understand a scope consider a typical enterprise client that has 2-3 thousand windows
that are backed by 20-30 thousand programs.
</p>
        <p>
Now, consider that the conversion is done. On output among other things we produce
a clean java or C# web application with REST and SOAP interface, and Angular or AngularJS
web client that encapsulates those 2-3 thousand windows.
</p>
        <p>
Each window definition is rather small 5-10 KB in html form, but whole mass of windows
takes 10-30 MB, which is not small any more.
</p>
        <p>
For AngularJS we generate just those html templates, but for Angular we need to generate
separate components for each window that includes typescript class, template and style.
</p>
        <p>
While amout of generated resource for AngularJS stays in those 10-30 MB, generated
Angular takes at least 5-10 MB more.
</p>
        <p>
The next step is build. 
</p>
        <p>
AngularJS builds distribution that includes all used libraries and a set of templates,
and it takes something like a minute from the CPU. Produced output is about 300 KB
minified script and those 10-30 MB of templates (multiple files with 5-10 KB each
one).
</p>
        <p>
Angular (here we talk about version 9) builds distribution that includes all used
libraries and a set of compiled components that are to be loaded lazily on demand.
Without of the both angular builder that performs tree shaking build takes days. With
tree shaking off it takes 40 minutes. This is the first notable difference. Produced
output for ES2015 (latest javascript) is about 1 MB, and 15-100 KB per each compiled
component. This is the second notable difference that already impacts end user rather
than developer.
</p>
        <p>
The third difference is in the end user experience. Though we have built equalvalent
Angular and AngularJS frontend we observe load time of angular is higher. This cannot
only be ascribed to bigger file sizes. It seems internal initialization also takes
more time for Angular.
</p>
        <p>
So, our experience in this particular test shows that Angular has more room to improve.
In particular: compile time, bundle size, runtime speed and simplicity of dynamic
loading (we have strong cases when template compilation is not the best approach).
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=2d7b9eb9-ad1b-40fa-9a55-f5afa260b2a8" />
      </body>
      <title>Angular vs AngularJS. Practical comparison.</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,2d7b9eb9-ad1b-40fa-9a55-f5afa260b2a8.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2020/04/04/AngularVsAngularJSPracticalComparison.aspx</link>
      <pubDate>Sat, 04 Apr 2020 12:37:15 GMT</pubDate>
      <description>  &lt;p&gt;
People compare these two technologies, and it seems an established fact is that Angular
is evolutionally more advanced framework. We&amp;#39;re not going to contradict, contrary,
we agree with it, but it&amp;#39;s better for an opinion to be grounded on facts that
one can evaluate and verify.
&lt;/p&gt;
&lt;p&gt;
Fortunately we got a chance to make such a comparison.
&lt;/p&gt;
&lt;p&gt;
We support conversions of &lt;a href="https://en.wikipedia.org/wiki/CA_Gen"&gt;Cool:GEN&lt;/a&gt; (a
legacy &lt;a href="https://en.wikipedia.org/wiki/Computer-aided_software_engineering"&gt;CASE&lt;/a&gt; tool
with roots in 80th) to java or C#. In its time Cool:GEN allowed to greatly automate
enterprise development using Mainframes as a server side and Mainframe terminals or
Win32 GUIs as clients.
&lt;/p&gt;
&lt;p&gt;
The legacy of this tool are probably hundreds of business and database models, milions
of programs generated on COBOL on Mainframes and on C or Java on Windows and Linux.
All this runs to this time in many econimic sectors.
&lt;/p&gt;
&lt;p&gt;
Usually the client is some enterprise that invested a lot into design, development
and support of their business model using Cool:GEN but now most such clients a trying
not to lose this legacy but to convert it into something that goes in parallel with
todays technologies.
&lt;/p&gt;
&lt;p&gt;
As original technology is sound, so it is possible to map it to todays Java or C#
on server, REST or SOAP as a transport, and Angular, AngularJS or some other on client.
Such automatic conversion is an essense of our conversions efforts.
&lt;/p&gt;
&lt;p&gt;
To understand a scope consider a typical enterprise client that has 2-3 thousand windows
that are backed by 20-30 thousand programs.
&lt;/p&gt;
&lt;p&gt;
Now, consider that the conversion is done. On output among other things we produce
a clean java or C# web application with REST and SOAP interface, and Angular or AngularJS
web client that encapsulates those 2-3 thousand windows.
&lt;/p&gt;
&lt;p&gt;
Each window definition is rather small 5-10 KB in html form, but whole mass of windows
takes 10-30 MB, which is not small any more.
&lt;/p&gt;
&lt;p&gt;
For AngularJS we generate just those html templates, but for Angular we need to generate
separate components for each window that includes typescript class, template and style.
&lt;/p&gt;
&lt;p&gt;
While amout of generated resource for AngularJS stays in those 10-30 MB, generated
Angular takes at least 5-10 MB more.
&lt;/p&gt;
&lt;p&gt;
The next step is build. 
&lt;/p&gt;
&lt;p&gt;
AngularJS builds distribution that includes all used libraries and a set of templates,
and it takes something like a minute from the CPU. Produced output is about 300 KB
minified script and those 10-30 MB of templates (multiple files with 5-10 KB each
one).
&lt;/p&gt;
&lt;p&gt;
Angular (here we talk about version 9) builds distribution that includes all used
libraries and a set of compiled components that are to be loaded lazily on demand.
Without of the both angular builder that performs tree shaking build takes days. With
tree shaking off it takes 40 minutes. This is the first notable difference. Produced
output for ES2015 (latest javascript) is about 1 MB, and 15-100 KB per each compiled
component. This is the second notable difference that already impacts end user rather
than developer.
&lt;/p&gt;
&lt;p&gt;
The third difference is in the end user experience. Though we have built equalvalent
Angular and AngularJS frontend we observe load time of angular is higher. This cannot
only be ascribed to bigger file sizes. It seems internal initialization also takes
more time for Angular.
&lt;/p&gt;
&lt;p&gt;
So, our experience in this particular test shows that Angular has more room to improve.
In particular: compile time, bundle size, runtime speed and simplicity of dynamic
loading (we have strong cases when template compilation is not the best approach).
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=2d7b9eb9-ad1b-40fa-9a55-f5afa260b2a8" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,2d7b9eb9-ad1b-40fa-9a55-f5afa260b2a8.aspx</comments>
      <category>AngularJS</category>
      <category>Java</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=861382a1-a2b8-4b39-a9f4-1f7a2148bf59</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,861382a1-a2b8-4b39-a9f4-1f7a2148bf59.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=861382a1-a2b8-4b39-a9f4-1f7a2148bf59</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
We were asked to help with search service in one enterprise. We were told that their
SharePoint portal does not serve their need. Main complaints were about the quality
of search results.
</p>
        <p>
They have decided to implement external index of SharePoint content, using <a href="https://www.elastic.co/">Elastic</a>,
and expose custom search API within the enterprise.
</p>
        <p>
        </p>
        <p>
We questioned their conclusions, asked why did they think Elastic will give much better
results, asked did they try to figure out why SharePoint give no desired results.
</p>
        <p>
Answers did not convince us though we have joined the project.
</p>
        <p>
        </p>
        <p>
What do you think? Elastic did not help at all though they hoped very much that its
query language will help to rank results in a way that matched documents will be found.
After all they thought it was a problem of ranking of results.
</p>
        <p>
        </p>
        <p>
Here we have started our analysis. We took a specific document that must be found
but is never returned from search.
</p>
        <p>
        </p>
        <p>
It turned to be well known problem, at least we dealt with closely related one in
the past. There are two ingredients here:
</p>
        <ul>
          <li>
documents that have low chances to be found are PDFs;</li>
          <li>
we live in Israel, so most texts are Hebrew, which means words are written from right
to left, while some other texts from left to right. See <a href="https://en.wikipedia.org/wiki/Bi-directional_text" target="_blank">Bi-directional
text</a>.</li>
        </ul>
        <p>
Traditionally PDF documents are provided in a way that only distantly resembles logical
structure of original content. E.g., paragraphs of texts are often represented as
unrelated runs of text lines, or as set of text runs representing single words, or
independant characters. No need to say that additional complication comes from that
Hebrew text are often represented visually (from left to right, as if "hello"
would be stored as "olleh" and would be just printed from right to left).
Another common feature of PDF are custom fonts with uncanonical mappings, or images
with glyphs of letters.
</p>
        <p>
You can implement these tricks in other document formats but for some reason PDF is
only format we have seen that regularly and intensively uses these techniques.
</p>
        <p>
        </p>
        <p>
At this point we have realized that it's not a fault of a search engine to find
the document but the feature of the PDF to expose its text to a crawler in a form
that cannot be used for search. In fact, PDF cannot search by itself in such documents,
as when you try to find some text in the document opened in a pdf viewer, that you
clearly see in the document, you often find nothing.
</p>
        <p>
        </p>
        <p>
A question. What should you do in this case when no any PDF text extractor can give
you correct text but text is there when you looking at document in a pdf viewer?
</p>
        <p>
        </p>
        <p>
We decided it's time to go in the direction of image recognition. Thankfully,
nowdays it's a matter of available processing resources.
</p>
        <p>
Our goal was:
</p>
        <ol>
          <li>
Have images of each PDF page. This task is immediately solved with <a href="https://pdfbox.apache.org/" target="_blank">Apache
PDFBox (A Java PDF Library) - it's time to say this is java project.</a></li>
          <li>
Run Optical Character Recognition (OCR) over images, and get extracted texts. This
is perfectly done by <a href="https://github.com/tesseract-ocr/tesseract" target="_blank">tesseract-ocr/tesseract</a>,
and thankfully to its java wrapper <a href="https://github.com/bytedeco/javacpp-presets/tree/master/tesseract" target="_blank">bytedeco/javacpp-presets</a> we
can immediately call this C++ API from java.</li>
        </ol>
        <p>
The only small nuisance of tesseract is that it does not expose table recognition
info, but we can easily overcome it (we solved this task in the past), as along with
each text run tesseract exposes its position.
</p>
        <p>
        </p>
        <p>
What are results of the run of such program?
</p>
        <ol>
          <li>
Full success! It works with high quality of recognition. Indeed, there is no any physical
noise that impacts quality.</li>
          <li>
Slow speed - up to several seconds per recognition per page.</li>
          <li>
Scalable solution. Slow speed can be compensated by almost unlimited theoretical scalability.</li>
        </ol>
        <p>
        </p>
        <p>
So, what is the lesson we have taked from this experience?
</p>
        <p>
        </p>
        <p>
Well, you should question yourself, test and verify ideas on the ground before building
any theories that will lead you in completely wrong direction. After all people started
to realize there was no need to claim on SharePoint, to throw it, and to spend great
deal of time and money just to prove that the problem is in the different place.
</p>
        <p>
A sample source code can be found at <a href="https://github.com/nesterovsky-bros/pdf.ocr/blob/master/src/main/java/nesterovskyBros/pdf/ocr/App.java" target="_blank">App.java</a></p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=861382a1-a2b8-4b39-a9f4-1f7a2148bf59" />
      </body>
      <title>Theory vs practice</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,861382a1-a2b8-4b39-a9f4-1f7a2148bf59.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2019/07/26/TheoryVsPractice.aspx</link>
      <pubDate>Fri, 26 Jul 2019 16:38:11 GMT</pubDate>
      <description>&lt;p&gt;
We were asked to help with search service in one enterprise. We were told that their
SharePoint portal does not serve their need. Main complaints were about the quality
of search results.
&lt;/p&gt;
&lt;p&gt;
They have decided to implement external index of SharePoint content, using &lt;a href="https://www.elastic.co/"&gt;Elastic&lt;/a&gt;,
and expose custom search API within the enterprise.
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
We questioned their conclusions, asked why did they think Elastic will give much better
results, asked did they try to figure out why SharePoint give no desired results.
&lt;/p&gt;
&lt;p&gt;
Answers did not convince us though we have joined the project.
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
What do you think? Elastic did not help at all though they hoped very much that its
query language will help to rank results in a way that matched documents will be found.
After all they thought it was a problem of ranking of results.
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Here we have started our analysis. We took a specific document that must be found
but is never returned from search.
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
It turned to be well known problem, at least we dealt with closely related one in
the past. There are two ingredients here:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
documents that have low chances to be found are PDFs;&lt;/li&gt;
&lt;li&gt;
we live in Israel, so most texts are Hebrew, which means words are written from right
to left, while some other texts from left to right. See &lt;a href="https://en.wikipedia.org/wiki/Bi-directional_text" target="_blank"&gt;Bi-directional
text&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Traditionally PDF documents are provided in a way that only distantly resembles logical
structure of original content. E.g., paragraphs of texts are often represented as
unrelated runs of text lines, or as set of text runs representing single words, or
independant characters. No need to say that additional complication comes from that
Hebrew text are often represented visually (from left to right, as if &amp;quot;hello&amp;quot;
would be stored as &amp;quot;olleh&amp;quot; and would be just printed from right to left).
Another common feature of PDF are custom fonts with uncanonical mappings, or images
with glyphs of letters.
&lt;/p&gt;
&lt;p&gt;
You can implement these tricks in other document formats but for some reason PDF is
only format we have seen that regularly and intensively uses these techniques.
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
At this point we have realized that it&amp;#39;s not a fault of a search engine to find
the document but the feature of the PDF to expose its text to a crawler in a form
that cannot be used for search. In fact, PDF cannot search by itself in such documents,
as when you try to find some text in the document opened in a pdf viewer, that you
clearly see in the document, you often find nothing.
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
A question. What should you do in this case when no any PDF text extractor can give
you correct text but text is there when you looking at document in a pdf viewer?
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
We decided it&amp;#39;s time to go in the direction of image recognition. Thankfully,
nowdays it&amp;#39;s a matter of available processing resources.
&lt;/p&gt;
&lt;p&gt;
Our goal was:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Have images of each PDF page. This task is immediately solved with &lt;a href="https://pdfbox.apache.org/" target="_blank"&gt;Apache
PDFBox (A Java PDF Library) - it's time to say this is java project.&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
Run Optical Character Recognition (OCR) over images, and get extracted texts. This
is perfectly done by &lt;a href="https://github.com/tesseract-ocr/tesseract" target="_blank"&gt;tesseract-ocr/tesseract&lt;/a&gt;,
and thankfully to its java wrapper &lt;a href="https://github.com/bytedeco/javacpp-presets/tree/master/tesseract" target="_blank"&gt;bytedeco/javacpp-presets&lt;/a&gt; we
can immediately call this C++ API from java.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
The only small nuisance of tesseract is that it does not expose table recognition
info, but we can easily overcome it (we solved this task in the past), as along with
each text run tesseract exposes its position.
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
What are results of the run of such program?
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Full success! It works with high quality of recognition. Indeed, there is no any physical
noise that impacts quality.&lt;/li&gt;
&lt;li&gt;
Slow speed - up to several seconds per recognition per page.&lt;/li&gt;
&lt;li&gt;
Scalable solution. Slow speed can be compensated by almost unlimited theoretical scalability.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
So, what is the lesson we have taked from this experience?
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Well, you should question yourself, test and verify ideas on the ground before building
any theories that will lead you in completely wrong direction. After all people started
to realize there was no need to claim on SharePoint, to throw it, and to spend great
deal of time and money just to prove that the problem is in the different place.
&lt;/p&gt;
&lt;p&gt;
A sample source code can be found at &lt;a href="https://github.com/nesterovsky-bros/pdf.ocr/blob/master/src/main/java/nesterovskyBros/pdf/ocr/App.java" target="_blank"&gt;App.java&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=861382a1-a2b8-4b39-a9f4-1f7a2148bf59" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,861382a1-a2b8-4b39-a9f4-1f7a2148bf59.aspx</comments>
      <category>C++</category>
      <category>Java</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=6b76a0f7-4eee-4023-8f67-781c38550685</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,6b76a0f7-4eee-4023-8f67-781c38550685.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=6b76a0f7-4eee-4023-8f67-781c38550685</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
This story started half year ago when Michael Kay, author of Saxon XSLT processor,
was dealing with performance in multithreaded environment. See <a href="https://saxonica.plan.io/issues/3958">Bug
#3958</a>.
</p>
        <p>
The problem is like this.
</p>
        <p>
Given XSLT:
</p>
        <blockquote>
          <pre>&lt;xsl:stylesheet exclude-result-prefixes="#all" 
  version="3.0" 
  xmlns:saxon="http://saxon.sf.net/"
  xmlns:xs="http://www.w3.org/2001/XMLSchema" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;

  &lt;xsl:output method="text" /&gt;

  &lt;xsl:template name="main"&gt;
    &lt;xsl:for-each saxon:threads="4" select="1 to 10"&gt;
      &lt;xsl:choose&gt;
        &lt;xsl:when test=". eq 1"&gt;
          &lt;!-- Will take 10 seconds --&gt;
          &lt;xsl:sequence select="
            json-doc('https://httpbin.org/delay/10')?url"/&gt;
        &lt;/xsl:when&gt;
        &lt;xsl:when test=". eq 5"&gt;
          &lt;!-- Will take 9 seconds --&gt;
          &lt;xsl:sequence select="
            json-doc('https://httpbin.org/delay/9')?url"/&gt;
        &lt;/xsl:when&gt;
        &lt;xsl:when test=". eq 10"&gt;
          &lt;!-- Will take 8 seconds --&gt;
          &lt;xsl:sequence select="
            json-doc('https://httpbin.org/delay/8')?url"/&gt;
        &lt;/xsl:when&gt;
      &lt;/xsl:choose&gt;
    &lt;/xsl:for-each&gt;
    &lt;xsl:text&gt;
&lt;/xsl:text&gt;
  &lt;/xsl:template&gt;
&lt;/xsl:stylesheet&gt;</pre>
        </blockquote>
        <p>
Implement engine to achieve best performance of parallel for-each. 
</p>
        <p>
Naive implementation that will distribute iterations per threads will run into unfair
load on threads, so some load-balancing is required. That was the case Saxon EE. 
</p>
        <p>
Michael Kay has been trying to find most elegant way for the implementation and has
written the comment: 
</p>
        <blockquote>
          <i>I can't help feeling that the answer to this must lie in using the
Streams machinery, and Spliterators in particular. I've spent another hour or so reading
all about Spliterators, and I have to confess I really don't understand the paradigm.
If someone can enlighten me, please go ahead...</i>
        </blockquote>
        <p>
We have decided to take the challange and to model the expected behavior using Streams.
Here is our go: 
</p>
        <blockquote>
          <pre>import java.util.stream.IntStream;
import java.util.stream.Stream;
import java.util.function.Consumer;
import java.util.function.Function;

public class Streams
{
  public static class Item&lt;T&gt;
  {
    public Item(int index, T data)
    {
      this.index = index;
      this.data = data;
    }
    
    int index;
    T data;
  }

  public static void main(String[] args)
  {
    run(
      "Sequential",
      input(),
      Streams::action,
      Streams::output,
      true);
    
    run(
      "Parallel ordered", 
      input().parallel(),
      Streams::action,
      Streams::output,
      true);
    
    run(
      "Parallel unordered", 
      input().parallel(),
      Streams::action,
      Streams::output,
      false);    
  }
  
  private static void run(
    String description,
    Stream&lt;Item&lt;String&gt;&gt; input,
    Function&lt;Item&lt;String&gt;, String[]&gt; action,
    Consumer&lt;String[]&gt; output,
    boolean ordered)
  {
    System.out.println(description);
    
    long start = System.currentTimeMillis();
   
    if (ordered)
    {
      input.map(action).forEachOrdered(output);
    }
    else
    {
      input.map(action).forEach(output);
    }
    
    long end = System.currentTimeMillis();
    
    System.out.println("Execution time: " + (end - start) + "ms.");
    System.out.println();
  }
  
  private static Stream&lt;Item&lt;String&gt;&gt; input()
  {
    return IntStream.range(0, 10).
      mapToObj(i -&gt; new Item&lt;String&gt;(i + 1, "Data " + (i + 1)));
  }
  
  private static String[] action(Item&lt;String&gt; item)
  {
    switch(item.index)
    {
      case 1:
      {
        sleep(10);
        
        break;
      }
      case 5:
      {
        sleep(9);
        
        break;
      }
      case 10:
      {
        sleep(8);
        
        break;
      }
      default:
      {
        sleep(1);
        
        break;
      }
    }
    
    String[] result = { "data:", item.data, "index:", item.index + "" };
    
    return result;
  }
  
  private synchronized static void output(String[] value)
  {
    boolean first = true;
    
    for(String item: value)
    {
      if (first)
      {
        first = false;
      }
      else
      {
        System.out.print(' ');
      }
    
      System.out.print(item);
    }

    System.out.println();
  }
  
  private static void sleep(int seconds)
  {
    try
    {
      Thread.sleep(seconds * 1000);
    }
    catch(InterruptedException e)
    {
      throw new IllegalStateException(e);
    }
  }
}</pre>
        </blockquote>
        <p>
We model three cases:
</p>
        <dl>
          <dt>"Sequential"</dt>
          <dd>
slowest, single threaded execution with output: <pre>data: Data 1 index: 1
data: Data 2 index: 2
data: Data 3 index: 3
data: Data 4 index: 4
data: Data 5 index: 5
data: Data 6 index: 6
data: Data 7 index: 7
data: Data 8 index: 8
data: Data 9 index: 9
data: Data 10 index: 10
Execution time: 34009ms.</pre></dd>
          <dt>"Parallel ordered"</dt>
          <dd>
fast, multithread execution preserving order, with output: <pre>data: Data 1 index: 1
data: Data 2 index: 2
data: Data 3 index: 3
data: Data 4 index: 4
data: Data 5 index: 5
data: Data 6 index: 6
data: Data 7 index: 7
data: Data 8 index: 8
data: Data 9 index: 9
data: Data 10 index: 10
Execution time: 10019ms.</pre></dd>
          <dt>"Parallel unordered"</dt>
          <dd>
fastest, multithread execution not preserving order, with output: <pre>data: Data 6 index: 6
data: Data 2 index: 2
data: Data 4 index: 4
data: Data 3 index: 3
data: Data 9 index: 9
data: Data 7 index: 7
data: Data 8 index: 8
data: Data 5 index: 5
data: Data 10 index: 10
data: Data 1 index: 1
Execution time: 10001ms.</pre></dd>
        </dl>
        <p>
What we can add in conclusion is that xslt engine could try automatically decide what
approach to use, as many SQL engines are doing, and not to force developer to go into
low level engine details.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=6b76a0f7-4eee-4023-8f67-781c38550685" />
      </body>
      <title>Scheduling algorithm for xsl:for-each/@saxon:threads=N</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,6b76a0f7-4eee-4023-8f67-781c38550685.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2019/03/24/SchedulingAlgorithmForXslforeachsaxonthreadsN.aspx</link>
      <pubDate>Sun, 24 Mar 2019 07:52:02 GMT</pubDate>
      <description>&lt;p&gt;
This story started half year ago when Michael Kay, author of Saxon XSLT processor,
was dealing with performance in multithreaded environment. See &lt;a href="https://saxonica.plan.io/issues/3958"&gt;Bug
#3958&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
The problem is like this.
&lt;/p&gt;
&lt;p&gt;
Given XSLT:
&lt;/p&gt;
&lt;blockquote&gt; &lt;pre&gt;&amp;lt;xsl:stylesheet exclude-result-prefixes="#all" 
  version="3.0" 
  xmlns:saxon="http://saxon.sf.net/"
  xmlns:xs="http://www.w3.org/2001/XMLSchema" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;

  &amp;lt;xsl:output method="text" /&gt;

  &amp;lt;xsl:template name="main"&gt;
    &amp;lt;xsl:for-each saxon:threads="4" select="1 to 10"&gt;
      &amp;lt;xsl:choose&gt;
        &amp;lt;xsl:when test=". eq 1"&gt;
          &amp;lt;!-- Will take 10 seconds --&gt;
          &amp;lt;xsl:sequence select="
            json-doc('https://httpbin.org/delay/10')?url"/&gt;
        &amp;lt;/xsl:when&gt;
        &amp;lt;xsl:when test=". eq 5"&gt;
          &amp;lt;!-- Will take 9 seconds --&gt;
          &amp;lt;xsl:sequence select="
            json-doc('https://httpbin.org/delay/9')?url"/&gt;
        &amp;lt;/xsl:when&gt;
        &amp;lt;xsl:when test=". eq 10"&gt;
          &amp;lt;!-- Will take 8 seconds --&gt;
          &amp;lt;xsl:sequence select="
            json-doc('https://httpbin.org/delay/8')?url"/&gt;
        &amp;lt;/xsl:when&gt;
      &amp;lt;/xsl:choose&gt;
    &amp;lt;/xsl:for-each&gt;
    &amp;lt;xsl:text&gt;&amp;#x0A;&amp;lt;/xsl:text&gt;
  &amp;lt;/xsl:template&gt;
&amp;lt;/xsl:stylesheet&gt;&lt;/pre&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Implement engine to achieve best performance of parallel for-each. 
&lt;/p&gt;
&lt;p&gt;
Naive implementation that will distribute iterations per threads will run into unfair
load on threads, so some load-balancing is required. That was the case Saxon EE. 
&lt;/p&gt;
&lt;p&gt;
Michael Kay has been trying to find most elegant way for the implementation and has
written the comment: 
&lt;/p&gt;
&lt;blockquote&gt; &lt;i&gt;I can't help feeling that the answer to this must lie in using the
Streams machinery, and Spliterators in particular. I've spent another hour or so reading
all about Spliterators, and I have to confess I really don't understand the paradigm.
If someone can enlighten me, please go ahead...&lt;/i&gt; &lt;/blockquote&gt; 
&lt;p&gt;
We have decided to take the challange and to model the expected behavior using Streams.
Here is our go: 
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;import java.util.stream.IntStream;
import java.util.stream.Stream;
import java.util.function.Consumer;
import java.util.function.Function;

public class Streams
{
  public static class Item&amp;lt;T&gt;
  {
    public Item(int index, T data)
    {
      this.index = index;
      this.data = data;
    }
    
    int index;
    T data;
  }

  public static void main(String[] args)
  {
    run(
      "Sequential",
      input(),
      Streams::action,
      Streams::output,
      true);
    
    run(
      "Parallel ordered", 
      input().parallel(),
      Streams::action,
      Streams::output,
      true);
    
    run(
      "Parallel unordered", 
      input().parallel(),
      Streams::action,
      Streams::output,
      false);    
  }
  
  private static void run(
    String description,
    Stream&amp;lt;Item&amp;lt;String&gt;&gt; input,
    Function&amp;lt;Item&amp;lt;String&gt;, String[]&gt; action,
    Consumer&amp;lt;String[]&gt; output,
    boolean ordered)
  {
    System.out.println(description);
    
    long start = System.currentTimeMillis();
   
    if (ordered)
    {
      input.map(action).forEachOrdered(output);
    }
    else
    {
      input.map(action).forEach(output);
    }
    
    long end = System.currentTimeMillis();
    
    System.out.println("Execution time: " + (end - start) + "ms.");
    System.out.println();
  }
  
  private static Stream&amp;lt;Item&amp;lt;String&gt;&gt; input()
  {
    return IntStream.range(0, 10).
      mapToObj(i -&gt; new Item&amp;lt;String&gt;(i + 1, "Data " + (i + 1)));
  }
  
  private static String[] action(Item&amp;lt;String&gt; item)
  {
    switch(item.index)
    {
      case 1:
      {
        sleep(10);
        
        break;
      }
      case 5:
      {
        sleep(9);
        
        break;
      }
      case 10:
      {
        sleep(8);
        
        break;
      }
      default:
      {
        sleep(1);
        
        break;
      }
    }
    
    String[] result = { "data:", item.data, "index:", item.index + "" };
    
    return result;
  }
  
  private synchronized static void output(String[] value)
  {
    boolean first = true;
    
    for(String item: value)
    {
      if (first)
      {
        first = false;
      }
      else
      {
        System.out.print(' ');
      }
    
      System.out.print(item);
    }

    System.out.println();
  }
  
  private static void sleep(int seconds)
  {
    try
    {
      Thread.sleep(seconds * 1000);
    }
    catch(InterruptedException e)
    {
      throw new IllegalStateException(e);
    }
  }
}&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
We model three cases:
&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;"Sequential"&lt;/dt&gt; 
&lt;dd&gt;
slowest, single threaded execution with output: &lt;pre&gt;data: Data 1 index: 1
data: Data 2 index: 2
data: Data 3 index: 3
data: Data 4 index: 4
data: Data 5 index: 5
data: Data 6 index: 6
data: Data 7 index: 7
data: Data 8 index: 8
data: Data 9 index: 9
data: Data 10 index: 10
Execution time: 34009ms.&lt;/pre&gt;
&lt;/dd&gt;
&lt;dt&gt;"Parallel ordered"&lt;/dt&gt; 
&lt;dd&gt;
fast, multithread execution preserving order, with output: &lt;pre&gt;data: Data 1 index: 1
data: Data 2 index: 2
data: Data 3 index: 3
data: Data 4 index: 4
data: Data 5 index: 5
data: Data 6 index: 6
data: Data 7 index: 7
data: Data 8 index: 8
data: Data 9 index: 9
data: Data 10 index: 10
Execution time: 10019ms.&lt;/pre&gt;
&lt;/dd&gt;
&lt;dt&gt;"Parallel unordered"&lt;/dt&gt; 
&lt;dd&gt;
fastest, multithread execution not preserving order, with output: &lt;pre&gt;data: Data 6 index: 6
data: Data 2 index: 2
data: Data 4 index: 4
data: Data 3 index: 3
data: Data 9 index: 9
data: Data 7 index: 7
data: Data 8 index: 8
data: Data 5 index: 5
data: Data 10 index: 10
data: Data 1 index: 1
Execution time: 10001ms.&lt;/pre&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;
What we can add in conclusion is that xslt engine could try automatically decide what
approach to use, as many SQL engines are doing, and not to force developer to go into
low level engine details.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=6b76a0f7-4eee-4023-8f67-781c38550685" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,6b76a0f7-4eee-4023-8f67-781c38550685.aspx</comments>
      <category>Java</category>
      <category>Thinking aloud</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=7916d7f6-9228-48f2-9b06-d2646328ec33</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,7916d7f6-9228-48f2-9b06-d2646328ec33.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=7916d7f6-9228-48f2-9b06-d2646328ec33</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Recently we observed how we solved the same task in different versions of XPath: 2.0,
3.0, and 3.1.
</p>
        <p>
Consider, you have a sequence <code>$items</code>, and you want to call some function
over each item of the sequence, and to return combined result.
</p>
        <p>
In XPath 2.0 this was solved like this:
</p>
        <blockquote>
          <pre>for $item in $items return
  f:func($item)</pre>
        </blockquote>
        <p>
In XPath 3.0 this was solved like this:
</p>
        <blockquote>
          <pre>$items!f:func(.)</pre>
        </blockquote>
        <p>
And now with XPath 3.1 that defined an arrow operator =&gt; we attempted to write something
as simple as:
</p>
        <blockquote>
          <pre>$items=&gt;f:func()</pre>
        </blockquote>
        <p>
That is definitely not working, as it is the same as <code>f:func($items)</code>.
</p>
        <p>
Next attempt was:
</p>
        <blockquote>
          <pre>$items!=&gt;f:func()</pre>
        </blockquote>
        <p>
That even does not compile.
</p>
        <p>
So, finally, working expression using =&gt; looks like this:
</p>
        <blockquote>
          <pre>$items!(.=&gt;f:func())</pre>
        </blockquote>
        <p>
This looks like a step back comparing to XPath 3.0 variant.
</p>
        <p>
More than that, XPath grammar of arrow operator forbids the use of predictes, axis
or mapping operators, so this won't compile:
</p>
        <blockquote>
          <pre>$items!(.=&gt;f:func()[1])</pre>
        </blockquote>
        <blockquote>
          <pre>$items!(.=&gt;f:func()!something)</pre>
        </blockquote>
        <p>
Our conclusion is that arrow operator is rather confusing addition to XPath.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=7916d7f6-9228-48f2-9b06-d2646328ec33" />
      </body>
      <title>XPath through evolution</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,7916d7f6-9228-48f2-9b06-d2646328ec33.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2018/11/03/XPathThroughEvolution.aspx</link>
      <pubDate>Sat, 03 Nov 2018 20:59:28 GMT</pubDate>
      <description>  &lt;p&gt;
Recently we observed how we solved the same task in different versions of XPath: 2.0,
3.0, and 3.1.
&lt;/p&gt;
&lt;p&gt;
Consider, you have a sequence &lt;code&gt;$items&lt;/code&gt;, and you want to call some function
over each item of the sequence, and to return combined result.
&lt;/p&gt;
&lt;p&gt;
In XPath 2.0 this was solved like this:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;for $item in $items return
  f:func($item)&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
In XPath 3.0 this was solved like this:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;$items!f:func(.)&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
And now with XPath 3.1 that defined an arrow operator =&gt; we attempted to write something
as simple as:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;$items=&gt;f:func()&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
That is definitely not working, as it is the same as &lt;code&gt;f:func($items)&lt;/code&gt;.
&lt;/p&gt;
&lt;p&gt;
Next attempt was:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;$items!=&gt;f:func()&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
That even does not compile.
&lt;/p&gt;
&lt;p&gt;
So, finally, working expression using =&gt; looks like this:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;$items!(.=&gt;f:func())&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
This looks like a step back comparing to XPath 3.0 variant.
&lt;/p&gt;
&lt;p&gt;
More than that, XPath grammar of arrow operator forbids the use of predictes, axis
or mapping operators, so this won't compile:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;$items!(.=&gt;f:func()[1])&lt;/pre&gt;&lt;/blockquote&gt; &lt;blockquote&gt;&lt;pre&gt;$items!(.=&gt;f:func()!something)&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
Our conclusion is that arrow operator is rather confusing addition to XPath.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=7916d7f6-9228-48f2-9b06-d2646328ec33" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,7916d7f6-9228-48f2-9b06-d2646328ec33.aspx</comments>
      <category>Thinking aloud</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=2b29772d-bded-4045-b6b8-d0035cb5944f</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,2b29772d-bded-4045-b6b8-d0035cb5944f.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=2b29772d-bded-4045-b6b8-d0035cb5944f</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Xslt 3.0 defines a feature called streamability: a technique to write xslt code that
is able to handle arbitrary sized inputs. 
</p>
        <p>
This contrasts with conventional xslt code (and xslt engines) where inputs are completely
loaded in memory.
</p>
        <p>
To make code streamable a developer should declare her code as such, and the code
should pass <a href="https://www.w3.org/TR/xslt-30/#streamability">Streamability analysis</a>.
</p>
        <p>
The goal is to define subset of xslt/xpath operations that allow to process input
in one pass.
</p>
        <p>
In simple case it's indeed a simple task to verify that code is streamable, but
the more complex your code is the less trivial it's to witness it is streamable.
</p>
        <p>
On the forums we have seen a lot of discussions, where experts were trying to figure
out whether particular xslt is streamable. At times it's remarkably untrivial
task!
</p>
        <p>
This, in our opinion, clearly manifests that the feature is largerly failed attempt
to inscribe some optimization technique into xslt spec.
</p>
        <p>
The place of such optimization is in the implementation space, and not in spec. Engine
had to attempt such optimization and fallback to the traditional implementation.
</p>
        <p>
The last such example is: <a href="https://saxonica.plan.io/boards/3/topics/7319">Getting
SXST0060 "No streamable path found in expression" when trying to push a
map with grounded nodes to a template of a streamable mode</a>, where both xslt code
and engine developers are not sure that the code is streamable in the first place.
</p>
        <p>
        </p>
        <p>
By the way, besides streamability there is other optimization technique that works
probably in all SQL engines. When data does not fit into memory engine may spill it
on disk. Thus trading memory pressure for disk access. So, why didn't such techninque
find the way into the Xslt or SQL specs?
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=2b29772d-bded-4045-b6b8-d0035cb5944f" />
      </body>
      <title>Xslt Streamability</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,2b29772d-bded-4045-b6b8-d0035cb5944f.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2018/10/02/XsltStreamability.aspx</link>
      <pubDate>Tue, 02 Oct 2018 12:50:22 GMT</pubDate>
      <description>  &lt;p&gt;
Xslt 3.0 defines a feature called streamability: a technique to write xslt code that
is able to handle arbitrary sized inputs. 
&lt;/p&gt;
&lt;p&gt;
This contrasts with conventional xslt code (and xslt engines) where inputs are completely
loaded in memory.
&lt;/p&gt;
&lt;p&gt;
To make code streamable a developer should declare her code as such, and the code
should pass &lt;a href="https://www.w3.org/TR/xslt-30/#streamability"&gt;Streamability analysis&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
The goal is to define subset of xslt/xpath operations that allow to process input
in one pass.
&lt;/p&gt;
&lt;p&gt;
In simple case it&amp;#39;s indeed a simple task to verify that code is streamable, but
the more complex your code is the less trivial it&amp;#39;s to witness it is streamable.
&lt;/p&gt;
&lt;p&gt;
On the forums we have seen a lot of discussions, where experts were trying to figure
out whether particular xslt is streamable. At times it&amp;#39;s remarkably untrivial
task!
&lt;/p&gt;
&lt;p&gt;
This, in our opinion, clearly manifests that the feature is largerly failed attempt
to inscribe some optimization technique into xslt spec.
&lt;/p&gt;
&lt;p&gt;
The place of such optimization is in the implementation space, and not in spec. Engine
had to attempt such optimization and fallback to the traditional implementation.
&lt;/p&gt;
&lt;p&gt;
The last such example is: &lt;a href="https://saxonica.plan.io/boards/3/topics/7319"&gt;Getting
SXST0060 &amp;quot;No streamable path found in expression&amp;quot; when trying to push a
map with grounded nodes to a template of a streamable mode&lt;/a&gt;, where both xslt code
and engine developers are not sure that the code is streamable in the first place.
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
By the way, besides streamability there is other optimization technique that works
probably in all SQL engines. When data does not fit into memory engine may spill it
on disk. Thus trading memory pressure for disk access. So, why didn&amp;#39;t such techninque
find the way into the Xslt or SQL specs?
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=2b29772d-bded-4045-b6b8-d0035cb5944f" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,2b29772d-bded-4045-b6b8-d0035cb5944f.aspx</comments>
      <category>Thinking aloud</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=8dcc4028-a6ff-48c9-99e2-72229895c1fb</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,8dcc4028-a6ff-48c9-99e2-72229895c1fb.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=8dcc4028-a6ff-48c9-99e2-72229895c1fb</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
For more than 25 years continues a discussion in C++ community about exceptions. In
our opinion this can only be compared with math community and their open problems
like <a href="https://en.wikipedia.org/wiki/Hilbert's_problems">Hilbert's 23 problems</a> dated
by 1900.
</p>
        <p>
In essence C++ exception discussion is about efficiency of exceptions vs status codes.
This problem is not so acute in other languages (like java or C#) because those languages
postulate different goals. 
</p>
        <p>
C++ designers have introduced a zero-overhead principle for any language feature,
which is:
</p>
        <ol>
          <li>
If you don’t use some feature you don’t pay for it.</li>
          <li>
If you do use it you cannot (reasonably) write it more efficiently by hand. 
</li>
        </ol>
        <p>
Exceptions comparing to status codes do not withstand this demand. This led to the
fragmentation of C++ comunity where many big projects and code styles ban exceptions
partially or completely.
</p>
        <p>
Make no doubt that all this time people were trying to make exceptions better, and
have found techniques to make them space and run time efficient to some extent, but
still, old plain status codes outperform both in speed (especially in predictability
of time of exception handling logic) and in code size. 
</p>
        <p>
We guess the solution is finally found after the quarter the century of discussion!
</p>
        <p>
WG paper: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0709r1.pdf">Zero-overhead
deterministic exceptions: Throwing values</a> by Herb Sutter. This "<i>paper
aims to extend C++’s exception model to let functions declare that they throw a statically
specified type by value. This lets the exception handling implementation be exactly
as efficient and deterministic as a local return by value, with zero dynamic or non-local
overheads.</i>"
</p>
        <p>
In other words author suggests to:
</p>
        <ul>
          <li>
extend exception model (in fact implement additional one);</li>
          <li>
make exceptions as fast and as predicable as status codes (which virtually means designate
a status code as a new exception);</li>
        </ul>
        <p>
 
</p>
        <p>
Here are author's arguments:
</p>
        <ol>
          <li>
Status code is usually just a number, and handling an error is like to perform some <code>if</code> or <code>switch</code> statements.</li>
          <li>
Handling errors with status codes is predicable in time and visible in the code though
it burdens the logic very much.</li>
          <li>
Exceptions give clear separation between a control flow and error handling.</li>
          <li>
Exceptions are mostly invisible in the code, so it's not always clear how much
they add to code size and how they impact performance.</li>
          <li>
Statistics show that exceptions add 15 to 30% to size of code, even if no exceptions
are used (violation of zero-overhead principle);</li>
          <li>
Exceptions require Run Time Type Information about types, and have no predictable
memory (stack or heap) footprint  (violation of zero-overhead principle).</li>
        </ol>
        <p>
 
</p>
        <p>
What aurhor suggests might seem too radical but at present it's only viable solution
to reestablish zero-verhead principle and to reunite two C++ camps.
</p>
        <p>
Here is the approach.
</p>
        <ol>
          <li>
Clarify what should be considered as an exception. 
<ol><li>
Contract violation. 
<p>
Are contract violation like invalid values of arguments or invalid post conditions
(unhold invariants) are exceptions or programmer's bugs?
</p><p>
If later then it's best to terminate, as you cannot correctly recover from bug.
</p></li><li>
Virtual Machine fault. 
<p>
What user program can do with stack overflow?
</p><p>
The best according to the author it to terminate.
</p></li><li>
OOM - Out Of Memory error. 
<p>
What is the best way to deal with OOM dyring dynamic allocation.
</p><p>
At present there are two operators:
</p><ul><li><code>new</code> - to allocate memory dynamically and throw <code>bad_alloc</code> on
failure.</li><li><code>new(nothrow)</code> - to allocate memory dynamically and return <code>nullptr</code> on
failure.</li></ul><p>
Herb Sutter suggests to change <code>new</code> behavior to terminate on failure (it
is very hard to properly handle <code>bad_alloc</code> anyway), while <code>new(nothrow)</code> will
still allow to build code that can deal with OOM.
</p></li><li>
Partial success 
<p>
This should never be reported as an error, and status codes should be used to report
the state.
</p></li><li>
Error condition distinct from any type of success. 
<p>
This is where exceptions should be used.
</p></li></ol><p>
Statistics shows that with such separation more than 90% of what curently is an exception
will not be exception any more, so no any hidden exception logic is required: program
either works or terminates.
</p></li>
          <li>
Refactor exception 
<p>
Redefine what exception object is and how it is propagated.
</p><p>
It should be thin value type. At minimum it needs to contain an error code. Suggested
size is up to a couple of pointers.
</p><p>
Compiler should be able to cheaply allocate and copy it on the stack or even in the
processor's registers.
</p><p>
Such simple exception type resolves problems with lifetime of exception object, and
makes exception handling as light as checking status codes.
</p><p>
Exception should be propagated through return chanel, so it's like a new calling
convention that defines either function result or error outcome.
</p></li>
        </ol>
        <p>
        </p>
        <p>
It's not our intention to quote whole the paper here. If you're interested then please
read it. Here we want to outline our concerns.
</p>
        <ol>
          <li>
Exception payload. 
<p>
This paper emphasizes that exception type should be small.
</p><p>
So, what to do with exception payload, if any (at least error message if it's
not a static text)?
</p><p>
If this won't be resolved then developers will start to invent custom mechanisms
like GetLastErrorMessage().
</p><p>
And what to do with aggregate exceptions?
</p><p>
We think this must be clearly addressed.
</p></li>
          <li>
Implemntation shift. 
<p>
We can accept that most of the current exceptions will terminate.
</p><p>
But consider now some container that serves requests, like web container or database.
</p><p>
It may be built from multiple components and serve multiple requests concurently.
If one request will terminate we don't want for container to terminate.
</p><p>
If terminate handler is called then we cannot rely on state of the application. At
least we can expect heap leaks and un-released resources.
</p><p>
So, we either want to be able release heap and other resources per request, or we
want to go down with whole process and let OS deal with it.
</p><p>
In the later case we need to design such containers differently: as a set of cooperative
processes; OS should allow to spin processes more easily.
</p></li>
          <li>
VM with exceptions 
<p>
There are Virtual Machines that allow exception to be thrown on each instruction (like
JVM, or CLI).
</p><p>
You cannot tell in this case that code would never throw exception, as it can out
of the blue!
</p><p>
Event in x86 you can have PAGE FAULT on memory access, which can be translated into
an exception.
</p><p>
So, it's still a question whether the terminate() solution is sound in every case,
and whether compiler can optimize out exception handling if it proves staticlly that
no exception should be thrown.
</p></li>
        </ol>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=8dcc4028-a6ff-48c9-99e2-72229895c1fb" />
      </body>
      <title>C++ Exceptions</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,8dcc4028-a6ff-48c9-99e2-72229895c1fb.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2018/08/06/CExceptions.aspx</link>
      <pubDate>Mon, 06 Aug 2018 12:00:10 GMT</pubDate>
      <description>  &lt;p&gt;
For more than 25 years continues a discussion in C++ community about exceptions. In
our opinion this can only be compared with math community and their open problems
like &lt;a href="https://en.wikipedia.org/wiki/Hilbert's_problems"&gt;Hilbert&amp;#39;s 23 problems&lt;/a&gt; dated
by 1900.
&lt;/p&gt;
&lt;p&gt;
In essence C++ exception discussion is about efficiency of exceptions vs status codes.
This problem is not so acute in other languages (like java or C#) because those languages
postulate different goals. 
&lt;/p&gt;
&lt;p&gt;
C++ designers have introduced a zero-overhead principle for any language feature,
which is:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
If you don’t use some feature you don’t pay for it.&lt;/li&gt;
&lt;li&gt;
If you do use it you cannot (reasonably) write it more efficiently by hand. 
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Exceptions comparing to status codes do not withstand this demand. This led to the
fragmentation of C++ comunity where many big projects and code styles ban exceptions
partially or completely.
&lt;/p&gt;
&lt;p&gt;
Make no doubt that all this time people were trying to make exceptions better, and
have found techniques to make them space and run time efficient to some extent, but
still, old plain status codes outperform both in speed (especially in predictability
of time of exception handling logic) and in code size. 
&lt;/p&gt;
&lt;p&gt;
We guess the solution is finally found after the quarter the century of discussion!
&lt;/p&gt;
&lt;p&gt;
WG paper: &lt;a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0709r1.pdf"&gt;Zero-overhead
deterministic exceptions: Throwing values&lt;/a&gt; by Herb Sutter. This &amp;quot;&lt;i&gt;paper
aims to extend C++’s exception model to let functions declare that they throw a statically
specified type by value. This lets the exception handling implementation be exactly
as efficient and deterministic as a local return by value, with zero dynamic or non-local
overheads.&lt;/i&gt;&amp;quot;
&lt;/p&gt;
&lt;p&gt;
In other words author suggests to:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
extend exception model (in fact implement additional one);&lt;/li&gt;
&lt;li&gt;
make exceptions as fast and as predicable as status codes (which virtually means designate
a status code as a new exception);&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Here are author&amp;#39;s arguments:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Status code is usually just a number, and handling an error is like to perform some &lt;code&gt;if&lt;/code&gt; or &lt;code&gt;switch&lt;/code&gt; statements.&lt;/li&gt;
&lt;li&gt;
Handling errors with status codes is predicable in time and visible in the code though
it burdens the logic very much.&lt;/li&gt;
&lt;li&gt;
Exceptions give clear separation between a control flow and error handling.&lt;/li&gt;
&lt;li&gt;
Exceptions are mostly invisible in the code, so it&amp;#39;s not always clear how much
they add to code size and how they impact performance.&lt;/li&gt;
&lt;li&gt;
Statistics show that exceptions add 15 to 30% to size of code, even if no exceptions
are used (violation of zero-overhead principle);&lt;/li&gt;
&lt;li&gt;
Exceptions require Run Time Type Information about types, and have no predictable
memory (stack or heap) footprint&amp;nbsp; (violation of zero-overhead principle).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
What aurhor suggests might seem too radical but at present it&amp;#39;s only viable solution
to reestablish zero-verhead principle and to reunite two C++ camps.
&lt;/p&gt;
&lt;p&gt;
Here is the approach.
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Clarify what should be considered as an exception. 
&lt;ol&gt;
&lt;li&gt;
Contract violation. 
&lt;p&gt;
Are contract violation like invalid values of arguments or invalid post conditions
(unhold invariants) are exceptions or programmer&amp;#39;s bugs?
&lt;/p&gt;
&lt;p&gt;
If later then it&amp;#39;s best to terminate, as you cannot correctly recover from bug.
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
Virtual Machine fault. 
&lt;p&gt;
What user program can do with stack overflow?
&lt;/p&gt;
&lt;p&gt;
The best according to the author it to terminate.
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
OOM - Out Of Memory error. 
&lt;p&gt;
What is the best way to deal with OOM dyring dynamic allocation.
&lt;/p&gt;
&lt;p&gt;
At present there are two operators:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;new&lt;/code&gt; - to allocate memory dynamically and throw &lt;code&gt;bad_alloc&lt;/code&gt; on
failure.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;new(nothrow)&lt;/code&gt; - to allocate memory dynamically and return &lt;code&gt;nullptr&lt;/code&gt; on
failure.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Herb Sutter suggests to change &lt;code&gt;new&lt;/code&gt; behavior to terminate on failure (it
is very hard to properly handle &lt;code&gt;bad_alloc&lt;/code&gt; anyway), while &lt;code&gt;new(nothrow)&lt;/code&gt; will
still allow to build code that can deal with OOM.
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
Partial success 
&lt;p&gt;
This should never be reported as an error, and status codes should be used to report
the state.
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
Error condition distinct from any type of success. 
&lt;p&gt;
This is where exceptions should be used.
&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Statistics shows that with such separation more than 90% of what curently is an exception
will not be exception any more, so no any hidden exception logic is required: program
either works or terminates.
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
Refactor exception 
&lt;p&gt;
Redefine what exception object is and how it is propagated.
&lt;/p&gt;
&lt;p&gt;
It should be thin value type. At minimum it needs to contain an error code. Suggested
size is up to a couple of pointers.
&lt;/p&gt;
&lt;p&gt;
Compiler should be able to cheaply allocate and copy it on the stack or even in the
processor&amp;#39;s registers.
&lt;/p&gt;
&lt;p&gt;
Such simple exception type resolves problems with lifetime of exception object, and
makes exception handling as light as checking status codes.
&lt;/p&gt;
&lt;p&gt;
Exception should be propagated through return chanel, so it&amp;#39;s like a new calling
convention that defines either function result or error outcome.
&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
It's not our intention to quote whole the paper here. If you're interested then please
read it. Here we want to outline our concerns.
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Exception payload. 
&lt;p&gt;
This paper emphasizes that exception type should be small.
&lt;/p&gt;
&lt;p&gt;
So, what to do with exception payload, if any (at least error message if it&amp;#39;s
not a static text)?
&lt;/p&gt;
&lt;p&gt;
If this won&amp;#39;t be resolved then developers will start to invent custom mechanisms
like GetLastErrorMessage().
&lt;/p&gt;
&lt;p&gt;
And what to do with aggregate exceptions?
&lt;/p&gt;
&lt;p&gt;
We think this must be clearly addressed.
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
Implemntation shift. 
&lt;p&gt;
We can accept that most of the current exceptions will terminate.
&lt;/p&gt;
&lt;p&gt;
But consider now some container that serves requests, like web container or database.
&lt;/p&gt;
&lt;p&gt;
It may be built from multiple components and serve multiple requests concurently.
If one request will terminate we don&amp;#39;t want for container to terminate.
&lt;/p&gt;
&lt;p&gt;
If terminate handler is called then we cannot rely on state of the application. At
least we can expect heap leaks and un-released resources.
&lt;/p&gt;
&lt;p&gt;
So, we either want to be able release heap and other resources per request, or we
want to go down with whole process and let OS deal with it.
&lt;/p&gt;
&lt;p&gt;
In the later case we need to design such containers differently: as a set of cooperative
processes; OS should allow to spin processes more easily.
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
VM with exceptions 
&lt;p&gt;
There are Virtual Machines that allow exception to be thrown on each instruction (like
JVM, or CLI).
&lt;/p&gt;
&lt;p&gt;
You cannot tell in this case that code would never throw exception, as it can out
of the blue!
&lt;/p&gt;
&lt;p&gt;
Event in x86 you can have PAGE FAULT on memory access, which can be translated into
an exception.
&lt;/p&gt;
&lt;p&gt;
So, it&amp;#39;s still a question whether the terminate() solution is sound in every case,
and whether compiler can optimize out exception handling if it proves staticlly that
no exception should be thrown.
&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=8dcc4028-a6ff-48c9-99e2-72229895c1fb" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,8dcc4028-a6ff-48c9-99e2-72229895c1fb.aspx</comments>
      <category>C++</category>
      <category>Thinking aloud</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=1040b8e9-5dc4-4af2-a83a-3554ec8bb5b3</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,1040b8e9-5dc4-4af2-a83a-3554ec8bb5b3.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=1040b8e9-5dc4-4af2-a83a-3554ec8bb5b3</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
We often deal with different SQL DBs, and in particular DB2, Oracle, and SQL Server,
and this is what we have found lately.
</p>
        <p>
Our client has reported a problem with SQL insert into the DB2:
</p>
        <ul>
          <li>
subject table has a small number of columns, but large number of rows;</li>
          <li>
insert should attempt to insert a row but tolerate the duplicate.</li>
        </ul>
        <p>
The prototype table is like this:
</p>
        <blockquote>
          <pre>create table Link(FromID int, ToID int, primary key(FromID, ToID));</pre>
        </blockquote>
        <p>
DB2 SQL insert is like this:
</p>
        <blockquote>
          <pre>insert into Link(FromID, ToID)
values(1, 2)
except
select FromID, ToID from Link;</pre>
        </blockquote>
        <p>
The idea is to have empty row set to insert if there is a duplicate.
</p>
        <p>
SQL Server variant looks like this:
</p>
        <blockquote>
          <pre>insert into Link(FromID, ToID)
select 1, 2
except
select FromID, ToID from Link;</pre>
        </blockquote>
        <p>
Client reported ridiculously slow performance of this SQL, due to table scan to calculate
results of <code>except</code> operator.
</p>
        <p>
Out of interest we performed the same experiment with SQL Server, and found the execution
plan is optimal, and index seek is used to check duplicates. See:
</p>
        <img alt="Execution Plan" src="content/binary/SQLInsertExcept.png" style="width: 600px" />
        <p>
 
</p>
        <p>
The only reasonable way of dealing with such DB2's peculiarity, except trying
to insert and handle duplicate exception, was to qualify <code>select</code> with <code>where</code> clause:
</p>
        <blockquote>
          <pre>insert into Link(FromID, ToID)
values(1, 2)
except
select FromID, ToID from Link where FromID = 1 and ToID = 2;</pre>
        </blockquote>
        <p>
We think DB2 could do better.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=1040b8e9-5dc4-4af2-a83a-3554ec8bb5b3" />
      </body>
      <title>SQL Server vs DB2</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,1040b8e9-5dc4-4af2-a83a-3554ec8bb5b3.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2018/04/14/SQLServerVsDB2.aspx</link>
      <pubDate>Sat, 14 Apr 2018 19:38:20 GMT</pubDate>
      <description>&lt;p&gt;
We often deal with different SQL DBs, and in particular DB2, Oracle, and SQL Server,
and this is what we have found lately.
&lt;/p&gt;
&lt;p&gt;
Our client has reported a problem with SQL insert into the DB2:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
subject table has a small number of columns, but large number of rows;&lt;/li&gt;
&lt;li&gt;
insert should attempt to insert a row but tolerate the duplicate.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
The prototype table is like this:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;create table Link(FromID int, ToID int, primary key(FromID, ToID));&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
DB2 SQL insert is like this:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;insert into Link(FromID, ToID)
values(1, 2)
except
select FromID, ToID from Link;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
The idea is to have empty row set to insert if there is a duplicate.
&lt;/p&gt;
&lt;p&gt;
SQL Server variant looks like this:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;insert into Link(FromID, ToID)
select 1, 2
except
select FromID, ToID from Link;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
Client reported ridiculously slow performance of this SQL, due to table scan to calculate
results of &lt;code&gt;except&lt;/code&gt; operator.
&lt;/p&gt;
&lt;p&gt;
Out of interest we performed the same experiment with SQL Server, and found the execution
plan is optimal, and index seek is used to check duplicates. See:
&lt;/p&gt;
&lt;img alt="Execution Plan" src="content/binary/SQLInsertExcept.png" style="width: 600px" /&gt; 
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
The only reasonable way of dealing with such DB2&amp;#39;s peculiarity, except trying
to insert and handle duplicate exception, was to qualify &lt;code&gt;select&lt;/code&gt; with &lt;code&gt;where&lt;/code&gt; clause:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;insert into Link(FromID, ToID)
values(1, 2)
except
select FromID, ToID from Link where FromID = 1 and ToID = 2;&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
We think DB2 could do better.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=1040b8e9-5dc4-4af2-a83a-3554ec8bb5b3" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,1040b8e9-5dc4-4af2-a83a-3554ec8bb5b3.aspx</comments>
      <category>SQL Server puzzle</category>
      <category>Thinking aloud</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=9edf3c0e-34f1-4d4a-97ec-94922826204c</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,9edf3c0e-34f1-4d4a-97ec-94922826204c.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=9edf3c0e-34f1-4d4a-97ec-94922826204c</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Today we wanted to write some code in java that performs some or the other action
depending on a condition. At the same time if some action fails we wanted to fall
back to the other action.
</p>
        <p>
We've written it like this:
</p>
        <blockquote>
          <pre>
switch(boolean_expression)
{
  case true:
  {
    try
    {
      // Some actions.
      break;
    }
    catch(Exception e)
    {
      // Fall back to false route. 
    }
  }
  case false:
  {
    // Other actions.
    break;
  }
}
</pre>
        </blockquote>
        <p>
The fun part is that it's not valid java code.
</p>
        <p>
Why?
</p>
        <p>
The answer can be found in spec: <a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.11">14.11.
The <code>switch</code> Statement</a></p>
        <blockquote>
          <i> The type of the Expression must be <code>char</code>, <code>byte</code>, <code>short</code>, <code>int</code>, <code>Character</code>, <code>Byte</code>, <code>Short</code>, <code>Integer</code>, <code>String</code>,
or an enum type (<a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.9" title="8.9. Enums">§8.9</a>),
or a compile-time error occurs. </i>
        </blockquote>
        <p>
But why?
</p>
        <p>
Who knows...
</p>
        <p>
Sure there are workarounds, even with switch, but it just not justified restriction...
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=9edf3c0e-34f1-4d4a-97ec-94922826204c" />
      </body>
      <title>Some fun with java switch</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,9edf3c0e-34f1-4d4a-97ec-94922826204c.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2017/08/22/SomeFunWithJavaSwitch.aspx</link>
      <pubDate>Tue, 22 Aug 2017 15:18:29 GMT</pubDate>
      <description>  &lt;p&gt;
Today we wanted to write some code in java that performs some or the other action
depending on a condition. At the same time if some action fails we wanted to fall
back to the other action.
&lt;/p&gt;
&lt;p&gt;
We've written it like this:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;
switch(boolean_expression)
{
  case true:
  {
    try
    {
      // Some actions.
      break;
    }
    catch(Exception e)
    {
      // Fall back to false route. 
    }
  }
  case false:
  {
    // Other actions.
    break;
  }
}
&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
The fun part is that it&amp;#39;s not valid java code.
&lt;/p&gt;
&lt;p&gt;
Why?
&lt;/p&gt;
&lt;p&gt;
The answer can be found in spec: &lt;a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.11"&gt;14.11.
The &lt;code&gt;switch&lt;/code&gt; Statement&lt;/a&gt; 
&lt;/p&gt;
&lt;blockquote&gt;&lt;i&gt; The type of the Expression must be &lt;code&gt;char&lt;/code&gt;, &lt;code&gt;byte&lt;/code&gt;, &lt;code&gt;short&lt;/code&gt;, &lt;code&gt;int&lt;/code&gt;, &lt;code&gt;Character&lt;/code&gt;, &lt;code&gt;Byte&lt;/code&gt;, &lt;code&gt;Short&lt;/code&gt;, &lt;code&gt;Integer&lt;/code&gt;, &lt;code&gt;String&lt;/code&gt;,
or an enum type (&lt;a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.9" title="8.9. Enums"&gt;§8.9&lt;/a&gt;),
or a compile-time error occurs. &lt;/i&gt;&lt;/blockquote&gt; 
&lt;p&gt;
But why?
&lt;/p&gt;
&lt;p&gt;
Who knows...
&lt;/p&gt;
&lt;p&gt;
Sure there are workarounds, even with switch, but it just not justified restriction...
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=9edf3c0e-34f1-4d4a-97ec-94922826204c" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,9edf3c0e-34f1-4d4a-97ec-94922826204c.aspx</comments>
      <category>Java</category>
      <category>Thinking aloud</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=824d5dcd-a1a5-4314-b7fa-1e4447417c9f</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,824d5dcd-a1a5-4314-b7fa-1e4447417c9f.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=824d5dcd-a1a5-4314-b7fa-1e4447417c9f</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
We have found that Saxon HE 9.7.0-18 has finally exposed partial support to map and
array item types. So, now you can encapsulate your data in sequence rather than having
a single sequence and treating odd and even elements specially.
</p>
        <p>
Basic example is:
</p>
        <blockquote>
          <pre>&lt;xsl:stylesheet version="3.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:t="t"
  xmlns:map="http://www.w3.org/2005/xpath-functions/map"
  exclude-result-prefixes="xs t map"&gt;

  &lt;xsl:template match="/"&gt;
    &lt;xsl:variable name="map" as="map(xs:string, xs:string)" select="
      map 
      {
        'Su': 'Sunday',
        'Mo': 'Monday',
        'Tu': 'Tuesday',
        'We': 'Wednesday',
        'Th': 'Thursday',
        'Fr': 'Friday',
        'Sa': 'Saturday'
      }"/&gt;
      
     &lt;xsl:message select="map:keys($map)"/&gt;
  &lt;/xsl:template&gt;  

&lt;/xsl:stylesheet&gt;</pre>
        </blockquote>
        <p>
A list of map functions can be found here <a href="http://www.w3.org/2005/xpath-functions/map/">http://www.w3.org/2005/xpath-functions/map/</a>,
though not all are available, as Saxon HE still does not allow inline functions.
</p>
        <p>
P.S. From the development perspective it's a great harm that Saxon HE is so limited.
Basically limited to xslt 2.0 + some selected parts of 3.0.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=824d5dcd-a1a5-4314-b7fa-1e4447417c9f" />
      </body>
      <title>Saxon HE map and array types.</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,824d5dcd-a1a5-4314-b7fa-1e4447417c9f.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2017/05/16/SaxonHEMapAndArrayTypes.aspx</link>
      <pubDate>Tue, 16 May 2017 06:20:48 GMT</pubDate>
      <description>  &lt;p&gt;
We have found that Saxon HE 9.7.0-18 has finally exposed partial support to map and
array item types. So, now you can encapsulate your data in sequence rather than having
a single sequence and treating odd and even elements specially.
&lt;/p&gt;
&lt;p&gt;
Basic example is:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&amp;lt;xsl:stylesheet version="3.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:t="t"
  xmlns:map="http://www.w3.org/2005/xpath-functions/map"
  exclude-result-prefixes="xs t map"&gt;

  &amp;lt;xsl:template match="/"&gt;
    &amp;lt;xsl:variable name="map" as="map(xs:string, xs:string)" select="
      map 
      {
        'Su': 'Sunday',
        'Mo': 'Monday',
        'Tu': 'Tuesday',
        'We': 'Wednesday',
        'Th': 'Thursday',
        'Fr': 'Friday',
        'Sa': 'Saturday'
      }"/&gt;
      
     &amp;lt;xsl:message select="map:keys($map)"/&gt;
  &amp;lt;/xsl:template&gt;  

&amp;lt;/xsl:stylesheet&gt;&lt;/pre&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
A list of map functions can be found here &lt;a href="http://www.w3.org/2005/xpath-functions/map/"&gt;http://www.w3.org/2005/xpath-functions/map/&lt;/a&gt;,
though not all are available, as Saxon HE still does not allow inline functions.
&lt;/p&gt;
&lt;p&gt;
P.S. From the development perspective it&amp;#39;s a great harm that Saxon HE is so limited.
Basically limited to xslt 2.0 + some selected parts of 3.0.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=824d5dcd-a1a5-4314-b7fa-1e4447417c9f" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,824d5dcd-a1a5-4314-b7fa-1e4447417c9f.aspx</comments>
      <category>Thinking aloud</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=acbef9ad-de11-4fea-b74e-d5c9a619ba50</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,acbef9ad-de11-4fea-b74e-d5c9a619ba50.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=acbef9ad-de11-4fea-b74e-d5c9a619ba50</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Lately we do not program in XSLT too often but rather in java, C#, SQL and javascript,
but from time to time we have tasks in XSLT.
</p>
        <p>
People claim that those languages are too different and use this argument to explain
why XSLT is only a niche language. We, on the other hand, often spot similarities
between them.
</p>
        <p>
So, what it is in other languages that is implemented as tunnel parameters in XSLT?
</p>
        <p>
To get an answer we reiterated how they work in XSLT, so, you:
</p>
        <ul>
          <li>
define a template with parameters marked as <code>tunnel="yes"</code>;</li>
          <li>
use these parameters the same way as regular parameters;</li>
          <li>
pass template parameters down to other templates marking them as <code>tunnel="yes"</code>;</li>
        </ul>
        <p>
The important difference of regular template parameters from tunnel parameters is
that the tunnel parameters are implicitly passed down the call chain of templates.
This means that you:
</p>
        <ul>
          <li>
define your API that is expected to receive some parameter;</li>
          <li>
pass these parameters somewhere high in the stack, or override them later in the stack
chain;</li>
          <li>
do not bother to propagate them (you might not even know all of the tunnel parameters
passed, so encapsulation is in action);</li>
        </ul>
        <p>
As a result we have a template with some parameters passed explicitly, and some others
are receiving values from somewhere, usually not from direct caller. It’s possible
to say that these tunnel parameters are injected into a template call. This resembles
a lot injection API in other languages where you configure that some parameters are
prepared for you by some container rather then by direct caller.
</p>
        <p>
Now, when we have expressed this idea it seems so obvious but before we thought of
this we did not realize that tunnel parameters in XSLT and Dependency Injection in
other languages are the same thing.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=acbef9ad-de11-4fea-b74e-d5c9a619ba50" />
      </body>
      <title>View on tunnel parameters in XSLT</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,acbef9ad-de11-4fea-b74e-d5c9a619ba50.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2017/03/26/ViewOnTunnelParametersInXSLT.aspx</link>
      <pubDate>Sun, 26 Mar 2017 04:21:36 GMT</pubDate>
      <description>&lt;p&gt;
Lately we do not program in XSLT too often but rather in java, C#, SQL and javascript,
but from time to time we have tasks in XSLT.
&lt;/p&gt;
&lt;p&gt;
People claim that those languages are too different and use this argument to explain
why XSLT is only a niche language. We, on the other hand, often spot similarities
between them.
&lt;/p&gt;
&lt;p&gt;
So, what it is in other languages that is implemented as tunnel parameters in XSLT?
&lt;/p&gt;
&lt;p&gt;
To get an answer we reiterated how they work in XSLT, so, you:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
define a template with parameters marked as &lt;code&gt;tunnel="yes"&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
use these parameters the same way as regular parameters;&lt;/li&gt;
&lt;li&gt;
pass template parameters down to other templates marking them as &lt;code&gt;tunnel="yes"&lt;/code&gt;;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
The important difference of regular template parameters from tunnel parameters is
that the tunnel parameters are implicitly passed down the call chain of templates.
This means that you:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
define your API that is expected to receive some parameter;&lt;/li&gt;
&lt;li&gt;
pass these parameters somewhere high in the stack, or override them later in the stack
chain;&lt;/li&gt;
&lt;li&gt;
do not bother to propagate them (you might not even know all of the tunnel parameters
passed, so encapsulation is in action);&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
As a result we have a template with some parameters passed explicitly, and some others
are receiving values from somewhere, usually not from direct caller. It’s possible
to say that these tunnel parameters are injected into a template call. This resembles
a lot injection API in other languages where you configure that some parameters are
prepared for you by some container rather then by direct caller.
&lt;/p&gt;
&lt;p&gt;
Now, when we have expressed this idea it seems so obvious but before we thought of
this we did not realize that tunnel parameters in XSLT and Dependency Injection in
other languages are the same thing.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=acbef9ad-de11-4fea-b74e-d5c9a619ba50" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,acbef9ad-de11-4fea-b74e-d5c9a619ba50.aspx</comments>
      <category>Thinking aloud</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=41fb6e80-8184-404b-aefe-2123225a72a0</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,41fb6e80-8184-404b-aefe-2123225a72a0.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=41fb6e80-8184-404b-aefe-2123225a72a0</wfw:commentRss>
      <title>Dependency Injection</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,41fb6e80-8184-404b-aefe-2123225a72a0.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2016/10/06/DependencyInjection.aspx</link>
      <pubDate>Thu, 06 Oct 2016 11:27:42 GMT</pubDate>
      <description>  &lt;p&gt;
Our genuine love is C++. Unfortunately clients don&amp;#39;t always share our favors,
so we mostly occupied in the C#, java and javascript. Nevertheless, we&amp;#39;re closely
watching the evolution of the C++. It became more mature in the latest specs.
&lt;/p&gt;
&lt;p&gt;
Recently, we wondered how would we deal with dependency injection in C++. What we
found is only strengthened our commitment to C++.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://en.cppreference.com/w/cpp/language/parameter_pack"&gt;Parameter packs&lt;/a&gt; introduced
in C++ 11 allow trivial implementation of constructor injection, while &lt;a href="http://en.cppreference.com/w/cpp/types/type_index"&gt;std::type_index&lt;/a&gt;, &lt;a href="http://en.cppreference.com/w/cpp/types/type_info"&gt;std::type_info&lt;/a&gt; and &lt;a href="http://en.cppreference.com/w/cpp/utility/any"&gt;std:any&lt;/a&gt; give
service containers. 
&lt;/p&gt;
&lt;p&gt;
In fact there are many DI implementations out there. The one we refer here is &lt;a href="http://boost-experimental.github.io/di/index.html"&gt;Boost.DI&lt;/a&gt;.
It&amp;#39;s not standard nor we can claim it&amp;#39;s the best but it&amp;#39;s good example
of how this concept can be implemented.
&lt;/p&gt;
&lt;p&gt;
So, consider &lt;a href="http://boost-experimental.github.io/di/tutorial/index.html"&gt;their
example&lt;/a&gt; seen in Java with CDI, in C# in .NET Core injection, and in C++:
&lt;/p&gt;
&lt;p&gt;
Java:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre style="white-space: pre-wrap"&gt;
@Dependent
public class Renderer 
{
  @Inject @Device
  private int device;
};

@Dependent
public class View 
{
  @Inject @Title
  private String title;
  @Inject
  private Renderer renderer;
};

@Dependent
public class Model {};

@Dependent
public class Controller 
{
  @Inject
  private Model model;
  @Inject
  private View view;
};

@Dependent
public class User {};

@Dependent
public class App 
{
  @Inject
  private Controller controller;
  @Inject
  private User user;
};

...
  Privider&amp;lt;App&gt; provider = ...

  App app = provider.get();
&lt;/pre&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
C#:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre style="white-space: pre-wrap"&gt;public class RenderedOptions
{
  public int Device { get; set; }
}
    
public class ViewOptions
{
  public int Title { get; set; }
}
    
public class Renderer 
{
  public Renderer(IOptions&amp;lt;RendererOptions&gt; options)
  {
    Device = options.Device;
  }

  public int Device { get; set; }
}

public class View 
{
  public View(IOptions&amp;lt;ViewOptions&gt; options, Renderer renderer)
  {
    Title = options.Title;
    Renderer = renderer;
  }

  public string Title { get; set; }
  public Renderer Renderer { get; set; }
}

public class Model {}

public class Controller 
{
  public Controller(Model model, View view) 
  {
    Model = model;
    View = view;
  }

  public Model Model { get; set; }
  public View View { get; set; }
};

public class User {};

public class App 
{
  public App(Controller controller, User user) 
  {
    Controller = controller;
    User = user;
  }

  public Controller Controller { get; set; }
  public User User { get; set; }
};

...
  IServiceProvider serviceProvider = ...

  serviceProvider.GetService&amp;lt;App&gt;();
&lt;/pre&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
C++:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre style="white-space: pre-wrap"&gt;#include &amp;lt;boost/di.hpp&gt;

namespace di = boost::di;

struct renderer 
{
  int device;
};

class view 
{
public:
  view(std::string title, const renderer&amp;) {}
};

class model {};

class controller 
{
public:
  controller(model&amp;, view&amp;) {}
};

class user {};

class app 
{
public:
  app(controller&amp;, user&amp;) {}
};

int main()
{
  /**
   * renderer renderer_;
   * view view_{"", renderer_};
   * model model_;
   * controller controller_{model_, view_};
   * user user_;
   * app app_{controller_, user_};
   */

  auto injector = di::make_injector();
  injector.create&amp;lt;app&gt;();
}
&lt;/pre&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
What is different between these DI flavors?
&lt;/p&gt;
&lt;p&gt;
Not too much from the perspective of the final task achieved.
&lt;/p&gt;
&lt;p&gt;
In java we used &lt;a href="http://docs.jboss.org/weld/reference/2.4.0.CR1/en-US/html/injection.html"&gt;member
injection&lt;/a&gt;, with &lt;a href="http://docs.jboss.org/weld/reference/2.4.0.CR1/en-US/html/injection.html#_qualifier_annotations"&gt;qualifiers&lt;/a&gt; to
inject scalars.
&lt;/p&gt;
&lt;p&gt;
In C# we used &lt;a href="https://docs.asp.net/en/latest/fundamentals/dependency-injection.html"&gt;constructor
injection&lt;/a&gt; with &lt;a href="https://docs.asp.net/en/latest/fundamentals/configuration.html#options-config-objects"&gt;Options
pattern&lt;/a&gt; to inject scalars.
&lt;/p&gt;
&lt;p&gt;
In C++ we used constructor injection with direct constants injected.
&lt;/p&gt;
&lt;p&gt;
All technologies have their API to initialize DI container, but, again, while API
is different, the idea is the same.
&lt;/p&gt;
&lt;p&gt;
So, expressiveness of C++ matches to those of java and C#.
&lt;/p&gt;
&lt;p&gt;
Deeper analysis shows that java&amp;#39;s CDI is more feature rich than DI of C# and C++,
but, personally, we consider it&amp;#39;s advantage of C# and C++ that they have such
a light DI.
&lt;/p&gt;
&lt;p&gt;
At the same time there is an important difference between C++ vs java and C#.
&lt;/p&gt;
&lt;p&gt;
While both java and C# are deemed to use reflection (C# in theory could use code generation
on the fly to avoid reflection), C++&amp;#39;s DI natively constructs and injects services.
&lt;/p&gt;
&lt;p&gt;
What does it mean for the user?
&lt;/p&gt;
&lt;p&gt;
Well, a lot! Both in java and in C# you would not want to use DI in a performance
critical part of code (e.g. in a tight loop), while it&amp;#39;s Ok in C++ due to near
to zero performance impact from DI. This may result in more modular and performant
code in C++.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=41fb6e80-8184-404b-aefe-2123225a72a0" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,41fb6e80-8184-404b-aefe-2123225a72a0.aspx</comments>
      <category>.NET</category>
      <category>C++</category>
      <category>Java</category>
      <category>Thinking aloud</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=2f514933-13db-476b-90c8-9cc9724b708d</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,2f514933-13db-476b-90c8-9cc9724b708d.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=2f514933-13db-476b-90c8-9cc9724b708d</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
While reading on ASP.NET Core Session, and analyzing the difference with previous
version of ASP.NET we bumped into a problem...
</p>
        <p>
At <a href="https://docs.asp.net/en/latest/fundamentals/app-state.html#managing-application-state">Managing
Application State</a> they note:
</p>
        <blockquote>
          <i>Session is non-locking, so if two requests both attempt to modify the
contents of session, the last one will win. Further, Session is implemented as a coherent
session, which means that all of the contents are stored together. This means that
if two requests are modifying different parts of the session (different keys), they
may still impact each other.</i>
        </blockquote>
        <p>
This is different from previous versions of ASP.NET where session was blocking, which
meant that if you had multiple concurrent requests to the session, then all requests
were synchronized. So, you could keep consistent state.
</p>
        <p>
In ASP.NET Core you have no built-in means to keep a consistent state of the session.
Even assurances that the session is coherent does not help in any way.
</p>
        <p>
You options are:
</p>
        <ul>
          <li>
build your own synchronization to deal with this problem (e.g. around the database);</li>
          <li>
decree that your application cannot handle concurrent requests to the same session,
so client should not attempt it, otherwise behaviour is undefined.</li>
        </ul>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=2f514933-13db-476b-90c8-9cc9724b708d" />
      </body>
      <title>ASP.NET Core Session</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,2f514933-13db-476b-90c8-9cc9724b708d.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2016/09/28/ASPNETCoreSession.aspx</link>
      <pubDate>Wed, 28 Sep 2016 19:22:15 GMT</pubDate>
      <description>  &lt;p&gt;
While reading on ASP.NET Core Session, and analyzing the difference with previous
version of ASP.NET we bumped into a problem...
&lt;/p&gt;
&lt;p&gt;
At &lt;a href="https://docs.asp.net/en/latest/fundamentals/app-state.html#managing-application-state"&gt;Managing
Application State&lt;/a&gt; they note:
&lt;/p&gt;
&lt;blockquote&gt;&lt;i&gt;Session is non-locking, so if two requests both attempt to modify the
contents of session, the last one will win. Further, Session is implemented as a coherent
session, which means that all of the contents are stored together. This means that
if two requests are modifying different parts of the session (different keys), they
may still impact each other.&lt;/i&gt; &lt;/blockquote&gt; 
&lt;p&gt;
This is different from previous versions of ASP.NET where session was blocking, which
meant that if you had multiple concurrent requests to the session, then all requests
were synchronized. So, you could keep consistent state.
&lt;/p&gt;
&lt;p&gt;
In ASP.NET Core you have no built-in means to keep a consistent state of the session.
Even assurances that the session is coherent does not help in any way.
&lt;/p&gt;
&lt;p&gt;
You options are:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
build your own synchronization to deal with this problem (e.g. around the database);&lt;/li&gt;
&lt;li&gt;
decree that your application cannot handle concurrent requests to the same session,
so client should not attempt it, otherwise behaviour is undefined.&lt;/li&gt;
&lt;/ul&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=2f514933-13db-476b-90c8-9cc9724b708d" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,2f514933-13db-476b-90c8-9cc9724b708d.aspx</comments>
      <category>.NET</category>
      <category>ASP.NET</category>
      <category>Thinking aloud</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=28231475-8816-4cc4-a181-cf4e781f0821</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,28231475-8816-4cc4-a181-cf4e781f0821.aspx</pingback:target>
      <dc:creator>Arthur Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,28231475-8816-4cc4-a181-cf4e781f0821.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=28231475-8816-4cc4-a181-cf4e781f0821</wfw:commentRss>
      <title>Dao for programmers.</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,28231475-8816-4cc4-a181-cf4e781f0821.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2016/02/29/DaoForProgrammers.aspx</link>
      <pubDate>Mon, 29 Feb 2016 18:33:04 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="https://dzone.com/articles/8-ways-to-become-a-better-coder?edition=148258&amp;utm_source=Daily%20Digest&amp;utm_medium=email&amp;utm_content=DZone%20Daily%20Digest&amp;utm_campaign=dd%202016-02-29&amp;userid=325146"&gt;8
Ways to Become a Better Coder&lt;/a&gt; is a good article. Read and apply to yourself. Never
mind what your occupation is. Replace "coder" with your profession. Suits to everybody
who wants to be the best.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=28231475-8816-4cc4-a181-cf4e781f0821" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,28231475-8816-4cc4-a181-cf4e781f0821.aspx</comments>
      <category>Thinking aloud</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=a57f50da-da1f-44f4-9572-cbc7e5434fa1</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,a57f50da-da1f-44f4-9572-cbc7e5434fa1.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,a57f50da-da1f-44f4-9572-cbc7e5434fa1.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=a57f50da-da1f-44f4-9572-cbc7e5434fa1</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="https://en.wikipedia.org/wiki/Visitor_pattern">Visitor pattern</a> is often
used to separate operation from object graph it operates with. Here we assume that
the reader is familiar with the subject.
</p>
        <p>
The idea is like this:
</p>
        <ul>
          <li>
The operation over object graph is implemented as type called <code>Visitor</code>.</li>
          <li>
            <code>Visitor</code> defines methods for each type of object in the graph, which a
called during traversing of the graph.</li>
          <li>
Traversing over the graph is implemented by a type called <code>Traverser</code>,
or by the <code>Visitor</code> or by each object type in the graph.</li>
        </ul>
        <p>
Implementation should collect, aggregate or perform other actions during visit of
objects in the graph, so that at the end of the visit the purpose of operation will
be complete.
</p>
        <p>
Such implementation is push-like: you create operation object and call a method that
gets object graph on input and returns operation result on output.
</p>
        <p style="direction: ltr">
In the past we often dealt with big graphs (usually these are virtual graphs backended
at database or at a file system).
</p>
        <p>
Also having a strong experience in the XSLT we see that the visitor pattern in OOP
is directly mapped into <code>xsl:template</code> and <code>xsl:apply-templates</code> technique.
</p>
        <p>
Another thought was that in XML processing there are two camps:
</p>
        <ul>
          <li>
SAX (push-like) - those who process xml in callbacks, which is very similar to visitor
pattern; and</li>
          <li>
XML Reader (pull-like) - those who pull xml components from a source, and then iterate
and process them.</li>
        </ul>
        <p>
As with SAX vs XML Reader or, more generally, push vs pull processing models, there
is no the best one. One or the other is preferable in particular circumstances. E.g.
Pull like component fits into a transformation pipeline where one pull component has
another as its source; another example is when one needs to process two sources at
once, which is untrivial with push like model. On the other hand push processing fits
better into Reduce part of <a href="https://en.wikipedia.org/wiki/MapReduce">MapReduce</a> pattern
where you need to accumulate results from source.
</p>
        <p>
So, our idea was to complete classic push-like visitor pattern with an example of
pull-like implementation.
</p>
        <p>
For the demostration we have selected Java language, and a simplest boolean expression
calculator.
</p>
        <p>
Please follow GitHub <a href="https://github.com/nesterovsky-bros/VisitorPattern">nesterovsky-bros/VisitorPattern</a> to
see the detailed explanation.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=a57f50da-da1f-44f4-9572-cbc7e5434fa1" />
      </body>
      <title>Pull visitor pattern</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,a57f50da-da1f-44f4-9572-cbc7e5434fa1.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2016/02/09/PullVisitorPattern.aspx</link>
      <pubDate>Tue, 09 Feb 2016 12:37:10 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="https://en.wikipedia.org/wiki/Visitor_pattern"&gt;Visitor pattern&lt;/a&gt; is often
used to separate operation from object graph it operates with. Here we assume that
the reader is familiar with the subject.
&lt;/p&gt;
&lt;p&gt;
The idea is like this:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
The operation over object graph is implemented as type called &lt;code&gt;Visitor&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Visitor&lt;/code&gt; defines methods for each type of object in the graph, which a
called during traversing of the graph.&lt;/li&gt;
&lt;li&gt;
Traversing over the graph is implemented by a type called &lt;code&gt;Traverser&lt;/code&gt;,
or by the &lt;code&gt;Visitor&lt;/code&gt; or by each object type in the graph.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Implementation should collect, aggregate or perform other actions during visit of
objects in the graph, so that at the end of the visit the purpose of operation will
be complete.
&lt;/p&gt;
&lt;p&gt;
Such implementation is push-like: you create operation object and call a method that
gets object graph on input and returns operation result on output.
&lt;/p&gt;
&lt;p style="direction: ltr"&gt;
In the past we often dealt with big graphs (usually these are virtual graphs backended
at database or at a file system).
&lt;/p&gt;
&lt;p&gt;
Also having a strong experience in the XSLT we see that the visitor pattern in OOP
is directly mapped into &lt;code&gt;xsl:template&lt;/code&gt; and &lt;code&gt;xsl:apply-templates&lt;/code&gt; technique.
&lt;/p&gt;
&lt;p&gt;
Another thought was that in XML processing there are two camps:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
SAX (push-like) - those who process xml in callbacks, which is very similar to visitor
pattern; and&lt;/li&gt;
&lt;li&gt;
XML Reader (pull-like) - those who pull xml components from a source, and then iterate
and process them.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
As with SAX vs XML Reader or, more generally, push vs pull processing models, there
is no the best one. One or the other is preferable in particular circumstances. E.g.
Pull like component fits into a transformation pipeline where one pull component has
another as its source; another example is when one needs to process two sources at
once, which is untrivial with push like model. On the other hand push processing fits
better into Reduce part of &lt;a href="https://en.wikipedia.org/wiki/MapReduce"&gt;MapReduce&lt;/a&gt; pattern
where you need to accumulate results from source.
&lt;/p&gt;
&lt;p&gt;
So, our idea was to complete classic push-like visitor pattern with an example of
pull-like implementation.
&lt;/p&gt;
&lt;p&gt;
For the demostration we have selected Java language, and a simplest boolean expression
calculator.
&lt;/p&gt;
&lt;p&gt;
Please follow GitHub &lt;a href="https://github.com/nesterovsky-bros/VisitorPattern"&gt;nesterovsky-bros/VisitorPattern&lt;/a&gt; to
see the detailed explanation.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=a57f50da-da1f-44f4-9572-cbc7e5434fa1" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,a57f50da-da1f-44f4-9572-cbc7e5434fa1.aspx</comments>
      <category>Java</category>
      <category>Thinking aloud</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=d17e5531-b143-46d3-9b69-4f05e7f3b04f</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,d17e5531-b143-46d3-9b69-4f05e7f3b04f.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=d17e5531-b143-46d3-9b69-4f05e7f3b04f</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Essence of the problem (see <a href="http://www.nesterovsky-bros.com/weblog/2016/01/02/ErrorDuringTransformationInSaxon97.aspx">Error
during transformation in Saxon 9.7</a>, <a href="https://saxonica.plan.io/boards/3/topics/6270">thread
on forum</a>):
</p>
        <ol>
          <li>
XPath engine may arbitrary reorder predicates whose expressions do not depend on a
context position.</li>
          <li>
While an XPath expression <code>$N[@x castable as xs:date][xs:date(@x) gt xs:date("2000-01-01")]</code> cannot
raise an error if it's evaluated from the left to right, an expression with reordered
predicates <code>$N[xs:date(@x) gt xs:date("2000-01-01")][@x castable as xs:date]</code> may
generate an error when <code>@x</code> is not a <code>xs:date</code>.</li>
        </ol>
        <p>
To avoid a potential problem one should rewrite the expression like this: <code>$N[if
(@x castable as xs:date) then xs:date(@x) gt xs:date("2000-01-01") else false()]</code>.
</p>
        <p>
Please note that the following rewrite will not work: <code>$N[(@x castable as xs:date)
and (xs:date(@x) gt xs:date("2000-01-01"))]</code>, as arguments of <code>and</code> expression
can be evaluated in any order, and error that occurs during evaluation of any argument
may be propageted.
</p>
        <p>
With these facts we faced a task to check our code base and to fix possible problems. 
</p>
        <p>
A search has brought ~450 instances of XPath expessions that use two or more consequtive
predicates. Accurate analysis limited this to ~20 instances that should be rewritten.
But then, all of sudden, we have decided to commit an experiment. What if we split
XPath expression in two sub expressions. Can error still resurface?
</p>
        <p>
Consider:
</p>
        <blockquote>
          <code>&lt;xsl:stylesheet version="2.0" xmlns:xsl="<a href="http://www.w3.org/1999/XSL/Transform">http://www.w3.org/1999/XSL/Transform</a>"<br />
  xmlns:xs="http://www.w3.org/2001/XMLSchema"&gt;<br /><br />
  &lt;xsl:variable name="elements" as="element()+"&gt;&lt;a/&gt;&lt;b value="c"/&gt;&lt;/xsl:variable&gt;<br /><br />
  &lt;xsl:template match="/"&gt;<br />
    &lt;xsl:variable name="a" as="element()*" select="$elements[self::d
or self::e]"/&gt;<br />
    &lt;xsl:variable name="b" as="element()*" select="$a[xs:integer(@value)
= 1]"/&gt;<br /><br />
    &lt;xsl:sequence select="$b"/&gt;<br />
  &lt;/xsl:template&gt;<br /><br />
&lt;/xsl:stylesheet&gt;</code>
        </blockquote>
        <p>
As we expected Saxon 9.7 internally assembles a final XPath with two predicates and
reorders them. As result we get an error:
</p>
        <blockquote>
          <code>Error at char 20 in xsl:variable/@select on line 8 column 81 of
Saxon9.7-filter_speculation.xslt:<br />
  FORG0001: Cannot convert string "c" to an integer</code>
        </blockquote>
        <p>
This turn of events greately complicates the code review we have to commit.
</p>
        <p>
Michiel Kay's answer to this example:
</p>
        <blockquote>
          <i>I think your argument that the reordering is inappropriate when the
expression is written using variables is very powerful. I shall raise the question
with my WG colleagues.</i>
        </blockquote>
        <p>
In fact we think that either: reordering of predicates is inappropriate, or (weaker,
to allow reordering) to treat an error during evaluation of predicate expression as <code>false()</code>.
This is what is done in XSLT patterns. Other solutions make XPath less intuitive. 
</p>
        <p>
In other words we should use XPath (language) to express ideas, and engine should
correctly and efficiently implement them. So, we should not be forced to rewrite expression
to please implementation.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=d17e5531-b143-46d3-9b69-4f05e7f3b04f" />
      </body>
      <title>Error during transformation in Saxon 9.7 - Continue</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,d17e5531-b143-46d3-9b69-4f05e7f3b04f.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2016/01/04/ErrorDuringTransformationInSaxon97Continue.aspx</link>
      <pubDate>Mon, 04 Jan 2016 10:07:12 GMT</pubDate>
      <description>  &lt;p&gt;
Essence of the problem (see &lt;a href="http://www.nesterovsky-bros.com/weblog/2016/01/02/ErrorDuringTransformationInSaxon97.aspx"&gt;Error
during transformation in Saxon 9.7&lt;/a&gt;, &lt;a href="https://saxonica.plan.io/boards/3/topics/6270"&gt;thread
on forum&lt;/a&gt;):
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
XPath engine may arbitrary reorder predicates whose expressions do not depend on a
context position.&lt;/li&gt;
&lt;li&gt;
While an XPath expression &lt;code&gt;$N[@x castable as xs:date][xs:date(@x) gt xs:date("2000-01-01")]&lt;/code&gt; cannot
raise an error if it&amp;#39;s evaluated from the left to right, an expression with reordered
predicates &lt;code&gt;$N[xs:date(@x) gt xs:date("2000-01-01")][@x castable as xs:date]&lt;/code&gt; may
generate an error when &lt;code&gt;@x&lt;/code&gt; is not a &lt;code&gt;xs:date&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
To avoid a potential problem one should rewrite the expression like this: &lt;code&gt;$N[if
(@x castable as xs:date) then xs:date(@x) gt xs:date("2000-01-01") else false()]&lt;/code&gt;.
&lt;/p&gt;
&lt;p&gt;
Please note that the following rewrite will not work: &lt;code&gt;$N[(@x castable as xs:date)
and (xs:date(@x) gt xs:date("2000-01-01"))]&lt;/code&gt;, as arguments of &lt;code&gt;and&lt;/code&gt; expression
can be evaluated in any order, and error that occurs during evaluation of any argument
may be propageted.
&lt;/p&gt;
&lt;p&gt;
With these facts we faced a task to check our code base and to fix possible problems. 
&lt;/p&gt;
&lt;p&gt;
A search has brought ~450 instances of XPath expessions that use two or more consequtive
predicates. Accurate analysis limited this to ~20 instances that should be rewritten.
But then, all of sudden, we have decided to commit an experiment. What if we split
XPath expression in two sub expressions. Can error still resurface?
&lt;/p&gt;
&lt;p&gt;
Consider:
&lt;/p&gt;
&lt;blockquote&gt;&lt;code&gt;&amp;lt;xsl:stylesheet version="2.0" xmlns:xsl="&lt;a href="http://www.w3.org/1999/XSL/Transform"&gt;http://www.w3.org/1999/XSL/Transform&lt;/a&gt;"&lt;br /&gt;
&amp;nbsp; xmlns:xs="http://www.w3.org/2001/XMLSchema"&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:variable name="elements" as="element()+"&gt;&amp;lt;a/&gt;&amp;lt;b value="c"/&gt;&amp;lt;/xsl:variable&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:template match="/"&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;xsl:variable name="a" as="element()*" select="$elements[self::d
or self::e]"/&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:variable name="b" as="element()*" select="$a[xs:integer(@value)
= 1]"/&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:sequence select="$b"/&gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;/xsl:template&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/xsl:stylesheet&gt;&lt;/code&gt;&lt;/blockquote&gt; 
&lt;p&gt;
As we expected Saxon 9.7 internally assembles a final XPath with two predicates and
reorders them. As result we get an error:
&lt;/p&gt;
&lt;blockquote&gt; &lt;code&gt;Error at char 20 in xsl:variable/@select on line 8 column 81 of
Saxon9.7-filter_speculation.xslt:&lt;br /&gt;
&amp;nbsp; FORG0001: Cannot convert string "c" to an integer&lt;/code&gt; &lt;/blockquote&gt; 
&lt;p&gt;
This turn of events greately complicates the code review we have to commit.
&lt;/p&gt;
&lt;p&gt;
Michiel Kay&amp;#39;s answer to this example:
&lt;/p&gt;
&lt;blockquote&gt;&lt;i&gt;I think your argument that the reordering is inappropriate when the
expression is written using variables is very powerful. I shall raise the question
with my WG colleagues.&lt;/i&gt;&lt;/blockquote&gt; 
&lt;p&gt;
In fact we think that either: reordering of predicates is inappropriate, or (weaker,
to allow reordering) to treat an error during evaluation of predicate expression as &lt;code&gt;false()&lt;/code&gt;.
This is what is done in XSLT patterns. Other solutions make XPath less intuitive. 
&lt;/p&gt;
&lt;p&gt;
In other words we should use XPath (language) to express ideas, and engine should
correctly and efficiently implement them. So, we should not be forced to rewrite expression
to please implementation.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=d17e5531-b143-46d3-9b69-4f05e7f3b04f" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,d17e5531-b143-46d3-9b69-4f05e7f3b04f.aspx</comments>
      <category>Thinking aloud</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=0440711a-6c3c-4d59-b2e6-ba41f64c1c0c</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,0440711a-6c3c-4d59-b2e6-ba41f64c1c0c.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=0440711a-6c3c-4d59-b2e6-ba41f64c1c0c</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
On December, 30 we have opened <a href="https://saxonica.plan.io/boards/3/topics/6270">a
thread in Saxon help forum</a> that shows a stylesheet generating an error. This is
the stylesheet:
</p>
        <blockquote>
          <code>&lt;xsl:stylesheet version="2.0" xmlns:xsl="<a href="http://www.w3.org/1999/XSL/Transform">http://www.w3.org/1999/XSL/Transform</a>"<br />
  xmlns:xs="http://www.w3.org/2001/XMLSchema"&gt;<br /><br />
  &lt;xsl:variable name="elements" as="element()+"&gt;&lt;a/&gt;&lt;b value="c"/&gt;&lt;/xsl:variable&gt;<br /><br />
  &lt;xsl:template match="/"&gt;<br />
    &lt;xsl:sequence select="$elements[self::d or self::e][xs:integer(@value)
= 1]"/&gt;<br />
  &lt;/xsl:template&gt;<br /><br />
&lt;/xsl:stylesheet&gt;</code>
        </blockquote>
        <p>
We get an error:
</p>
        <blockquote>
          <code>Error at char 47 in xsl:sequence/@select on line 7 column 83 of
Saxon9.7-filter_speculation.xslt:<br />
  FORG0001: Cannot convert string "c" to an integer<br />
Exception in thread "main" ; SystemID: .../Saxon9.7-filter_speculation.xslt; Line#:
7; Column#: 47<br />
ValidationException: Cannot convert string "c" to an integer<br />
  at ... </code>
        </blockquote>
        <p>
It's interesting that error happens in Saxon 9.7 but not in earlier versions.
</p>
        <p>
The answer we got was expected but disheartening:
</p>
        <blockquote>
          <i>The XPath specification (section 2.3.4, Errors and Optimization) explicitly
allows the predicates of a filter expression to be reordered by an optimizer. See
this example, which is very similar to yours:</i>
          <blockquote>
            <p>
              <i>The expression in the following example cannot raise a casting error if it is evaluated
exactly as written (i.e., left to right). Since neither predicate depends on the context
position, an implementation might choose to reorder the predicates to achieve better
performance (for example, by taking advantage of an index). This reordering could
cause the expression to raise an error.</i>
            </p>
            <pre>$N[@x castable as xs:date][xs:date(@x) gt xs:date("2000-01-01")]</pre>
          </blockquote>
        </blockquote>
        <p>
Following the spec, Michael Kay advices us to rewrite XPath:
</p>
        <blockquote>
          <code>$elements[self::d or self::e][xs:integer(@value) = 1]</code>
        </blockquote>
        <p>
like this:
</p>
        <blockquote>
          <code>$elements[if (self::d or self::e) then xs:integer(@value) = 1 else
false()]</code>
        </blockquote>
        <p>
Such subtleties make it hard to reason about and to teach XPath. We doubt many people
will spot the difference immediately.
</p>
        <p>
We think that if such optimization was so much important to spec writers, then they
had to change filter rules to treat failed predicates as <code>false()</code>. This
would avoid any obscure differences in these two, otherwise equal, expressions. In
fact something <a href="http://www.nesterovsky-bros.com/weblog/2008/07/31/SFINAEInXsltOrNativeExceptionHandling.aspx">similar
already exists with templates</a> where failed evaluation of pattern is treated as
un-match.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=0440711a-6c3c-4d59-b2e6-ba41f64c1c0c" />
      </body>
      <title>Error during transformation in Saxon 9.7</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,0440711a-6c3c-4d59-b2e6-ba41f64c1c0c.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2016/01/02/ErrorDuringTransformationInSaxon97.aspx</link>
      <pubDate>Sat, 02 Jan 2016 21:32:16 GMT</pubDate>
      <description>  &lt;p&gt;
On December, 30 we have opened &lt;a href="https://saxonica.plan.io/boards/3/topics/6270"&gt;a
thread in Saxon help forum&lt;/a&gt; that shows a stylesheet generating an error. This is
the stylesheet:
&lt;/p&gt;
&lt;blockquote&gt;&lt;code&gt;&amp;lt;xsl:stylesheet version="2.0" xmlns:xsl="&lt;a href="http://www.w3.org/1999/XSL/Transform"&gt;http://www.w3.org/1999/XSL/Transform&lt;/a&gt;"&lt;br /&gt;
&amp;nbsp; xmlns:xs="http://www.w3.org/2001/XMLSchema"&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:variable name="elements" as="element()+"&gt;&amp;lt;a/&gt;&amp;lt;b value="c"/&gt;&amp;lt;/xsl:variable&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;lt;xsl:template match="/"&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;xsl:sequence select="$elements[self::d or self::e][xs:integer(@value)
= 1]"/&gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;/xsl:template&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/xsl:stylesheet&gt;&lt;/code&gt;&lt;/blockquote&gt; 
&lt;p&gt;
We get an error:
&lt;/p&gt;
&lt;blockquote&gt;&lt;code&gt;Error at char 47 in xsl:sequence/@select on line 7 column 83 of
Saxon9.7-filter_speculation.xslt:&lt;br /&gt;
&amp;nbsp; FORG0001: Cannot convert string "c" to an integer&lt;br /&gt;
Exception in thread "main" ; SystemID: .../Saxon9.7-filter_speculation.xslt; Line#:
7; Column#: 47&lt;br /&gt;
ValidationException: Cannot convert string "c" to an integer&lt;br /&gt;
&amp;nbsp; at ... &lt;/code&gt;&lt;/blockquote&gt; 
&lt;p&gt;
It&amp;#39;s interesting that error happens in Saxon 9.7 but not in earlier versions.
&lt;/p&gt;
&lt;p&gt;
The answer we got was expected but disheartening:
&lt;/p&gt;
&lt;blockquote&gt;&lt;i&gt;The XPath specification (section 2.3.4, Errors and Optimization) explicitly
allows the predicates of a filter expression to be reordered by an optimizer. See
this example, which is very similar to yours:&lt;/i&gt; &lt;blockquote&gt; 
&lt;p&gt;
&lt;i&gt;The expression in the following example cannot raise a casting error if it is evaluated
exactly as written (i.e., left to right). Since neither predicate depends on the context
position, an implementation might choose to reorder the predicates to achieve better
performance (for example, by taking advantage of an index). This reordering could
cause the expression to raise an error.&lt;/i&gt;
&lt;/p&gt;
&lt;pre&gt;$N[@x castable as xs:date][xs:date(@x) gt xs:date(&amp;quot;2000-01-01&amp;quot;)]&lt;/pre&gt;
&lt;/blockquote&gt; &lt;/blockquote&gt; 
&lt;p&gt;
Following the spec, Michael Kay advices us to rewrite XPath:
&lt;/p&gt;
&lt;blockquote&gt;&lt;code&gt;$elements[self::d or self::e][xs:integer(@value) = 1]&lt;/code&gt;&lt;/blockquote&gt; 
&lt;p&gt;
like this:
&lt;/p&gt;
&lt;blockquote&gt;&lt;code&gt;$elements[if (self::d or self::e) then xs:integer(@value) = 1 else
false()]&lt;/code&gt;&lt;/blockquote&gt; 
&lt;p&gt;
Such subtleties make it hard to reason about and to teach XPath. We doubt many people
will spot the difference immediately.
&lt;/p&gt;
&lt;p&gt;
We think that if such optimization was so much important to spec writers, then they
had to change filter rules to treat failed predicates as &lt;code&gt;false()&lt;/code&gt;. This
would avoid any obscure differences in these two, otherwise equal, expressions. In
fact something &lt;a href="http://www.nesterovsky-bros.com/weblog/2008/07/31/SFINAEInXsltOrNativeExceptionHandling.aspx"&gt;similar
already exists with templates&lt;/a&gt; where failed evaluation of pattern is treated as
un-match.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=0440711a-6c3c-4d59-b2e6-ba41f64c1c0c" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,0440711a-6c3c-4d59-b2e6-ba41f64c1c0c.aspx</comments>
      <category>Thinking aloud</category>
      <category>xslt</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=64676412-4e10-41e1-bfcf-89cf4dfa6881</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,64676412-4e10-41e1-bfcf-89cf4dfa6881.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,64676412-4e10-41e1-bfcf-89cf4dfa6881.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=64676412-4e10-41e1-bfcf-89cf4dfa6881</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
A collegue has approached to us with a question on how <a href="http://en.akinator.com/" target="_blank">Akinator</a> engine
may work. 
</p>
        <p>
To our shame we have never heard about this amazing game before. To fill the gap we
have immediately started to play it, and have identified it as a <a href="https://en.wikipedia.org/wiki/Troubleshooting" target="_blank">Troubleshooting</a> solver.
</p>
        <p>
It took us a couple of minutes to come up with a brilliant solution: "We just need
to google and find the engine in the internet". <img alt=":-)" src="http://www.nesterovsky-bros.com/weblog/smilies/happy.gif" /></p>
        <p>
Unfortunately, this led to nowhere, as no Akinator itself is open sourced, and no
other good quality open source solutions are available.
</p>
        <p>
After another hour we have got two more ideas:
</p>
        <ol>
          <li>
The task should fit into SQL;</li>
          <li>
The task is a good candidate for a neural network.</li>
        </ol>
        <p>
In fact, the first might be required to teach the second, so we have decided to formalize
the problem in terms of SQL, while still keeping in mind a neural network.
</p>
        <p>
With this goal we have created a GitHub project. Please see the algorithm and its
implementation at <a href="https://github.com/nesterovsky-bros/KB">github.com/nesterovsky-bros/KB</a>.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=64676412-4e10-41e1-bfcf-89cf4dfa6881" />
      </body>
      <title>Akinator like engine</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,64676412-4e10-41e1-bfcf-89cf4dfa6881.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2015/12/16/AkinatorLikeEngine.aspx</link>
      <pubDate>Wed, 16 Dec 2015 12:33:41 GMT</pubDate>
      <description>&lt;p&gt;
A collegue has approached to us with a question on how &lt;a href="http://en.akinator.com/" target="_blank"&gt;Akinator&lt;/a&gt; engine
may work. 
&lt;/p&gt;
&lt;p&gt;
To our shame we have never heard about this amazing game before. To fill the gap we
have immediately started to play it, and have identified it as a &lt;a href="https://en.wikipedia.org/wiki/Troubleshooting" target="_blank"&gt;Troubleshooting&lt;/a&gt; solver.
&lt;/p&gt;
&lt;p&gt;
It took us a couple of minutes to come up with a brilliant solution: "We just need
to google and find the engine in the internet". &lt;img alt=":-)" src="http://www.nesterovsky-bros.com/weblog/smilies/happy.gif"&gt;
&lt;/p&gt;
&lt;p&gt;
Unfortunately, this led to nowhere, as no Akinator itself is open sourced, and no
other good quality open source solutions are available.
&lt;/p&gt;
&lt;p&gt;
After another hour we have got two more ideas:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
The task should fit into SQL;&lt;/li&gt;
&lt;li&gt;
The task is a good candidate for a neural network.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
In fact, the first might be required to teach the second, so we have decided to formalize
the problem in terms of SQL, while still keeping in mind a neural network.
&lt;/p&gt;
&lt;p&gt;
With this goal we have created a GitHub project. Please see the algorithm and its
implementation at &lt;a href="https://github.com/nesterovsky-bros/KB"&gt;github.com/nesterovsky-bros/KB&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=64676412-4e10-41e1-bfcf-89cf4dfa6881" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,64676412-4e10-41e1-bfcf-89cf4dfa6881.aspx</comments>
      <category>Announce</category>
      <category>SQL Server puzzle</category>
      <category>Thinking aloud</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=9ab00999-60e6-4106-ad73-9e5359ee93c5</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,9ab00999-60e6-4106-ad73-9e5359ee93c5.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,9ab00999-60e6-4106-ad73-9e5359ee93c5.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=9ab00999-60e6-4106-ad73-9e5359ee93c5</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Though <a href="https://msdn.microsoft.com/en-us/library/e80y5yhx(v=vs.110).aspx">ADO.NET</a> and
other ORM framworks like <a href="https://msdn.microsoft.com/en-us/data/ef.aspx">EntityFramework</a> and <a href="https://github.com/StackExchange/dapper-dot-net">Dapper</a> support
async pattern, you should remember that database drivers (at least all we know about)
do not support concurrent db commands running against a single connection.
</p>
        <p>
To see what we mean consider a bug we have recently identified. Consider a code:
</p>
        <blockquote>
          <pre>await Task.WhenAll(
  newImages.
    Select(
      async image =&gt;
      {
        // Load data from url.
        image.Content = await HttpUtils.ReadData(image.Url);

        // Insert image into the database.
        image.ImageID = await context.InsertImage(image);
      }));
</pre>
        </blockquote>
        <p>
The code runs multiple tasks to read images, and to write them into a database. 
</p>
        <p>
Framework decides to run all these tasks in parallel. <code>HttpUtils.ReadData()</code> has
no problem with parallel execution, while <code>context.InsertImage()</code> does
not run well in parallel, and is a subject of race conditions.
</p>
        <p>
To workaround the problem we had to use async variant of a critical section. So the
fixed code looks like this:
</p>
        <blockquote>
          <pre>
            <b>using(var semaphore = new SemaphoreSlim(1))</b> { await Task.WhenAll(
newImages. Select( async image =&gt; { // Load data from url. image.Content = await HttpUtils.ReadData(image.Url); <b>await
semaphore.WaitAsync();</b> try { // Insert image into the database. image.ImageID
= await context.InsertImage(image); } finally { <b>semaphore.Release();</b> } }));
} </pre>
        </blockquote>
        <p>
So, in the async world we still should care about race conditions.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=9ab00999-60e6-4106-ad73-9e5359ee93c5" />
      </body>
      <title>Database async trap</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,9ab00999-60e6-4106-ad73-9e5359ee93c5.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2015/07/27/DatabaseAsyncTrap.aspx</link>
      <pubDate>Mon, 27 Jul 2015 06:44:45 GMT</pubDate>
      <description>  &lt;p&gt;
Though &lt;a href="https://msdn.microsoft.com/en-us/library/e80y5yhx(v=vs.110).aspx"&gt;ADO.NET&lt;/a&gt; and
other ORM framworks like &lt;a href="https://msdn.microsoft.com/en-us/data/ef.aspx"&gt;EntityFramework&lt;/a&gt; and &lt;a href="https://github.com/StackExchange/dapper-dot-net"&gt;Dapper&lt;/a&gt; support
async pattern, you should remember that database drivers (at least all we know about)
do not support concurrent db commands running against a single connection.
&lt;/p&gt;
&lt;p&gt;
To see what we mean consider a bug we have recently identified. Consider a code:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;await Task.WhenAll(
  newImages.
    Select(
      async image =&gt;
      {
        // Load data from url.
        image.Content = await HttpUtils.ReadData(image.Url);

        // Insert image into the database.
        image.ImageID = await context.InsertImage(image);
      }));
&lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
The code runs multiple tasks to read images, and to write them into a database. 
&lt;/p&gt;
&lt;p&gt;
Framework decides to run all these tasks in parallel. &lt;code&gt;HttpUtils.ReadData()&lt;/code&gt; has
no problem with parallel execution, while &lt;code&gt;context.InsertImage()&lt;/code&gt; does
not run well in parallel, and is a subject of race conditions.
&lt;/p&gt;
&lt;p&gt;
To workaround the problem we had to use async variant of a critical section. So the
fixed code looks like this:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;&lt;b&gt;using(var semaphore = new SemaphoreSlim(1))&lt;/b&gt; { await Task.WhenAll(
newImages. Select( async image =&gt; { // Load data from url. image.Content = await HttpUtils.ReadData(image.Url); &lt;b&gt;await
semaphore.WaitAsync();&lt;/b&gt; try { // Insert image into the database. image.ImageID
= await context.InsertImage(image); } finally { &lt;b&gt;semaphore.Release();&lt;/b&gt; } }));
} &lt;/pre&gt;&lt;/blockquote&gt; 
&lt;p&gt;
So, in the async world we still should care about race conditions.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=9ab00999-60e6-4106-ad73-9e5359ee93c5" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,9ab00999-60e6-4106-ad73-9e5359ee93c5.aspx</comments>
      <category>.NET</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=855a578f-c92f-4bfd-aa5a-4c5e99dd588e</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,855a578f-c92f-4bfd-aa5a-4c5e99dd588e.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,855a578f-c92f-4bfd-aa5a-4c5e99dd588e.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=855a578f-c92f-4bfd-aa5a-4c5e99dd588e</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Having a strong experience in ASP.NET and JSF, we found angular's transclusion
concept is obscure and counterintuitive. It took a while for both of us to grasp the
transclude's ideas described the <a href="https://docs.angularjs.org/guide/directive#creating-a-directive-that-wraps-other-elements">Developer
Guide</a>. We suspect that this is due to the bad design: a bad design leads to a
bad wording.
</p>
        <p>
The other consequence of the bad design is that the transclusion is limited to one
template per directive, which limits the use of the feature.
</p>
        <p>
Consider:
</p>
        <ul>
          <li>
A directive <code>my-page</code> that encapsulates a page with menu and content.</li>
          <li>
            <code>my-page</code> uses <code>templateUrl: my-page.html</code> to render the page.</li>
          <li>
            <code>my-page.html</code> defines two sites where menu and page content have to be
embedded.</li>
          <li>
Two content fragments are passed to <code>my-page</code> to fill content sites.</li>
        </ul>
        <p>
Unfortunately, you cannot immediately implement this design in angularjs. On the other
hand <a href="https://msdn.microsoft.com/en-us/library/wtxbf3hh(v=vs.140).aspx">ASP.NET's
Master Pages</a>, and <a href="http://docs.oracle.com/javaee/6/tutorial/doc/giqxp.html">JSF's
ui:composition</a> readily solve this task. 
</p>
        <p>
Here is one of JSF's approaches:
</p>
        <ol>
          <li>
Define page template my-page.xhtml: <blockquote><code> &lt;html xmlns="http://www.w3.org/1999/xhtml"<br />
  xmlns:ui="http://java.sun.com/jsf/facelets"<br />
  xmlns:h="http://java.sun.com/jsf/html"&gt;<br />
  &lt;h:body&gt;<br />
    &lt;table&gt;<br />
      &lt;tr&gt; 
<br />
        &lt;td&gt;&lt;ui:insert name="menu"/&gt;&lt;/td&gt; 
<br />
      &lt;/tr&gt; 
<br />
      &lt;tr&gt; 
<br />
        &lt;td&gt;&lt;ui:insert name="content"/&gt;&lt;/td&gt; 
<br />
      &lt;/tr&gt; 
<br />
    &lt;/table&gt; 
<br />
  &lt;/h:body&gt;<br />
&lt;/html&gt;</code></blockquote></li>
          <li>
Use <code>ui:composition</code> tag to pass parts to the template: <blockquote><code> &lt;html
xmlns="http://www.w3.org/1999/xhtml"<br />
  xmlns:ui="http://java.sun.com/jsf/facelets"<br />
  xmlns:h="http://java.sun.com/jsf/html"&gt;<br />
  &lt;h:body&gt;<br />
    &lt;ui:composition template="my-page.xhtml"&gt;<br />
      &lt;ui:define name="content"&gt;<br />
        My Content<br />
      &lt;ui:define&gt;<br />
      &lt;ui:define name="menu"&gt;<br />
        &lt;a href="#file"&gt;File&lt;/a&gt;<br />
        &lt;a href="#edit"&gt;Edit&lt;/a&gt;<br />
        &lt;a href="#view"&gt;View&lt;/a&gt;<br />
      &lt;ui:define&gt;<br />
    &lt;/ui:composition&gt; 
<br />
  &lt;/h:body&gt;<br />
&lt;/html&gt;</code></blockquote></li>
        </ol>
        <p>
We have decided to model angular directives after JSF, and have defined three simple
directives: ui-template, ui-insert, ui-define (see <a href="https://github.com/nesterovsky-bros/angularjs-api/blob/master/template/ui-lib.js">angularjs-api/template/ui-lib.js</a>).
</p>
        <p>
To define a template one writes the following markup (see <a href="https://github.com/nesterovsky-bros/angularjs-api/blob/master/template/my-page.html">angularjs-api/template/my-page.html</a>):
</p>
        <blockquote>
          <code>&lt;table ui-template&gt;<br />
  &lt;tr&gt;<br />
    &lt;td ui-insert="menu"&gt;&lt;/td&gt;<br />
  &lt;/tr&gt;<br />
  &lt;tr&gt;<br />
    &lt;td ui-insert="content"&gt;&lt;/td&gt;<br />
  &lt;/tr&gt;<br />
&lt;/table&gt; </code>
        </blockquote>
        <p>
and declares a directive (see <a href="https://github.com/nesterovsky-bros/angularjs-api/blob/master/template/my-page.js">angularjs-api/template/my-page.js</a>):
</p>
        <blockquote>
          <code> var myPage = 
<br />
{<br />
  templateUrl: "my-page.html",<br />
  transclude: true<br />
};<br /><br />
angular.module("app").<br />
  directive("myPage", function() { return myPage; }); </code>
        </blockquote>
        <p>
and finally, to instantiate the directive one needs to write (see <a href="https://github.com/nesterovsky-bros/angularjs-api/blob/master/template/sample.html">angularjs-api/template/sample.html</a>):
</p>
        <blockquote>
          <code>&lt;my-page&gt;<br />
  &lt;div ui-define="content"&gt;<br />
    My content<br />
  &lt;/div&gt;<br />
  &lt;div ui-define="menu"&gt;<br />
    &lt;a href="#file"&gt;File&lt;/a&gt;<br />
    &lt;a href="#edit"&gt;Edit&lt;/a&gt;<br />
    &lt;a href="#view"&gt;View&lt;/a&gt;<br />
  &lt;/div&gt;<br />
&lt;/my-page&gt; </code>
        </blockquote>
        <p>
The working sample can be seen through rawgit: <a href="http://rawgit.com/nesterovsky-bros/angularjs-api/master/template/sample.html">sample.html</a></p>
        <p>
The other sample that integrates with routing can be found at <a href="http://rawgit.com/nesterovsky-bros/angularjs-api/master/template/sample-routing.html">sample-routing.html</a></p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=855a578f-c92f-4bfd-aa5a-4c5e99dd588e" />
      </body>
      <title>Multisite transclusion in Angularjs</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,855a578f-c92f-4bfd-aa5a-4c5e99dd588e.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2015/05/04/MultisiteTransclusionInAngularjs.aspx</link>
      <pubDate>Mon, 04 May 2015 13:07:53 GMT</pubDate>
      <description>  &lt;p&gt;
Having a strong experience in ASP.NET and JSF, we found angular&amp;#39;s transclusion
concept is obscure and counterintuitive. It took a while for both of us to grasp the
transclude&amp;#39;s ideas described the &lt;a href="https://docs.angularjs.org/guide/directive#creating-a-directive-that-wraps-other-elements"&gt;Developer
Guide&lt;/a&gt;. We suspect that this is due to the bad design: a bad design leads to a
bad wording.
&lt;/p&gt;
&lt;p&gt;
The other consequence of the bad design is that the transclusion is limited to one
template per directive, which limits the use of the feature.
&lt;/p&gt;
&lt;p&gt;
Consider:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
A directive &lt;code&gt;my-page&lt;/code&gt; that encapsulates a page with menu and content.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;my-page&lt;/code&gt; uses &lt;code&gt;templateUrl: my-page.html&lt;/code&gt; to render the page.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;my-page.html&lt;/code&gt; defines two sites where menu and page content have to be
embedded.&lt;/li&gt;
&lt;li&gt;
Two content fragments are passed to &lt;code&gt;my-page&lt;/code&gt; to fill content sites.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Unfortunately, you cannot immediately implement this design in angularjs. On the other
hand &lt;a href="https://msdn.microsoft.com/en-us/library/wtxbf3hh(v=vs.140).aspx"&gt;ASP.NET&amp;#39;s
Master Pages&lt;/a&gt;, and &lt;a href="http://docs.oracle.com/javaee/6/tutorial/doc/giqxp.html"&gt;JSF&amp;#39;s
ui:composition&lt;/a&gt; readily solve this task. 
&lt;/p&gt;
&lt;p&gt;
Here is one of JSF&amp;#39;s approaches:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Define page template my-page.xhtml: &lt;blockquote&gt;&lt;code&gt; &amp;lt;html xmlns=&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&lt;br /&gt;
&amp;nbsp; xmlns:ui=&amp;quot;http://java.sun.com/jsf/facelets&amp;quot;&lt;br /&gt;
&amp;nbsp; xmlns:h=&amp;quot;http://java.sun.com/jsf/html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;h:body&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;table&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;tr&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;td&amp;gt;&amp;lt;ui:insert name=&amp;quot;menu&amp;quot;/&amp;gt;&amp;lt;/td&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/tr&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;tr&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;td&amp;gt;&amp;lt;ui:insert name=&amp;quot;content&amp;quot;/&amp;gt;&amp;lt;/td&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/tr&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/table&gt; 
&lt;br /&gt;
&amp;nbsp; &amp;lt;/h:body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/blockquote&gt; 
&lt;/li&gt;
&lt;li&gt;
Use &lt;code&gt;ui:composition&lt;/code&gt; tag to pass parts to the template: &lt;blockquote&gt;&lt;code&gt; &amp;lt;html
xmlns=&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&lt;br /&gt;
&amp;nbsp; xmlns:ui=&amp;quot;http://java.sun.com/jsf/facelets&amp;quot;&lt;br /&gt;
&amp;nbsp; xmlns:h=&amp;quot;http://java.sun.com/jsf/html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;h:body&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ui:composition template=&amp;quot;my-page.xhtml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ui:define name=&amp;quot;content&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; My Content&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ui:define&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ui:define name=&amp;quot;menu&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;a href=&amp;quot;#file&amp;quot;&amp;gt;File&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;a href=&amp;quot;#edit&amp;quot;&amp;gt;Edit&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;a href=&amp;quot;#view&amp;quot;&amp;gt;View&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ui:define&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/ui:composition&amp;gt; 
&lt;br /&gt;
&amp;nbsp; &amp;lt;/h:body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/blockquote&gt; 
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
We have decided to model angular directives after JSF, and have defined three simple
directives: ui-template, ui-insert, ui-define (see &lt;a href="https://github.com/nesterovsky-bros/angularjs-api/blob/master/template/ui-lib.js"&gt;angularjs-api/template/ui-lib.js&lt;/a&gt;).
&lt;/p&gt;
&lt;p&gt;
To define a template one writes the following markup (see &lt;a href="https://github.com/nesterovsky-bros/angularjs-api/blob/master/template/my-page.html"&gt;angularjs-api/template/my-page.html&lt;/a&gt;):
&lt;/p&gt;
&lt;blockquote&gt;&lt;code&gt;&amp;lt;table ui-template&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;td ui-insert=&amp;quot;menu&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;td ui-insert=&amp;quot;content&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt; &lt;/code&gt;&lt;/blockquote&gt; 
&lt;p&gt;
and declares a directive (see &lt;a href="https://github.com/nesterovsky-bros/angularjs-api/blob/master/template/my-page.js"&gt;angularjs-api/template/my-page.js&lt;/a&gt;):
&lt;/p&gt;
&lt;blockquote&gt;&lt;code&gt; var myPage = 
&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; templateUrl: &amp;quot;my-page.html&amp;quot;,&lt;br /&gt;
&amp;nbsp; transclude: true&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
angular.module(&amp;quot;app&amp;quot;).&lt;br /&gt;
&amp;nbsp; directive(&amp;quot;myPage&amp;quot;, function() { return myPage; }); &lt;/code&gt;&lt;/blockquote&gt; 
&lt;p&gt;
and finally, to instantiate the directive one needs to write (see &lt;a href="https://github.com/nesterovsky-bros/angularjs-api/blob/master/template/sample.html"&gt;angularjs-api/template/sample.html&lt;/a&gt;):
&lt;/p&gt;
&lt;blockquote&gt;&lt;code&gt;&amp;lt;my-page&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;div ui-define=&amp;quot;content&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; My content&lt;br /&gt;
&amp;nbsp; &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;div ui-define=&amp;quot;menu&amp;quot;&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;a href=&amp;quot;#file&amp;quot;&amp;gt;File&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;a href=&amp;quot;#edit&amp;quot;&amp;gt;Edit&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;a href=&amp;quot;#view&amp;quot;&amp;gt;View&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/my-page&amp;gt; &lt;/code&gt;&lt;/blockquote&gt; 
&lt;p&gt;
The working sample can be seen through rawgit: &lt;a href="http://rawgit.com/nesterovsky-bros/angularjs-api/master/template/sample.html"&gt;sample.html&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
The other sample that integrates with routing can be found at &lt;a href="http://rawgit.com/nesterovsky-bros/angularjs-api/master/template/sample-routing.html"&gt;sample-routing.html&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=855a578f-c92f-4bfd-aa5a-4c5e99dd588e" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,855a578f-c92f-4bfd-aa5a-4c5e99dd588e.aspx</comments>
      <category>AngularJS</category>
      <category>javascript</category>
      <category>Thinking aloud</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=41875b64-8d10-43bb-9893-d1c124af9f31</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,41875b64-8d10-43bb-9893-d1c124af9f31.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,41875b64-8d10-43bb-9893-d1c124af9f31.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=41875b64-8d10-43bb-9893-d1c124af9f31</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Farewell Entity Framework and hello <a href="https://github.com/StackExchange/dapper-dot-net">Dapper</a>!
</p>
        <p>
For many years we were using <a href="http://msdn.microsoft.com/en-us/data/ef.aspx">Entity
Framework</a>. It's still very popular and Microsoft's primary Object-Relational
Mapper library.
</p>
        <p>
Clearly, the decision is subjective but here are our arguments.
</p>
        <p>
We know and love SQL, and think that in its domain it occupies strong positions. What
SQL leaves out of scope is a bridge between itself and other languages. That's
where ORM should help.
</p>
        <p>
We strongly beleive that no ORM library should try to hide SQL behind the Object's
language itself. We beleive in a separation of roles in development. Database design
and Data Access Layer should be separated from client's logic. Thus, we strive,
if possible, to encapulate data access through SQL functions and stored procedures.
</p>
        <p>
Entity Framework, in contrast, tries to factor out SQL, giving a perspective of object
graph to a client. Initially, it looks promising but at the end a developer should
remember that any object query is mapped back to SQL. Without keeping this in mind
either query won't compile, or performance will be poor. 
<br /><br />
E.g. This query will probably fail to build SQL, as no Regex can be mapped to SQL:
</p>
        <p style="padding-left: 1em">
          <i>
            <code> var result = context.Content.<br />
  Where(data =&gt; Regex.IsMatch(data.Content, pattern)).<br />
  ToArray();</code>
          </i>
        </p>
        <p>
This query might be slow, if no suitble SQL index is defined:
</p>
        <p style="padding-left: 1em">
          <i>
            <code> var result = context.Content.<br />
  Where(data =&gt; data.Field == value).<br />
  ToArray();</code>
          </i>
        </p>
        <p>
Thus no EF's goal is achieved completely, SQL power is limitted, and Data Access
Layer is often fused into other client's logic.
</p>
        <p>
We think that Entity Framework is over-engineered library, which tries to be more
than ORM. Its generality often bumps into limits of SQL support in EF: SQL dialects,
types, operators, functions, and so on. One can observe that people for years appeal
to introduce support of xml, hierarchyid, geometry/geography types, full text search,
and so on. This state cannot be different, as EF will never be able and does not aim
to support all SQL features.
</p>
        <p>
EF has both design-time and runtime. Each database vendor should implement their EF
adapter for EF to play well with that database. This cooperation is not always smooth.
E.g see <a href="http://stackoverflow.com/questions/25089346/database-first-create-entity-framework-6-1-1-model-using-system-data-sqlite-1-0">Database
first create entity framework 6.1.1 model using system.data.sqlite 1.0.93</a>.
</p>
        <p>
At some point the cost of dealing with EF has became too high for us, so we started
to look into an alternatives: from plain ADO.NET to lighter ORM library.
</p>
        <p>
To our delight we have immediately found: <a href="https://github.com/StackExchange/dapper-dot-net#dapper---a-simple-object-mapper-for-net"></a><a href="https://github.com/StackExchange/dapper-dot-net">Dapper
- a simple object mapper for .NET</a>. It provides a simple extensions to <code>IDBConnection</code> interface
to deal with mapping of query parameters to object properties, and of query results
to plain types. Here are some examples:
</p>
        <p style="padding-left: 1em">
          <i>
            <code> // Get Customer<br />
var customer = connection.<br />
  Query&lt;Customer&gt;("select * from Customers where CustomerId = @id", new {
id = customerID }).<br />
  ToSingle(); 
<br /><br />
// Insert a value<br />
connection.Execute("insert into MyTable(A, B) values(@a, @b)", new { a =
2, b = 3 });</code>
          </i>
        </p>
        <p>
So, Dapper leaves you with plain SQL, which we consider as advantage.
</p>
        <p>
Except beeing minimalistic compared to EF, Dapper claims performance close to pure
hand written ADO.NET. Indeed, they build dynamic methods to populate parameters and
to create rows instances, so reflection is used during warm up period only.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=41875b64-8d10-43bb-9893-d1c124af9f31" />
      </body>
      <title>Farewell Entity Framework</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,41875b64-8d10-43bb-9893-d1c124af9f31.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2014/11/30/FarewellEntityFramework.aspx</link>
      <pubDate>Sun, 30 Nov 2014 12:47:46 GMT</pubDate>
      <description>  &lt;p&gt;
Farewell Entity Framework and hello &lt;a href="https://github.com/StackExchange/dapper-dot-net"&gt;Dapper&lt;/a&gt;!
&lt;/p&gt;
&lt;p&gt;
For many years we were using &lt;a href="http://msdn.microsoft.com/en-us/data/ef.aspx"&gt;Entity
Framework&lt;/a&gt;. It&amp;#39;s still very popular and Microsoft&amp;#39;s primary Object-Relational
Mapper library.
&lt;/p&gt;
&lt;p&gt;
Clearly, the decision is subjective but here are our arguments.
&lt;/p&gt;
&lt;p&gt;
We know and love SQL, and think that in its domain it occupies strong positions. What
SQL leaves out of scope is a bridge between itself and other languages. That&amp;#39;s
where ORM should help.
&lt;/p&gt;
&lt;p&gt;
We strongly beleive that no ORM library should try to hide SQL behind the Object&amp;#39;s
language itself. We beleive in a separation of roles in development. Database design
and Data Access Layer should be separated from client&amp;#39;s logic. Thus, we strive,
if possible, to encapulate data access through SQL functions and stored procedures.
&lt;/p&gt;
&lt;p&gt;
Entity Framework, in contrast, tries to factor out SQL, giving a perspective of object
graph to a client. Initially, it looks promising but at the end a developer should
remember that any object query is mapped back to SQL. Without keeping this in mind
either query won&amp;#39;t compile, or performance will be poor. 
&lt;br /&gt;
&lt;br /&gt;
E.g. This query will probably fail to build SQL, as no Regex can be mapped to SQL:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;i&gt;&lt;code&gt; var result = context.Content.&lt;br /&gt;
&amp;nbsp; Where(data =&amp;gt; Regex.IsMatch(data.Content, pattern)).&lt;br /&gt;
&amp;nbsp; ToArray();&lt;/code&gt;&lt;/i&gt;
&lt;/p&gt;
&lt;p&gt;
This query might be slow, if no suitble SQL index is defined:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;i&gt;&lt;code&gt; var result = context.Content.&lt;br /&gt;
&amp;nbsp; Where(data =&amp;gt; data.Field == value).&lt;br /&gt;
&amp;nbsp; ToArray();&lt;/code&gt;&lt;/i&gt;
&lt;/p&gt;
&lt;p&gt;
Thus no EF&amp;#39;s goal is achieved completely, SQL power is limitted, and Data Access
Layer is often fused into other client&amp;#39;s logic.
&lt;/p&gt;
&lt;p&gt;
We think that Entity Framework is over-engineered library, which tries to be more
than ORM. Its generality often bumps into limits of SQL support in EF: SQL dialects,
types, operators, functions, and so on. One can observe that people for years appeal
to introduce support of xml, hierarchyid, geometry/geography types, full text search,
and so on. This state cannot be different, as EF will never be able and does not aim
to support all SQL features.
&lt;/p&gt;
&lt;p&gt;
EF has both design-time and runtime. Each database vendor should implement their EF
adapter for EF to play well with that database. This cooperation is not always smooth.
E.g see &lt;a href="http://stackoverflow.com/questions/25089346/database-first-create-entity-framework-6-1-1-model-using-system-data-sqlite-1-0"&gt;Database
first create entity framework 6.1.1 model using system.data.sqlite 1.0.93&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
At some point the cost of dealing with EF has became too high for us, so we started
to look into an alternatives: from plain ADO.NET to lighter ORM library.
&lt;/p&gt;
&lt;p&gt;
To our delight we have immediately found: &lt;a href="https://github.com/StackExchange/dapper-dot-net#dapper---a-simple-object-mapper-for-net"&gt;&lt;/a&gt;&lt;a href="https://github.com/StackExchange/dapper-dot-net"&gt;Dapper
- a simple object mapper for .NET&lt;/a&gt;. It provides a simple extensions to &lt;code&gt;IDBConnection&lt;/code&gt; interface
to deal with mapping of query parameters to object properties, and of query results
to plain types. Here are some examples:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;i&gt; &lt;code&gt; // Get Customer&lt;br /&gt;
var customer = connection.&lt;br /&gt;
&amp;nbsp; Query&amp;lt;Customer&gt;("select * from Customers where CustomerId = @id", new {
id = customerID }).&lt;br /&gt;
&amp;nbsp; ToSingle(); 
&lt;br /&gt;
&lt;br /&gt;
// Insert a value&lt;br /&gt;
connection.Execute(&amp;quot;insert into MyTable(A, B) values(@a, @b)&amp;quot;, new { a =
2, b = 3 });&lt;/code&gt;&lt;/i&gt;
&lt;/p&gt;
&lt;p&gt;
So, Dapper leaves you with plain SQL, which we consider as advantage.
&lt;/p&gt;
&lt;p&gt;
Except beeing minimalistic compared to EF, Dapper claims performance close to pure
hand written ADO.NET. Indeed, they build dynamic methods to populate parameters and
to create rows instances, so reflection is used during warm up period only.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=41875b64-8d10-43bb-9893-d1c124af9f31" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,41875b64-8d10-43bb-9893-d1c124af9f31.aspx</comments>
      <category>.NET</category>
      <category>Thinking aloud</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=0b757059-c123-4997-83e2-eb04d976edcb</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,0b757059-c123-4997-83e2-eb04d976edcb.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=0b757059-c123-4997-83e2-eb04d976edcb</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Among latest C++ proposals the most ambiguous is <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4021.pdf">N4021</a>. 
</p>
        <p>
The goal of that proposal is <span style="font-style: italic">"to define a 2D drawing
API for the C++ programming language".</span></p>
        <p>
The motivation is going like this:
</p>
        <p style="padding-left: 1em; font-style: italic">
Today, computer graphics are pervasive in modern life, and are even replacing console-style
I/O for basic user interaction on many platforms. For example, a simple <code>cout
&lt;&lt; "Hello, world!"</code> statement doesn’t do anything useful on many tablets
and smartphones. We feel that C++ programmers should have a simple, standard way of
displaying 2D graphics to users.
</p>
        <p>
Authors compare several public and proprietary APIs to select the one named <a href="http://cairographics.org/">cairo
graphics library</a> as a base. 
</p>
        <p>
Reflecting on starting point they write:
</p>
        <p style="padding-left: 1em; font-style: italic">
Taken as a whole, starting from cairo allows for the creation of a 2D C++ drawing
library that is already known to be portable, implementable, and useful without the
need to spend years drafting, implementing, and testing a library to make sure that
it meets those criteria.<br />
...<br />
An alternative design would be to <a href="http://xkcd.com/927/">create a new API
via a synthesis of existing 2D APIs</a>. This has the benefit of being able to avoid
any perceived design flaws that existing APIs suffer from. Unfortunately this would
not have implementation and usage experience. Further, doing so would not provide
any guarantee that design flaws would not creep in.
</p>
        <p>
What follows is a discussion on best way to transform that C library into std style
C++ API.
</p>
        <p>
 
</p>
        <p>
Our thoughts on this proposal are threefold:
</p>
        <ol>
          <li>
This proposal seems a decade or two late.</li>
          <li>
C++ standard should be modular to support basic and optional features.</li>
          <li>
We feel that programmers will not be satisfied with bare 2D graphics. It's not
enough at nowadays.</li>
        </ol>
        <p>
 
</p>
        <p>
Indeed, appeals to create standard C++ API for UI are as old as the C++'s standardization
process. It's clear why did the committee not produce such API yet: they are bureaucracy
that can approve API only. In fact it's a role of community to invent and implement
libraries that may make their way into the standard. Without consensus in community
no standard will reflect such API.
</p>
        <p>
On the other hand C++ spec at present is too fat. Probably, not many people are satisfied
with the pace of its evolution. Any big chunk of a new API makes the progress even
slower. C++ spec should go through a refactoring and be split into core(s) and libraries
and to allow individual progress of each part. This will simplify both specification
and implementation. After that refactoring an API can be added or deprecated much
more easily. In fact implementations were always like this. It's the spec that
tries to be monolith.
</p>
        <p>
As for a new 2D graphics API. It looks like an idea from late 90-es. We think that
today's programmers (at least several samples <img alt=":-)" src="http://www.nesterovsky-bros.com/weblog/smilies/happy.gif" /> )
wished to deal with industry standard UI API, and not to start from basic drawing.
Looking around we observe that html 5 is such de-facto standard. Take into an account
that it supports rich layout, svg, canvas, user input; in addition it's good for
GPU optimization. Even if you want to deal with simple graphics then you can build
svg markup or draw on the canvas.
</p>
        <p>
So, what we rather prefer to see in the C++ spec is an html binding API (both for
DOM and Javascript).
</p>
        <p>
Just think of <strong>standard C++ program</strong> that uses html engine as its UI!
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=0b757059-c123-4997-83e2-eb04d976edcb" />
      </body>
      <title>A Proposal to Add 2D Graphics Rendering and Display to C++</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,0b757059-c123-4997-83e2-eb04d976edcb.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2014/08/17/AProposalToAdd2DGraphicsRenderingAndDisplayToC.aspx</link>
      <pubDate>Sun, 17 Aug 2014 08:56:08 GMT</pubDate>
      <description>  &lt;p&gt;
Among latest C++ proposals the most ambiguous is &lt;a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4021.pdf"&gt;N4021&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
The goal of that proposal is &lt;span style="font-style: italic"&gt;"to define a 2D drawing
API for the C++ programming language".&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
The motivation is going like this:
&lt;/p&gt;
&lt;p style="padding-left: 1em; font-style: italic"&gt;
Today, computer graphics are pervasive in modern life, and are even replacing console-style
I/O for basic user interaction on many platforms. For example, a simple &lt;code&gt;cout
&amp;lt;&amp;lt; "Hello, world!"&lt;/code&gt; statement doesn’t do anything useful on many tablets
and smartphones. We feel that C++ programmers should have a simple, standard way of
displaying 2D graphics to users.
&lt;/p&gt;
&lt;p&gt;
Authors compare several public and proprietary APIs to select the one named &lt;a href="http://cairographics.org/"&gt;cairo
graphics library&lt;/a&gt; as a base. 
&lt;/p&gt;
&lt;p&gt;
Reflecting on starting point they write:
&lt;/p&gt;
&lt;p style="padding-left: 1em; font-style: italic"&gt;
Taken as a whole, starting from cairo allows for the creation of a 2D C++ drawing
library that is already known to be portable, implementable, and useful without the
need to spend years drafting, implementing, and testing a library to make sure that
it meets those criteria.&lt;br /&gt;
...&lt;br /&gt;
An alternative design would be to &lt;a href="http://xkcd.com/927/"&gt;create a new API
via a synthesis of existing 2D APIs&lt;/a&gt;. This has the benefit of being able to avoid
any perceived design flaws that existing APIs suffer from. Unfortunately this would
not have implementation and usage experience. Further, doing so would not provide
any guarantee that design flaws would not creep in.
&lt;/p&gt;
&lt;p&gt;
What follows is a discussion on best way to transform that C library into std style
C++ API.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Our thoughts on this proposal are threefold:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
This proposal seems a decade or two late.&lt;/li&gt;
&lt;li&gt;
C++ standard should be modular to support basic and optional features.&lt;/li&gt;
&lt;li&gt;
We feel that programmers will not be satisfied with bare 2D graphics. It&amp;#39;s not
enough at nowadays.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Indeed, appeals to create standard C++ API for UI are as old as the C++&amp;#39;s standardization
process. It&amp;#39;s clear why did the committee not produce such API yet: they are bureaucracy
that can approve API only. In fact it&amp;#39;s a role of community to invent and implement
libraries that may make their way into the standard. Without consensus in community
no standard will reflect such API.
&lt;/p&gt;
&lt;p&gt;
On the other hand C++ spec at present is too fat. Probably, not many people are satisfied
with the pace of its evolution. Any big chunk of a new API makes the progress even
slower. C++ spec should go through a refactoring and be split into core(s) and libraries
and to allow individual progress of each part. This will simplify both specification
and implementation. After that refactoring an API can be added or deprecated much
more easily. In fact implementations were always like this. It&amp;#39;s the spec that
tries to be monolith.
&lt;/p&gt;
&lt;p&gt;
As for a new 2D graphics API. It looks like an idea from late 90-es. We think that
today&amp;#39;s programmers (at least several samples &lt;img alt=":-)" src="http://www.nesterovsky-bros.com/weblog/smilies/happy.gif"&gt; )
wished to deal with industry standard UI API, and not to start from basic drawing.
Looking around we observe that html 5 is such de-facto standard. Take into an account
that it supports rich layout, svg, canvas, user input; in addition it&amp;#39;s good for
GPU optimization. Even if you want to deal with simple graphics then you can build
svg markup or draw on the canvas.
&lt;/p&gt;
&lt;p&gt;
So, what we rather prefer to see in the C++ spec is an html binding API (both for
DOM and Javascript).
&lt;/p&gt;
&lt;p&gt;
Just think of &lt;strong&gt;standard C++ program&lt;/strong&gt; that uses html engine as its UI!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=0b757059-c123-4997-83e2-eb04d976edcb" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,0b757059-c123-4997-83e2-eb04d976edcb.aspx</comments>
      <category>C++</category>
      <category>Thinking aloud</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=9ca4f9a5-1de8-4ed7-8175-6755a1bd14f6</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,9ca4f9a5-1de8-4ed7-8175-6755a1bd14f6.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,9ca4f9a5-1de8-4ed7-8175-6755a1bd14f6.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=9ca4f9a5-1de8-4ed7-8175-6755a1bd14f6</wfw:commentRss>
      <title>.NET Cache API</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,9ca4f9a5-1de8-4ed7-8175-6755a1bd14f6.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2014/07/28/NETCacheAPI.aspx</link>
      <pubDate>Mon, 28 Jul 2014 05:36:06 GMT</pubDate>
      <description>  &lt;p&gt;
Looking at &lt;a href="http://code.google.com/p/guava-libraries/wiki/CachesExplained"&gt;Guava
Cache&lt;/a&gt; we think its API is more convenient than &lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.caching.memorycache.aspx"&gt;.NET&amp;#39;s
Cache API&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
Just consider: 
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
.NET has getters, and setters of &lt;code&gt;object&lt;/code&gt;s by &lt;code&gt;string&lt;/code&gt; keys. 
&lt;br /&gt;
You should provide caching policy with each setter. 
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
Guava cache operates with typed storage of &lt;code&gt;Key&lt;/code&gt; to &lt;code&gt;Value.&lt;/code&gt;
&lt;br /&gt;
Provides a value factory and a caching policy in advance at cache construction. 
&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Guava&amp;#39;s advantange is based on an idea that homogenous storage assumes a uniform
way of creation of values, and uniform caching policy. Thus a great part of logic
is factored out into a cache initialization. 
&lt;/p&gt;
&lt;p&gt;
We have decided to create a simple adapter of the &lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.caching.memorycache.aspx"&gt;MemoryCache&lt;/a&gt; to
achieve the same goal. Here is a result of such an experiment: 
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; public class Cache&amp;lt;K, V&gt; 
&lt;br /&gt;
&amp;nbsp; where V: class 
&lt;br /&gt;
{ 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// A cache builder. 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp; public struct Builder 
&lt;br /&gt;
&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// A memory cache. If not specified then MemoryCache.Default is
used. 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public MemoryCache MemoryCache; 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// An expiration value. 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Alternatively CachePolicyFunc can be used. 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public TimeSpan Expiration; 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Indicates whether to use sliding (true), or absolute (false) 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// expiration. 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Alternatively CachePolicyFunc can be used. 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public bool Sliding; 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Optional function to get caching policy. 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Alternatively Expiration and Sliding property can be used. 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public Func&amp;lt;V, CacheItemPolicy&gt; CachePolicyFunc; 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Optional value validator. 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public Func&amp;lt;V, bool&gt; Validator; 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// A value factory. 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Alternatively FactoryAsync can be used. 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public Func&amp;lt;K, V&gt; Factory; 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Async value factory. 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Alternatively Factory can be used. 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public Func&amp;lt;K, Task&amp;lt;V&gt;&gt; FactoryAsync; 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// A key to string converter. 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public Func&amp;lt;K, string&gt; KeyFunc; 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Converts builder to a Cache&amp;lt;K, V&gt; instance. 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;param name="builder"&gt;A builder to convert.&amp;lt;/param&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;returns&gt;A Cache&amp;lt;K, V&gt; instance.&amp;lt;/returns&gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public static implicit operator Cache&amp;lt;K, V&gt;(Builder builder) 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return new Cache&amp;lt;K, V&gt;(builder); 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; } 
&lt;br /&gt;
&amp;nbsp; } 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// Creates a cache from a cache builder. 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;param name="builder"&gt;A cache builder instance.&amp;lt;/param&gt; 
&lt;br /&gt;
&amp;nbsp; public Cache(Builder builder) 
&lt;br /&gt;
&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if ((builder.Factory == null) &amp;&amp; (builder.FactoryAsync == null)) 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw new ArgumentException("builder.Factory"); 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; } 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (builder.MemoryCache == null) 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; builder.MemoryCache = MemoryCache.Default; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; } 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; this.builder = builder; 
&lt;br /&gt;
&amp;nbsp; } 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// Cached value by key. 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;param name="key"&gt;A key.&amp;lt;/param&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;returns&gt;A cached value.&amp;lt;/returns&gt; 
&lt;br /&gt;
&amp;nbsp; public V this[K key] 
&lt;br /&gt;
&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return Get(key); } 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; set { Set(key, value); } 
&lt;br /&gt;
&amp;nbsp; } 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// Sets a value for a key. 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;param name="key"&gt;A key to set.&amp;lt;/param&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;param name="value"&gt;A value to set.&amp;lt;/param&gt; 
&lt;br /&gt;
&amp;nbsp; public void Set(K key, V value) 
&lt;br /&gt;
&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; SetImpl(GetKey(key), IsValid(value) ? value : null); 
&lt;br /&gt;
&amp;nbsp; } 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// Gets a value for a key. 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;param name="key"&gt;A key to get value for.&amp;lt;/param&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;returns&gt;A value instance.&amp;lt;/returns&gt; 
&lt;br /&gt;
&amp;nbsp; public V Get(K key) 
&lt;br /&gt;
&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; var keyValue = GetKey(key); 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; var value = builder.MemoryCache.Get(keyValue) as V; 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!IsValid(value)) 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; value = CreateValue(key); 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SetImpl(keyValue, value); 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; } 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return value; 
&lt;br /&gt;
&amp;nbsp; } 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// Gets a task to return an async value. 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;param name="key"&gt;A key.&amp;lt;/param&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;returns&gt;A cached value.&amp;lt;/returns&gt; 
&lt;br /&gt;
&amp;nbsp; public async Task&amp;lt;V&gt; GetAsync(K key) 
&lt;br /&gt;
&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; var keyValue = GetKey(key); 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; var value = builder.MemoryCache.Get(keyValue) as V; 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!IsValid(value)) 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; value = await CreateValueAsync(key); 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SetImpl(keyValue, value); 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; } 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return value; 
&lt;br /&gt;
&amp;nbsp; } 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// Gets string key value for a key. 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;param name="key"&gt;A key.&amp;lt;/param&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;returns&gt;A string key value.&amp;lt;/returns&gt; 
&lt;br /&gt;
&amp;nbsp; protected string GetKey(K key) 
&lt;br /&gt;
&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return builder.KeyFunc != null ? builder.KeyFunc(key) : 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; key == null ? null : key.ToString(); 
&lt;br /&gt;
&amp;nbsp; } 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// Creates a value for a key. 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;param name="key"&gt;A key to create value for.&amp;lt;/param&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;returns&gt;A value instance.&amp;lt;/returns&gt; 
&lt;br /&gt;
&amp;nbsp; protected V CreateValue(K key) 
&lt;br /&gt;
&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return builder.Factory != null ? builder.Factory(key) : 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; builder.FactoryAsync(key).Result; 
&lt;br /&gt;
&amp;nbsp; } 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// Creates a task for value for a key. 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;param name="key"&gt;A key to create value for.&amp;lt;/param&gt;&lt;br /&gt;
&amp;nbsp; /// &amp;lt;returns&gt;A task for a value instance.&amp;lt;/returns&gt; 
&lt;br /&gt;
&amp;nbsp; protected Task&amp;lt;V&gt; CreateValueAsync(K key) 
&lt;br /&gt;
&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return builder.FactoryAsync != null ? builder.FactoryAsync(key)
: 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Task.FromResult(builder.Factory(key)); 
&lt;br /&gt;
&amp;nbsp; } 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// Validates the value. 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;param name="value"&gt;A value to validate.&amp;lt;/param&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;returns&gt; 
&lt;br /&gt;
&amp;nbsp; /// true if value is valid for a cache, and false otherise. 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;/returns&gt; 
&lt;br /&gt;
&amp;nbsp; protected bool IsValid(V value) 
&lt;br /&gt;
&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return (value != null) &amp;&amp; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ((builder.Validator == null) || builder.Validator(value)); 
&lt;br /&gt;
&amp;nbsp; } 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// Set implementation. 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;param name="key"&gt;A key to set value for.&amp;lt;/param&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;param name="value"&gt;A value to set.&amp;lt;/param&gt; 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;returns&gt;A set value.&amp;lt;/returns&gt; 
&lt;br /&gt;
&amp;nbsp; private V SetImpl(string key, V value) 
&lt;br /&gt;
&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (value == null) 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; builder.MemoryCache.Remove(key); 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; } 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; else 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; builder.MemoryCache.Set( 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; key, 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; value, 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; builder.CachePolicyFunc != null ? builder.CachePolicyFunc(value)
: 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; builder.Sliding ? 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new CacheItemPolicy { SlidingExpiration
= builder.Expiration } : 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new CacheItemPolicy 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AbsoluteExpiration
= DateTime.Now + builder.Expiration 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }); 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; } 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return value; 
&lt;br /&gt;
&amp;nbsp; } 
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt; 
&lt;br /&gt;
&amp;nbsp; /// Cache builder. 
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;/summary&gt; 
&lt;br /&gt;
&amp;nbsp; private Builder builder; 
&lt;br /&gt;
} 
&lt;br /&gt;
&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
The use consists of initialization:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; Cache&amp;lt;MyKey, MyValue&gt; MyValues = new Cache&amp;lt;MyKey, MyValue&gt;.Builder 
&lt;br /&gt;
{ 
&lt;br /&gt;
&amp;nbsp; KeyFunc = key =&gt; ...key to string value..., 
&lt;br /&gt;
&amp;nbsp; Factory = key =&gt; ...create a value for a key..., 
&lt;br /&gt;
&amp;nbsp; Expiration = new TimeSpan(0, 3, 0), 
&lt;br /&gt;
&amp;nbsp; Sliding = true 
&lt;br /&gt;
}; &lt;/code&gt; 
&lt;/p&gt;
&lt;p&gt;
and a trivial cache access:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;var value = MyValues[key];&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
This contrasts with MemoryCache coding pattern:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; MemoryCache cache = MemoryCache.Default;&lt;br /&gt;
... &lt;/code&gt; 
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; var keyAsString = ...key to string value...&lt;br /&gt;
var value = cache.Get(keyAsString) as MyValue;&lt;br /&gt;
&lt;br /&gt;
if (value == null)&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; value = ...create a value for a key...&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; cache.Set(keyAsString, value, ...caching policy...);&lt;br /&gt;
} &lt;/code&gt; 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=9ca4f9a5-1de8-4ed7-8175-6755a1bd14f6" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,9ca4f9a5-1de8-4ed7-8175-6755a1bd14f6.aspx</comments>
      <category>.NET</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=8e33a257-619e-412a-b3ac-1947b068fd77</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,8e33a257-619e-412a-b3ac-1947b068fd77.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=8e33a257-619e-412a-b3ac-1947b068fd77</wfw:commentRss>
      <title>IEqualityComparer in LINQ</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,8e33a257-619e-412a-b3ac-1947b068fd77.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2014/07/10/IEqualityComparerInLINQ.aspx</link>
      <pubDate>Thu, 10 Jul 2014 20:31:42 GMT</pubDate>
      <description>  &lt;p&gt;
&lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.linq.enumerable"&gt;Enumerable
class&lt;/a&gt;&lt;/code&gt; contains many overloads with &lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms132151"&gt;IEqualityComparable&amp;lt;T&amp;gt;&lt;/a&gt;&lt;/code&gt; argument.
Most notable methods are:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Contains;&lt;/li&gt;
&lt;li&gt;
Distinct;&lt;/li&gt;
&lt;li&gt;
Except;&lt;/li&gt;
&lt;li&gt;
GroupBy;&lt;/li&gt;
&lt;li&gt;
Intersect;&lt;/li&gt;
&lt;li&gt;
Join;&lt;/li&gt;
&lt;li&gt;
ToDictionary;&lt;/li&gt;
&lt;li&gt;
ToLookup;&lt;/li&gt;
&lt;li&gt;
Union.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Recently we dealt with simple case:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; source.&lt;br /&gt;
&amp;nbsp; Select(&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; item =&amp;gt; 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new Word 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Text = ..., 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LangID = ..., 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Properties = ...&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }).&lt;br /&gt;
&amp;nbsp; Distinct(&lt;span style="color: red"&gt;&lt;b&gt;equality comparer by Text and LangID&lt;/b&gt;&lt;/span&gt;);&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
In other words how do you produce a enumeration of distinct words from a enumeration
of words, where two words are qualified equal if their &lt;code&gt;Text&lt;/code&gt; and &lt;code&gt;LangID&lt;/code&gt; are
equal?
&lt;/p&gt;
&lt;p&gt;
It turns out it&amp;#39;s cumbersome to implement &lt;code&gt;IEqualityComparer&amp;lt;T&amp;gt;&lt;/code&gt; interface
(and any other interface in C#), at least it&amp;#39;s nothing close to a conciseness
of lambda functions.
&lt;/p&gt;
&lt;p&gt;
Here we&amp;#39;ve decided to step in into framework space and to introduce an API to
define simple equality comparers for a class.
&lt;/p&gt;
&lt;p&gt;
We start from the use case:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; var &lt;span style="color: red"&gt;&lt;b&gt;wordComparer&lt;/b&gt;&lt;/span&gt; = KeyEqualityComparer.Null&amp;lt;Word&gt;().&lt;br /&gt;
&amp;nbsp; ThenBy(item =&gt; item.Text).&lt;br /&gt;
&amp;nbsp; ThenBy(item =&gt; item.LangID);&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
source.Select(...).Distinct(&lt;span style="color: red"&gt;&lt;b&gt;wordComparer&lt;/b&gt;&lt;/span&gt;);&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
And then proceed to the API:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;namespace NesterovskyBros.Linq&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; using System;&lt;br /&gt;
&amp;nbsp; using System.Collections;&lt;br /&gt;
&amp;nbsp; using System.Collections.Generic;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt;&lt;br /&gt;
&amp;nbsp; /// A equality comparer extensions.&lt;br /&gt;
&amp;nbsp; /// &amp;lt;/summary&gt;&lt;br /&gt;
&amp;nbsp; public static class KeyEqualityComparer&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Gets null as equality comparer for a type.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;typeparam name="T"&gt;A type.&amp;lt;/typeparam&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;returns&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// null as equality comparer for a type.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/returns&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public static IEqualityComparer&amp;lt;T&gt; Null&amp;lt;T&gt;()&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return null;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Creates an equality comparer for a enumeration item.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;typeparam name="T"&gt;A type.&amp;lt;/typeparam&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;param name="source"&gt;A source items.&amp;lt;/param&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;param name="keyFunc"&gt;A key function.&amp;lt;/param&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;returns&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// null as equality comparer for a type.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/returns&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public static IEqualityComparer&amp;lt;T&gt; EqualityComparerBy&amp;lt;T,
K&gt;(&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this IEnumerable&amp;lt;T&gt; source,&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Func&amp;lt;T, K&gt; keyFunc)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return new KeyEqualityComparer&amp;lt;T, K&gt;(keyFunc);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Creates an equality comparer that uses this comparer as a base.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;typeparam name="T"&gt;A type.&amp;lt;/typeparam&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;typeparam name="K"&gt;A key type.&amp;lt;/typeparam&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;param name="equalityComparer"&gt;A base equality comparer.&amp;lt;/param&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;param name="keyFunc"&gt;A key function.&amp;lt;/param&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;returns&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// An equality comparer that uses this comparer as a base.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/returns&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public static KeyEqualityComparer&amp;lt;T, K&gt; ThenBy&amp;lt;T, K&gt;(&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this IEqualityComparer&amp;lt;T&gt; equalityComparer, 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Func&amp;lt;T, K&gt; keyFunc)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return new KeyEqualityComparer&amp;lt;T, K&gt;(keyFunc, equalityComparer);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; /// &amp;lt;summary&gt;&lt;br /&gt;
&amp;nbsp; /// Equality comparer that uses a function to extract a comparision key.&lt;br /&gt;
&amp;nbsp; /// &amp;lt;/summary&gt;&lt;br /&gt;
&amp;nbsp; /// &amp;lt;typeparam name="T"&gt;A type.&amp;lt;/typeparam&gt;&lt;br /&gt;
&amp;nbsp; /// &amp;lt;typeparam name="K"&gt;A key type.&amp;lt;/typeparam&gt;&lt;br /&gt;
&amp;nbsp; public struct KeyEqualityComparer&amp;lt;T, K&gt;: IEqualityComparer&amp;lt;T&gt;&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Creates an equality comparer.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;param name="keyFunc"&gt;A key function.&amp;lt;/param&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;param name="equalityComparer"&gt;A base equality comparer.&amp;lt;/param&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public KeyEqualityComparer(&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Func&amp;lt;T, K&gt; keyFunc, 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IEqualityComparer&amp;lt;T&gt; equalityComparer = null)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; KeyFunc = keyFunc;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; EqualityComparer = equalityComparer;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;param name="x"&gt;The first object of type T to compare.&amp;lt;/param&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;param name="y"&gt;The second object of type T to compare.&amp;lt;/param&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;returns&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// true if the specified objects are equal; otherwise, false.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/returns&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public bool Equals(T x, T y)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return ((EqualityComparer == null) || EqualityComparer.Equals(x,
y)) &amp;&amp;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; EqualityComparer&amp;lt;K&gt;.Default.Equals(KeyFunc(x),
KeyFunc(y));&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Returns a hash code for the specified object.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;param name="obj"&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// The value for which a hash code is to be returned.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/param&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;returns&gt;A hash code for the specified object.&amp;lt;/returns&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public int GetHashCode(T obj)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var hash = EqualityComparer&amp;lt;K&gt;.Default.GetHashCode(KeyFunc(obj));&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (EqualityComparer != null)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var hash2 = EqualityComparer.GetHashCode(obj);&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; hash ^= (hash2 &amp;lt;&amp;lt; 5) + hash2;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return hash;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// A key function.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public readonly Func&amp;lt;T, K&gt; KeyFunc;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Optional base equality comparer.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public readonly IEqualityComparer&amp;lt;T&gt; EqualityComparer;&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
} &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
So, now you can easily build simple equality comparers to cache them or instantiate
on the fly. This comparers are usually related to property values or their function
of source values.
&lt;/p&gt;
&lt;p&gt;
See also &lt;a href="http://www.nesterovsky-bros.com/weblog/2014/03/07/LINQExtensions.aspx"&gt;LINQ
extensions&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=8e33a257-619e-412a-b3ac-1947b068fd77" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,8e33a257-619e-412a-b3ac-1947b068fd77.aspx</comments>
      <category>.NET</category>
      <category>Thinking aloud</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=56c7dc56-7d3c-4263-b4a9-48cc1fee2aee</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,56c7dc56-7d3c-4263-b4a9-48cc1fee2aee.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,56c7dc56-7d3c-4263-b4a9-48cc1fee2aee.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=56c7dc56-7d3c-4263-b4a9-48cc1fee2aee</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
This is a small post about refactoring <code>lock</code> statements in <code>async</code> methods.
</p>
        <p>
Before refactoring we had a code like this:
</p>
        <p style="padding-left: 1em">
          <code>lock(sync)<br />
{<br />
  result = methodToRefactorIntoAsync();<br />
}<br /><br />
...<br /><br />
private object sync = new object();</code>
        </p>
        <p>
Lock is bound to a thread, thus no way you to use it in <code>async</code> code. As
an alternative you may use <a href="http://msdn.microsoft.com/en-us/library/system.threading.semaphoreslim(v=vs.110).aspx">SemaphoreSlim</a> class:
</p>
        <p style="padding-left: 1em">
          <code> await sync.WaitAsync(cancellationToken);<br /><br />
try<br />
{<br />
  result = await methodAsync(cancellationToken);<br />
}<br />
finally<br />
{<br />
  sync.Release();<br />
}<br /><br />
...<br /><br />
private SemaphoreSlim sync = new SemaphoreSlim(1, 1);<br /></code>
        </p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=56c7dc56-7d3c-4263-b4a9-48cc1fee2aee" />
      </body>
      <title>Async and scarce resources in C#</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,56c7dc56-7d3c-4263-b4a9-48cc1fee2aee.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2014/06/28/AsyncAndScarceResourcesInC.aspx</link>
      <pubDate>Sat, 28 Jun 2014 11:56:32 GMT</pubDate>
      <description>  &lt;p&gt;
This is a small post about refactoring &lt;code&gt;lock&lt;/code&gt; statements in &lt;code&gt;async&lt;/code&gt; methods.
&lt;/p&gt;
&lt;p&gt;
Before refactoring we had a code like this:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;lock(sync)&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; result = methodToRefactorIntoAsync();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
private object sync = new object();&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Lock is bound to a thread, thus no way you to use it in &lt;code&gt;async&lt;/code&gt; code. As
an alternative you may use &lt;a href="http://msdn.microsoft.com/en-us/library/system.threading.semaphoreslim(v=vs.110).aspx"&gt;SemaphoreSlim&lt;/a&gt; class:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; await sync.WaitAsync(cancellationToken);&lt;br /&gt;
&lt;br /&gt;
try&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; result = await methodAsync(cancellationToken);&lt;br /&gt;
}&lt;br /&gt;
finally&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; sync.Release();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
private SemaphoreSlim sync = new SemaphoreSlim(1, 1);&lt;br /&gt;
&lt;/code&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=56c7dc56-7d3c-4263-b4a9-48cc1fee2aee" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,56c7dc56-7d3c-4263-b4a9-48cc1fee2aee.aspx</comments>
      <category>.NET</category>
      <category>Thinking aloud</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=4d14fa41-ded2-40c1-9a0d-cf1af923566b</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,4d14fa41-ded2-40c1-9a0d-cf1af923566b.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=4d14fa41-ded2-40c1-9a0d-cf1af923566b</wfw:commentRss>
      <title>Client disconnects in ASP.NET Web API</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,4d14fa41-ded2-40c1-9a0d-cf1af923566b.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2014/06/27/ClientDisconnectsInASPNETWebAPI.aspx</link>
      <pubDate>Fri, 27 Jun 2014 14:42:44 GMT</pubDate>
      <description>  &lt;p&gt;
What will you do if you have &lt;code&gt;async&lt;/code&gt; Web API method that runs on server
for a some time but your client is dropped?
&lt;/p&gt;
&lt;p&gt;
There are two solutions:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Run method to the end and allow to a framework to deal with disconnect;&lt;/li&gt;
&lt;li&gt;
Try to be notified about client&amp;#39;s drop and to break early.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
The first approach is simplest but might result in some overconsumption of server
resources. The other method requires you to check client status from time to time.
&lt;/p&gt;
&lt;p&gt;
Fortunatelly, ASP.NET provides a &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.httpresponse.clientdisconnectedtoken(v=vs.110).aspx"&gt;HttpResponse.ClientDisconnectedToken&lt;/a&gt; property,
which is limited to IIS 7.5+ in integrated mode, but still fits our needs. So, you
should request &lt;code&gt;ClientDisconnectedToken&lt;/code&gt;, if any, and implement your &lt;code&gt;async&lt;/code&gt; code
using that token. 
&lt;/p&gt;
&lt;p&gt;
The following extension function gets that token:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; using System.Linq;&lt;br /&gt;
using System.Net.Http;&lt;br /&gt;
using System.Threading.Tasks;&lt;br /&gt;
using System.Threading;&lt;br /&gt;
using System.Web;&lt;br /&gt;
&lt;br /&gt;
public static class HttpApiExtensions&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; public static CancellationToken GetCancellationToken(&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; this HttpRequestMessage request)&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; CancellationToken cancellationToken;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; object value;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; var key = typeof(HttpApiExtensions).Namespace + ":CancellationToken";&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (request.Properties.TryGetValue(key, out value))&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return (CancellationToken)value;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; var httpContext = HttpContext.Current;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (httpContext != null)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var httpResponse = httpContext.Response;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (httpResponse != null)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cancellationToken = httpResponse.ClientDisconnectedToken;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; catch&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Do not support cancellation.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; request.Properties[key] = cancellationToken;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return cancellationToken;&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
} &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
And here is a Web API &lt;a href="http://www.nesterovsky-bros.com/weblog/2014/06/25/ParallelVsAsyncInC.aspx"&gt;WordCount
service described in the previous post&lt;/a&gt;:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;using System;&lt;br /&gt;
using System.Collections.Generic;&lt;br /&gt;
using System.Linq;&lt;br /&gt;
using System.Net;&lt;br /&gt;
using System.Net.Http;&lt;br /&gt;
using System.Threading;&lt;br /&gt;
using System.Threading.Tasks;&lt;br /&gt;
&lt;br /&gt;
public class ValuesController: ApiController&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; public async Task&amp;lt;int&gt; GetWordCount([FromUri(Name = "url")] string[] urls)&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; var cancellationToken = &lt;b&gt;Request.GetCancellationToken();&lt;/b&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; using(var client = new HttpClient())&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return (await Task.WhenAll(&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; urls.Select(url =&gt; WordCountAsync(client,
url, cancellationToken)))).Sum();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; public static async Task&amp;lt;int&gt; WordCountAsync(&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; HttpClient client,&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; string url, 
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; CancellationToken cancellationToken)&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; string content = await (await client.GetAsync(url, cancellationToken)).&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Content.ReadAsStringAsync();&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return WordCount(content);&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; private static int WordCount(string text)&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; var count = 0;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; var space = true;&lt;br /&gt;
&lt;br /&gt;&lt; text.Length; ++i)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; for (var i = 0; i &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (space != char.IsWhiteSpace(text[i]))&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; space = !space;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!space)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ++count;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return count;&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
} &lt;/code&gt; 
&lt;/p&gt;
&lt;p&gt;
Though is simple there is a nuisance. You should pass cancellation token here and
there, which adds to a &lt;a href="http://www.nesterovsky-bros.com/weblog/2014/06/23/AsyncCodeInC.aspx"&gt;pollution&lt;/a&gt; from &lt;code&gt;async&lt;/code&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=4d14fa41-ded2-40c1-9a0d-cf1af923566b" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,4d14fa41-ded2-40c1-9a0d-cf1af923566b.aspx</comments>
      <category>.NET</category>
      <category>Thinking aloud</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=b90dd55e-e3eb-4a62-9a3c-696b2caa1d0e</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,b90dd55e-e3eb-4a62-9a3c-696b2caa1d0e.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=b90dd55e-e3eb-4a62-9a3c-696b2caa1d0e</wfw:commentRss>
      <slash:comments>5</slash:comments>
      <title>Parallel vs Async in C#</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,b90dd55e-e3eb-4a62-9a3c-696b2caa1d0e.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2014/06/25/ParallelVsAsyncInC.aspx</link>
      <pubDate>Wed, 25 Jun 2014 12:51:28 GMT</pubDate>
      <description>  &lt;p&gt;
Though parallel and async algorithms solve different tasks, they converge in some
cases. And it&amp;#39;s not always immediately clear what&amp;#39;s the best.
&lt;/p&gt;
&lt;p&gt;
Consider the following task: get a total word count contained in a given a set of
urls.
&lt;/p&gt;
&lt;p&gt;
At first we&amp;#39;ve solved it as a parallel task: indeed this fits to &lt;a href="http://en.wikipedia.org/wiki/MapReduce"&gt;MapReduce&lt;/a&gt; pattern
when you get urls&amp;#39; contents to count the number of words in&amp;nbsp; parallel (Map),
and then sum word counts per each url to get final result (Reduce). But then we decided
that the very same MapReduce algorithm can be implemented with &lt;code&gt;async&lt;/code&gt;.
&lt;/p&gt;
&lt;p&gt;
This is a parallel word count:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; public static int ParallelWordCount(IEnumerable&amp;lt;string&gt; urls)&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; var result = 0;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; Parallel.ForEach(&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; urls,&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; url =&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string content;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; using(var client = new WebClient())&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; content = client.DownloadString(url);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var count = WordCount(content);&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Interlocked.Add(ref result, count);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; });&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; return result;&lt;br /&gt;
} &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Here is &lt;code&gt;async&lt;/code&gt; word count:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; public static async Task&amp;lt;int&gt; WordCountAsync(IEnumerable&amp;lt;string&gt; urls)&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; return (await Task.WhenAll(urls.Select(url =&gt; WordCountAsync(url)))).Sum();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public static async Task&amp;lt;int&gt; WordCountAsync(string url)&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; string content;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; using(var client = new WebClient())&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; content = await client.DownloadStringTaskAsync(url);&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; return WordCount(content);&lt;br /&gt;
} &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
And this is an implementation of word count for a text (it&amp;#39;s less important for
this discussion):
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; public static int WordCount(string text)&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; var count = 0;&lt;br /&gt;
&amp;nbsp; var space = true;&lt;br /&gt;
&lt;br /&gt;&lt; text.Length; ++i)&lt;br /&gt;
&amp;nbsp; for(var i = 0; i &amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (space != char.IsWhiteSpace(text[i]))&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; space = !space;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!space)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ++count;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; return count;&lt;br /&gt;
} &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Our impressions are:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;
The parallel version is contained in one method, while the &lt;code&gt;async&lt;/code&gt; one
is implemeneted with two methods.
&lt;/p&gt;
&lt;p&gt;
This is due to the fact that C# compiler fails to generate &lt;code&gt;async&lt;/code&gt; labmda
function. We attribute this to Microsoft who leads and implements C# spec. Features
should be composable. If one can implement a method as a lambda function, and one
can implement a method as &lt;code&gt;async&lt;/code&gt; then one should be able to implement
a method as an &lt;code&gt;async&lt;/code&gt; lambda function.
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
Both parallel and &lt;code&gt;async&lt;/code&gt; versions are using thread pool to run their logic.
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
While both implementations follow MapReduce pattern, we can see that &lt;code&gt;async&lt;/code&gt; version
is much more scaleable. It&amp;#39;s because of parallel threads stay blocked while waiting
for an http response. On the other hand &lt;code&gt;async&lt;/code&gt; tasks are not bound to
any thread and are just not running while waiting for I/O.
&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
This sample helped us to answer the question as to when to use parallel and when &lt;code&gt;async&lt;/code&gt;.
The &lt;b&gt;simple&lt;/b&gt; answer goes like this:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
if your logic is only CPU bound then use parallel API;&lt;/li&gt;
&lt;li&gt;
otherwise use &lt;code&gt;async&lt;/code&gt; API (this accounts I/O waits).&lt;/li&gt;
&lt;/ul&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=b90dd55e-e3eb-4a62-9a3c-696b2caa1d0e" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,b90dd55e-e3eb-4a62-9a3c-696b2caa1d0e.aspx</comments>
      <category>.NET</category>
      <category>Thinking aloud</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=695e151a-af98-4cc0-afd8-1a14dcba21ed</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,695e151a-af98-4cc0-afd8-1a14dcba21ed.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,695e151a-af98-4cc0-afd8-1a14dcba21ed.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=695e151a-af98-4cc0-afd8-1a14dcba21ed</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Not a long ago C# has introduced special language constructs to simplify asynchronous
programming. It seems <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3858.pdf">C++1x
will follow async trend</a>. But only recently when frameworks like ASP.NET Web API
and Entity Framework started to catch up we've felt how it's to program with <code><a href="http://msdn.microsoft.com/en-us/library/hh156513.aspx">async</a></code> and <code><a href="http://msdn.microsoft.com/en-us/library/hh156528.aspx">await</a></code> keywords.
</p>
        <p>
At first glance it seems it's a pure pleasure to write async methods:
</p>
        <p style="padding-left: 1em">
          <code>private async Task SumPageSizesAsync()<br />
{<br />
  // To use the HttpClient type in desktop apps, you must include a using directive
and add a 
<br />
  // reference for the System.Net.Http namespace.<br />
  HttpClient client = new HttpClient();<br />
  // . . .<br /><br />
  byte[] urlContents = await client.GetByteArrayAsync(url);<br />
  // . . .<br />
}</code>
        </p>
        <p>
To dereference a <code>Task&lt;T&gt;</code> into <code>T</code> you just write <code>await
task_t_expression</code>, mark your method with <code>async</code> specifier, and
adjust output type (if not <code>void</code>) to <code>Task</code> or <code>Task&lt;Result&gt;</code>.
Compiler applies its magic to convert your code into an asynchronous state machine.
</p>
        <p>
We liked this feature and immediately have started to use it. But, as we said, <code>async</code>/<code>await</code> has
shined in full when frameworks made it a core element, and at that point we have started
to see that while  <code>async</code>/<code>await</code> solve the task, they
does not abstract the developer from implementation details, as a code gets considerably
polluted.
</p>
        <p>
Consider a method with pollution marked:
</p>
        <p style="padding-left: 1em">
          <code>public static <b>async</b><b>Task&lt;</b>UserAuthorization<b>&gt;</b> GetAuthorization<b>Async</b>(string
accessToken)<br />
{<br />
  var key = "oauth2:" + accessToken;<br />
  var authorization = cache.Get&lt;UserAuthorization&gt;(key);<br /><br />
  if (authorization != null)<br />
  {<br />
    return authorization;<br />
  }<br /><br />
  using(var model = new ModelContainer())<br />
  {<br />
    authorization =<br /><b>      (await </b>model.UserAuthorizations.<br />
        Where(item =&gt; item.AccessToken == accessToken).<br /><b>        ToListAsync()).</b><br />
      FirstOrDefault();<br />
  }<br /><br />
  if (authorization == null)<br />
  {<br />
    authorization = <b>await </b>Validate<b>Async</b>(accessToken);<br />
  }<br /><br />
  cache.Set(key, cache.ShortDelay, authorization);<br /><br />
  return authorization;<br />
} </code>
        </p>
        <p>
The more you use <code>async</code>, the more pollution you will see in your code.
Ideally we would like to see the method quoted without any marked parts.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=695e151a-af98-4cc0-afd8-1a14dcba21ed" />
      </body>
      <title>Async code in C#</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,695e151a-af98-4cc0-afd8-1a14dcba21ed.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2014/06/23/AsyncCodeInC.aspx</link>
      <pubDate>Mon, 23 Jun 2014 06:15:55 GMT</pubDate>
      <description>  &lt;p&gt;
Not a long ago C# has introduced special language constructs to simplify asynchronous
programming. It seems &lt;a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3858.pdf"&gt;C++1x
will follow async trend&lt;/a&gt;. But only recently when frameworks like ASP.NET Web API
and Entity Framework started to catch up we&amp;#39;ve felt how it&amp;#39;s to program with &lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/hh156513.aspx"&gt;async&lt;/a&gt;&lt;/code&gt; and &lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/hh156528.aspx"&gt;await&lt;/a&gt;&lt;/code&gt; keywords.
&lt;/p&gt;
&lt;p&gt;
At first glance it seems it&amp;#39;s a pure pleasure to write async methods:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;private async Task SumPageSizesAsync()&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; // To use the HttpClient type in desktop apps, you must include a using directive
and add a 
&lt;br /&gt;
&amp;nbsp; // reference for the System.Net.Http namespace.&lt;br /&gt;
&amp;nbsp; HttpClient client = new HttpClient();&lt;br /&gt;
&amp;nbsp; // . . .&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; byte[] urlContents = await client.GetByteArrayAsync(url);&lt;br /&gt;
&amp;nbsp; // . . .&lt;br /&gt;
}&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
To dereference a &lt;code&gt;Task&amp;lt;T&amp;gt;&lt;/code&gt; into &lt;code&gt;T&lt;/code&gt; you just write &lt;code&gt;await
task_t_expression&lt;/code&gt;, mark your method with &lt;code&gt;async&lt;/code&gt; specifier, and
adjust output type (if not &lt;code&gt;void&lt;/code&gt;) to &lt;code&gt;Task&lt;/code&gt; or &lt;code&gt;Task&amp;lt;Result&gt;&lt;/code&gt;.
Compiler applies its magic to convert your code into an asynchronous state machine.
&lt;/p&gt;
&lt;p&gt;
We liked this feature and immediately have started to use it. But, as we said, &lt;code&gt;async&lt;/code&gt;/&lt;code&gt;await&lt;/code&gt; has
shined in full when frameworks made it a core element, and at that point we have started
to see that while&amp;nbsp; &lt;code&gt;async&lt;/code&gt;/&lt;code&gt;await&lt;/code&gt; solve the task, they
does not abstract the developer from implementation details, as a code gets considerably
polluted.
&lt;/p&gt;
&lt;p&gt;
Consider a method with pollution marked:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;public static &lt;b&gt;async&lt;/b&gt; &lt;b&gt;Task&amp;lt;&lt;/b&gt;UserAuthorization&lt;b&gt;&gt;&lt;/b&gt; GetAuthorization&lt;b&gt;Async&lt;/b&gt;(string
accessToken)&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; var key = "oauth2:" + accessToken;&lt;br /&gt;
&amp;nbsp; var authorization = cache.Get&amp;lt;UserAuthorization&gt;(key);&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; if (authorization != null)&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return authorization;&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; using(var model = new ModelContainer())&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; authorization =&lt;br /&gt;
&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (await &lt;/b&gt;model.UserAuthorizations.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Where(item =&gt; item.AccessToken == accessToken).&lt;br /&gt;
&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ToListAsync()).&lt;/b&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FirstOrDefault();&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; if (authorization == null)&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; authorization = &lt;b&gt;await &lt;/b&gt;Validate&lt;b&gt;Async&lt;/b&gt;(accessToken);&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; cache.Set(key, cache.ShortDelay, authorization);&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; return authorization;&lt;br /&gt;
} &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
The more you use &lt;code&gt;async&lt;/code&gt;, the more pollution you will see in your code.
Ideally we would like to see the method quoted without any marked parts.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=695e151a-af98-4cc0-afd8-1a14dcba21ed" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,695e151a-af98-4cc0-afd8-1a14dcba21ed.aspx</comments>
      <category>.NET</category>
      <category>Thinking aloud</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=044c2188-ce3c-43a9-a7aa-0b98d88bb19f</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,044c2188-ce3c-43a9-a7aa-0b98d88bb19f.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,044c2188-ce3c-43a9-a7aa-0b98d88bb19f.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=044c2188-ce3c-43a9-a7aa-0b98d88bb19f</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
After several years of experience with <a href="http://www.telerik.com/kendo-ui">KendoUI</a> we
turned our attention to <a href="https://angularjs.org/">AngularJS</a>. As many other
libraries it has its strong and weak sides. There are many resources describing what
AngularJS is, and what it is not. Our approach to study AngularJS was through an attempt
to integrate it into an existing KendoUI web application. 
</p>
        <p>
It's rather straightforward to convert model from KendoUI into AngularJS, as logically
both frameworks are equal in this regard. But tactically KendoUI implements model-view
binding very differently than AngularJS does. KendoUI binds model to view immediately
per each model field, where AngularJS delays a binding of each model field and performs
whole model binding in one go. Angular's approach is more performant, and even
more appealing to a developer, though the problem is that the time it takes to make
whole model binding is proportional to a size (number of objects and properties) of
model. This means that if you have a relatively big model you will experience tangible
halts in browser's UI while a javascript updating view/model is running.
</p>
        <p>
AngularJS advices some workaround, which in essence is to avoid big model. The problem
is that a couple of thousands or even several hundrends of objects and properties
are already considered big model. So, you should immediately plan your model, and
view to avoid any potential impact. This seriously distracts from the task your're
solving.
</p>
        <p>
The idea that your UI will halt for the time proportional to the size of your whole
model looks flawed in our opinion. KendoUI knows no such a problem. That's the
reason why our KendoUI to AngularJS transition experience was not smooth.
</p>
        <p>
Our analysis of AngularJS sources shows that the issue could be resolved provided
model to view binding (it's called digest in that library) was asynchronous.
</p>
        <p>
To verify our ideas we have created a branch <a href="https://github.com/nesterovsky-bros/angular.js">nesterovsky-bros/angular.js</a> where
we implemented required refactorings. It includes: 
</p>
        <ul>
          <li>
API based on existing deferred/promise to write algorithms in async way, and 
</li>
          <li>
refactored digest logic.</li>
        </ul>
        <p>
At the end we have proposed to integrate our changes into the main branch: <a href="https://github.com/angular/angular.js/pull/7548">Make
$digest async</a>.
</p>
        <p>
We're not sure whether our proposition will be integrated (rather no than yes).
Nevertheless what we have come with is an interesting extension of deferred object
that we neither have seen in AngularJS nor in JQuery, so later we will quote that
API from <a href="https://github.com/nesterovsky-bros/angular.js/blob/master/src/ng/q.js">q.js</a> and <a href="https://github.com/nesterovsky-bros/angular.js/blob/master/src/ng/scheduler.js">scheduler.js</a>.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=044c2188-ce3c-43a9-a7aa-0b98d88bb19f" />
      </body>
      <title>AngularJS</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,044c2188-ce3c-43a9-a7aa-0b98d88bb19f.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2014/05/25/AngularJS.aspx</link>
      <pubDate>Sun, 25 May 2014 08:02:41 GMT</pubDate>
      <description>  &lt;p&gt;
After several years of experience with &lt;a href="http://www.telerik.com/kendo-ui"&gt;KendoUI&lt;/a&gt; we
turned our attention to &lt;a href="https://angularjs.org/"&gt;AngularJS&lt;/a&gt;. As many other
libraries it has its strong and weak sides. There are many resources describing what
AngularJS is, and what it is not. Our approach to study AngularJS was through an attempt
to integrate it into an existing KendoUI web application. 
&lt;/p&gt;
&lt;p&gt;
It&amp;#39;s rather straightforward to convert model from KendoUI into AngularJS, as logically
both frameworks are equal in this regard. But tactically KendoUI implements model-view
binding very differently than AngularJS does. KendoUI binds model to view immediately
per each model field, where AngularJS delays a binding of each model field and performs
whole model binding in one go. Angular&amp;#39;s approach is more performant, and even
more appealing to a developer, though the problem is that the time it takes to make
whole model binding is proportional to a size (number of objects and properties) of
model. This means that if you have a relatively big model you will experience tangible
halts in browser&amp;#39;s UI while a javascript updating view/model is running.
&lt;/p&gt;
&lt;p&gt;
AngularJS advices some workaround, which in essence is to avoid big model. The problem
is that a couple of thousands or even several hundrends of objects and properties
are already considered big model. So, you should immediately plan your model, and
view to avoid any potential impact. This seriously distracts from the task your&amp;#39;re
solving.
&lt;/p&gt;
&lt;p&gt;
The idea that your UI will halt for the time proportional to the size of your whole
model looks flawed in our opinion. KendoUI knows no such a problem. That&amp;#39;s the
reason why our KendoUI to AngularJS transition experience was not smooth.
&lt;/p&gt;
&lt;p&gt;
Our analysis of AngularJS sources shows that the issue could be resolved provided
model to view binding (it&amp;#39;s called digest in that library) was asynchronous.
&lt;/p&gt;
&lt;p&gt;
To verify our ideas we have created a branch &lt;a href="https://github.com/nesterovsky-bros/angular.js"&gt;nesterovsky-bros/angular.js&lt;/a&gt; where
we implemented required refactorings. It includes: 
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
API based on existing deferred/promise to write algorithms in async way, and 
&lt;/li&gt;
&lt;li&gt;
refactored digest logic.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
At the end we have proposed to integrate our changes into the main branch: &lt;a href="https://github.com/angular/angular.js/pull/7548"&gt;Make
$digest async&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
We&amp;#39;re not sure whether our proposition will be integrated (rather no than yes).
Nevertheless what we have come with is an interesting extension of deferred object
that we neither have seen in AngularJS nor in JQuery, so later we will quote that
API from &lt;a href="https://github.com/nesterovsky-bros/angular.js/blob/master/src/ng/q.js"&gt;q.js&lt;/a&gt; and &lt;a href="https://github.com/nesterovsky-bros/angular.js/blob/master/src/ng/scheduler.js"&gt;scheduler.js&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=044c2188-ce3c-43a9-a7aa-0b98d88bb19f" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,044c2188-ce3c-43a9-a7aa-0b98d88bb19f.aspx</comments>
      <category>AngularJS</category>
      <category>javascript</category>
      <category>kendoui</category>
      <category>Thinking aloud</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=8cac7e9a-f811-488b-844b-85d983ba534b</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,8cac7e9a-f811-488b-844b-85d983ba534b.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,8cac7e9a-f811-488b-844b-85d983ba534b.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=8cac7e9a-f811-488b-844b-85d983ba534b</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
These are initial positions for this writing: 
</p>
        <ul>
          <li>
SQL Server allows to execute dynamic SQL.</li>
          <li>
Dynamic SQL is useful and often unavoidable, e.g. when you have to filter or order
data in a way that you cannot code efficiently in advance.</li>
          <li>
Dynamic SQL has proven to be a dangerous area, as with improper use it can open hole
in a security.</li>
        </ul>
        <p>
In general nothing stops you from building and then excuting of SQL string. Our goal,
however, is to define rules that make work with dynamic SQL is more managable and
verifiable. 
</p>
        <p>
Here we outline these rules, and then give some examples and tips. 
</p>
        <p>
          <strong>Rule #1. Isolate dynamic SQL</strong>
        </p>
        <p>
Put all logic related to building of dynamic SQL into a separate function.<br />
We usually define a separate scheme <code>Dynamic</code>, and define functions like <code>Dynamic.GetSQL_XXX(params)</code>.<br />
This makes it simple to perform code review. 
</p>
        <p>
          <strong>Rule #2. Xml as parameters</strong>
        </p>
        <p>
Use <code>xml</code> type to pass parameters to a function that builds dynamic SQL.<br />
In many cases dynamic SQL depends on variable number of parameters (like a list of
values to check against). 
<br />
Xml fits here to represent structured information.<br />
On a client (e.g. in C# or java) you can define a class with all parameters, populate
an instance and serialize it to an xml. 
</p>
        <p>
          <strong>Rule #3. XQuery as template language</strong>
        </p>
        <p>
Use XQuery to define SQL template and to generate SQL tree from the input parameters.<br />
Here is an example of such XQuery:
</p>
        <p style="padding-left: 1em">
          <code>@data.query('<br />
&lt;sql&gt;<br />
select<br />
T.*<br />
from<br />
Data.Ticket T<br />
where<br />
{<br />
for $ticketID in data/ticketID return<br />
&lt;sql&gt;(T.TicketID = &lt;int&gt;{$ticketID}&lt;/int&gt;) and &lt;/sql&gt;<br />
}<br />
(1 = 1)<br />
&lt;/sql&gt;')</code>
        </p>
        <p>
You can see that output is an xml with <code>sql</code> element to represent literal
SQL, and <code>int</code> element to represent integer literal. 
</p>
        <p>
In fact whole output schema can be defined like this:
</p>
        <p>
          <code>&lt;xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"&gt;<br />
&lt;xs:element name="sql"/&gt;<br />
&lt;xs:element name="name"/&gt;<br />
&lt;xs:element name="string" nillable="true"/&gt;<br />
&lt;xs:element name="int" nillable="true"/&gt;<br />
&lt;xs:element name="decimal" nillable="true"/&gt;<br />
&lt;xs:element name="date" nillable="true"/&gt;<br />
&lt;xs:element name="time" nillable="true"/&gt;<br />
&lt;xs:element name="datetime" nillable="true"/&gt;<br />
&lt;/xs:schema&gt; </code>
        </p>
        <p>
where <code>sql</code> is to represent literal content, <code>name</code> to represent
a name, and other elements to represent different literal values.
</p>
        <p>
          <strong>Rule #4. Escape literals</strong>
        </p>
        <p>
Use function <code>Dynamic.ToSQL(@template)</code> to build final SQL text.<br />
Here we quote the definition:
</p>
        <p style="padding-left: 1em">
          <code>-- Builds a text of SQL function for an sql template.<br />
create function Dynamic.ToSQL 
<br />
( 
<br />
-- SQL template. 
<br />
@template xml 
<br />
) 
<br />
returns nvarchar(max) 
<br />
with returns null on null input 
<br />
as 
<br />
begin 
<br />
return 
<br />
( 
<br />
select<br />
case 
<br />
when N.Node.exist('*[xs:boolean(@xsi:nil)]') = 1 then 
<br />
'null' 
<br /><br />
when N.Node.exist('self::int') = 1 then 
<br />
isnull(N.Node.value('xs:int(.)', 'nvarchar(max)'), '# int #') 
<br /><br />
when N.Node.exist('self::string') = 1 then 
<br />
'N''' + 
<br />
replace 
<br />
( 
<br />
N.Node.value('.', 'nvarchar(max)'),<br />
'''', 
<br />
'''''' 
<br />
) + 
<br />
'''' 
<br /><br />
when N.Node.exist('self::name') = 1 then 
<br />
isnull 
<br />
( 
<br />
quotename(N.Node.value('.', 'nvarchar(128)'), '['), 
<br />
'# name #' 
<br />
) 
<br /><br />
when N.Node.exist('self::datetime') = 1 then 
<br />
isnull 
<br />
( 
<br />
'convert(datetime2, ''' + 
<br />
N.Node.value('xs:dateTime(.)', 'nvarchar(128)') + 
<br />
''', 126)', 
<br />
'# datetime #' 
<br />
) 
<br /><br />
when N.Node.exist('self::date') = 1 then 
<br />
isnull 
<br />
( 
<br />
'convert(date, ''' + 
<br />
N.Node.value('xs:date(.)', 'nvarchar(128)') + 
<br />
''', 126)', 
<br />
'# date #' 
<br />
) 
<br /><br />
when N.Node.exist('self::time') = 1 then 
<br />
isnull 
<br />
( 
<br />
'convert(time, ''' + 
<br />
N.Node.value('xs:time(.)', 'nvarchar(128)') + 
<br />
''', 114)', 
<br />
'# time #' 
<br />
) 
<br /><br />
when N.Node.exist('self::decimal') = 1 then 
<br />
isnull 
<br />
( 
<br />
N.Node.value('xs:decimal(.)', 'nvarchar(128)'), 
<br />
'# decimal #' 
<br />
) 
<br /><br />
when N.Node.exist('self::*') = 1 then 
<br />
'# invalid template #' 
<br /><br />
else 
<br />
N.Node.value('.', 'nvarchar(max)') 
<br />
end 
<br />
from 
<br />
@template.nodes('//sql/node()[not(self::sql)]') N(Node) 
<br />
for xml path(''), type<br />
).value('.', 'nvarchar(max)'); 
<br />
end; </code>
        </p>
        <p>
Now, we want to stress that this function plays an important role in prevention of
the SQL injection, as it escapes literals from the SQL tree.
</p>
        <p>
          <strong>Rule #5 (optional). Collect data</strong>
        </p>
        <p>
Use SQL to collect additional data required to build dynamic SQL. Here is an example
of how we get a <code>Ticket</code> by <code>StatusID</code>, while on input we receive
a <code>StatusName</code>:
</p>
        <p style="padding-left: 1em">
          <code>create function Dynamic.GetSQL_GetTicketByStatus(@data xml)<br />
returns nvarchar(max)<br />
as<br />
begin<br /><span style="color: red"> set @data = 
<br />
(<br />
select 
<br />
@data, 
<br />
(<br />
select<br />
T.StatusID<br />
from<br />
@data.nodes('/data/status') N(Node)<br />
inner join<br />
Metadata.Status T<br />
on<br />
T.StatusName = Node.value('.', 'nvarchar(128)')<br />
for xml auto, type, elements<br />
) 
<br />
for xml path('')<br />
);<br /></span><br />
return Dynamic.ToSQL<br />
(<br />
@data.query<br />
('<br />
&lt;sql&gt;<br />
select<br />
T.*<br />
from<br />
Data.Ticket T<br />
where<br />
T.Status in ({ for $status in /T/StatusID return &lt;sql&gt;&lt;int&gt;{$status}&lt;/int&gt;,&lt;/sql&gt;
} null)<br />
&lt;/sql&gt;<br />
')<br />
);<br />
end; </code>
        </p>
        <p>
Notice code in red that collects some more data before calling XQuery.
</p>
        <p>
          <strong>Rule #6. Execute</strong>
        </p>
        <p>
The final step is to call dynamic SQL.<br />
This is done like this:
</p>
        <p style="padding-left: 1em">
          <code>-- build<br />
declare @sql nvarchar(max) = Dynamic.GetSQL_GetTicket(@data);<br /><br />
-- execute<br />
execute sp_executesql 
<br />
@sql<br />
-- {, N'@parameter_name data_type [ OUT | OUTPUT ][ ,...n ]' } 
<br />
-- { , [ @param1 = ] 'value1' [ ,...n ] }<br />
with result sets<br />
( 
<br />
(<br />
TicketID int not null,<br />
CreatedAt datetime2 not null,<br />
Summary nvarchar(256) null,<br />
Status int,<br />
Severity int,<br />
DeadLineAt datetime2 null<br />
)<br />
);</code>
        </p>
        <p>
Notice that the use of dynamic SQL does not prevent static parameters.<br />
Notice also that <code>with result sets</code> clause is used to specify output.
</p>
        <p>
          <strong>Example. Tickets system</strong>
        </p>
        <p>
Let's assume you're dealing with a tickets system (like Bugzilla), and you
have a table <code>Data.Ticket</code> to describe tickets. Assume that DDL for this
table is like this:
</p>
        <p style="padding-left: 1em">
          <code>create table Data.Ticket<br />
(<br />
TicketID bigint not null primary key,<br />
CreatedAt datetime2 not null,<br />
Summary nvarchar(128) null,<br />
Status int not null,<br />
UpdatedAt datetime2(7) not null<br />
) </code>
        </p>
        <p>
Suppose you have to build C# code to search different tickets, where Entity Framework
is used to access the database.<br />
Search should be done by a range of <code>CreatedAt</code>, a range of <code>UpdatedAt</code>, <code>Summary</code>,
or by different <code>Status</code> values. It should be possible to order results
in different ways.
</p>
        <p>
We start out solution from the C# and define classes for a request:
</p>
        <p style="padding-left: 1em">
          <code> public enum Direction<br />
{<br />
Asc,<br />
Desc<br />
}<br /><br />
public struct Order 
<br />
{<br />
public string Field { get; set; }<br />
public Direction Direction {get; set; }<br />
}<br /><br />
public class DateRange<br />
{<br />
public DateTime? From { get; set; }<br /><br />
// This property is to omit From element if value is null.<br />
// See rules for xml serialization.<br />
public bool FromSpecified { get { return From != null; } }<br /><br />
public DateTime? To { get; set; }<br />
public bool ToSpecified { get { return To != null; } }<br />
}<br /><br />
public class TicketsRequest<br />
{<br />
public DateRange CreatedAt { get; set; }<br />
public string Summary { get; set; }<br />
public DateRange UpdatedAt { get; set; }<br />
[XmlElement]<br />
public Order[] Order { get; set; }<br />
[XmlElement]<br />
public int[] Status { get; set; }<br />
} </code>
        </p>
        <p>
Notice that we're going to use <code>XmlSerializer</code> to convert request to
xml and then to pass parameter into EF's model. Here is utility method to perform
such conversion:
</p>
        <p style="padding-left: 1em">
          <code> public static string ToXmlString&lt;T&gt;(T value)<br />
{<br />
if (value == null)<br />
{<br />
return null;<br />
}<br /><br />
var serializer = new XmlSerializer(typeof(T));<br />
var builder = new StringBuilder();<br /><br />
var writer = XmlWriter.Create(<br />
builder,<br />
new XmlWriterSettings<br />
{<br />
OmitXmlDeclaration = true,<br />
Indent = false<br />
});<br /><br />
serializer.Serialize(writer, value);<br />
writer.Flush();<br /><br />
return builder.ToString();<br />
} </code>
        </p>
        <p>
Now we proceed to the database and define a procedure that runs the search:
</p>
        <p style="padding-left: 1em">
          <code>-- Gets tickets.<br />
create procedure Data.GetTickets<br />
(<br />
-- A query parameters.<br />
@params xml<br />
)<br />
as<br />
begin<br />
set nocount on;<br /><br />
-- This is for EF to guess type of result.<br />
if (1 = 0)<br />
begin<br />
select<br />
TicketID,<br />
CreatedAt,<br />
Summary,<br />
Status,<br />
UpdatedAt<br />
from<br />
Data.Ticket;<br />
end;<br /><br />
declare @sql nvarchar(max) = Dynamic.GetSQL_GetTickets(@params);<br /><br />
execute sp_executesql @sql<br />
with result sets<br />
( 
<br />
(<br />
TicketID int not null,<br />
CreatedAt datetime2 not null,<br />
Summary nvarchar(256) null,<br />
Status int,<br />
UpdatedAt datetime2 null<br />
)<br />
);<br />
end; </code>
        </p>
        <p>
Switch back to C#, import the <code>Data.GetTickets</code> into the EF model, and
create a search method:
</p>
        <p style="padding-left: 1em">
          <code> public IEnumerable&lt;Ticket&gt; GetTickets(TicketsRequest request)<br />
{ 
<br />
var model = new Model();<br /><br />
return model.GetTickets(ToXmlString(request));<br />
} </code>
        </p>
        <p>
The last ingredient is <code>Dynamic.GetSQL_GetTickets()</code> function.
</p>
        <p style="padding-left: 1em">
          <code>create function Dynamic.GetSQL_GetTickets(@data xml)<br />
returns nvarchar(max)<br />
as<br />
begin<br />
return Dynamic.ToSQL<br />
(<br />
@data.query('<br />
&lt;sql&gt;<br />
select<br />
T.TicketID,<br />
T.CreatedAt,<br />
T.Summary,<br />
T.Status,<br />
T.UpdatedAt<br />
from<br />
Data.Ticket T<br />
where<br />
{<br />
for $range in */CreatedAt return<br />
(<br />
for $date in $range/From return<br />
&lt;sql&gt;<br />
(T.CreatedAt &gt;= &lt;datetime&gt;{$date}&lt;/datetime&gt;) and<br />
&lt;/sql&gt;,<br /><br />
for $date in $range/To return<br />
&lt;sql&gt;<br />
(&lt;datetime&gt;{$date}&lt;/datetime&gt; &gt; T.CreatedAt) and<br />
&lt;/sql&gt;<br />
),<br /><br />
for $range in */UpdatedAt return<br />
(<br />
for $date in $range/From return<br />
&lt;sql&gt;<br />
(T.UpdatedAt &gt;= &lt;datetime&gt;{$date}&lt;/datetime&gt;) and<br />
&lt;/sql&gt;,<br /><br />
for $date in $range/To return<br />
&lt;sql&gt;<br />
(&lt;datetime&gt;{$date}&lt;/datetime&gt; &gt; T.UpdatedAt) and<br />
&lt;/sql&gt;<br />
),<br /><br />
for $summary in */Summary return<br />
&lt;sql&gt;<br />
(T.Summary like &lt;string&gt;{$summary}&lt;/string&gt;) and<br />
&lt;/sql&gt;,<br /><br />
if (*/Status) then<br />
&lt;sql&gt;<br />
T.Status in 
<br />
({<br />
for $status in */Status return<br />
&lt;sql&gt;&lt;int&gt;{$status}&lt;/int&gt;, &lt;/sql&gt;<br />
} null) and<br />
&lt;/sql&gt;<br />
else ()<br />
}<br />
(1 = 1)<br />
order by<br />
{<br />
for $order in 
<br />
*/Order 
<br />
[<br />
Field = ("TicketID", "CreatedAt", "Summary", "UpdatedAt", "Status")<br />
]<br />
return<br />
&lt;sql&gt;<br />
&lt;name&gt;{$order/Field}&lt;/name&gt;<br />
{" desc"[$order[Direction = "Desc"]]},<br />
&lt;/sql&gt;<br />
}<br />
(select null)<br />
&lt;/sql&gt;<br />
') 
<br />
);<br />
end;</code>
        </p>
        <p>
          <strong>SQL text from Dynamic.GetSQL_GetTickets()</strong>
        </p>
        <p>
Consider now SQL text produced by this function. For an input:
</p>
        <p style="padding-left: 1em">
          <code>&lt;TicketsRequest&gt;<br />
&lt;CreatedAt&gt;<br />
&lt;From&gt;2014-01-01T00:00:00&lt;/From&gt;<br />
&lt;/CreatedAt&gt;<br />
&lt;Summary&gt;hello%&lt;/Summary&gt;<br />
&lt;Order&gt;<br />
&lt;Field&gt;Status&lt;/Field&gt;<br />
&lt;Direction&gt;Desc&lt;/Direction&gt;<br />
&lt;/Order&gt;<br />
&lt;Status&gt;1&lt;/Status&gt;<br />
&lt;Status&gt;3&lt;/Status&gt;<br />
&lt;/TicketsRequest&gt;</code>
        </p>
        <p>
the output is:
</p>
        <p style="padding-left: 1em">
          <code> select<br />
T.TicketID,<br />
T.CreatedAt,<br />
T.Summary,<br />
T.Status,<br />
T.UpdatedAt<br />
from<br />
Data.Ticket T<br />
where<br /><br />
(T.CreatedAt &gt;= convert(datetime2, '2014-01-01T00:00:00', 126)) and<br /><br />
(T.Summary like N'hello%') and<br /><br />
T.Status in 
<br />
(1, 3, null) and<br /><br />
(1 = 1)<br />
order by<br />
[Status] desc,<br /><br />
(select null)<br /></code>
        </p>
        <p>
Though the text is not formatted as we would like, it's perfectly valid SQL.
</p>
        <p>
          <strong>Tips for building XQuery templates</strong>
        </p>
        <p>
What is called XQuery in SQL Server is in fact a very limited subset of XQuery 1.0.
Microsoft clearly states this fact. What is trivial in XQuery is often impossible
or ugly in XQuery of SQL Server. 
</p>
        <p>
Nevertheless XQuery in SQL Server works rather well as SQL template language. To make
it most efficient, however, you should learn several tips. 
</p>
        <p>
          <strong>Tip #1. Where clause</strong>
        </p>
        <p>
In template you might want to build a <code>where</code> clause: 
</p>
        <p style="padding-left: 1em">
          <code>&lt;sql&gt;<br />
select 
<br />
... 
<br />
where 
<br />
{<br />
if (...) then<br />
&lt;sql&gt;...&lt;/sql&gt;<br />
else ()<br />
}<br />
&lt;/sql&gt;</code>
        </p>
        <p>
and it might happen that for a certain input a condition under <code>where</code> might
collapse, and you will be left with <code>where</code> keyword without a real condition,
which is wrong. A simple work around is to always add some true condition under ther <code>where</code> like
this:
</p>
        <p style="padding-left: 1em">
          <code>&lt;sql&gt;<br />
select 
<br />
... 
<br />
where 
<br />
{<br />
if (...) then<br />
&lt;sql&gt;... <span style="color: red">and</span> &lt;/sql&gt;<br />
else ()<br />
} <span style="color: red">(1 = 1)</span><br />
&lt;/sql&gt;</code>
        </p>
        <p>
          <strong>Tip #2. "in" expression</strong>
        </p>
        <p>
If you want to generate "in" expression like this:
</p>
        <p style="padding-left: 1em">
          <code>value in (item1, item2,...)</code>
        </p>
        <p>
then you might find that it's much easier generate equivalent a code like this: 
</p>
        <p style="padding-left: 1em">
          <code>value in (item1, item2,..., null)</code>.
</p>
        <p>
Here is a XQuery to generate such template:
</p>
        <p style="padding-left: 1em">
          <code>value in 
<br />
({<br />
for $item in ... return<br />
&lt;sql&gt;&lt;int&gt;{$item}&lt;/int&gt;, &lt;/sql&gt;<br />
} null) and</code>
        </p>
        <p>
          <strong>Tip #3. Order by</strong>
        </p>
        <p>
You can conclude an <code>order by</code> clause built from a data with a dummy expression
like this:
</p>
        <p style="padding-left: 1em">
          <code>order by<br />
{<br />
for $item in ... return<br />
&lt;sql&gt;<br />
&lt;name&gt;{$item/Field}&lt;/name&gt;<br />
{" desc"[$item/Direction = "Desc"]},<br />
&lt;/sql&gt;<br />
} <span style="color: red">(select null)</span></code>
        </p>
        <p>
Alternatively you can use first column from a clustered index.
</p>
        <p>
          <strong>Tip #4. Group by</strong>
        </p>
        <p>
In a <code>group by</code> clause we cannot introduce terminator expression as it
was with <code>order by</code>, so a code is a less trivial:
</p>
        <p style="padding-left: 1em">
          <code>{<br />
let $items := ... return<br /><br />
if ($items) then<br />
&lt;sql&gt;<br />
group by &lt;name&gt;{$items[1]}&lt;/name&gt;<br />
{<br />
for $item in $items[position() &gt; 1] return<br />
&lt;sql&gt;, &lt;name&gt;{$item}&lt;/name&gt;&lt;/sql&gt;<br />
      }<br />
&lt;/sql&gt;<br />
else ()<br />
}</code>
        </p>
        <p>
In fact similar logic may work with <code>order by</code>.
</p>
        <p>
          <strong>Tip #5. Escape literals</strong>
        </p>
        <p>
It's crusial not to introduce SQL injection while building SQL. Thus use:
</p>
        <p style="padding-left: 1em">
          <code>&lt;int&gt;{...}&lt;/int&gt;</code> - for literal int;<br /><code>&lt;decimal&gt;{...}&lt;/decimal&gt;</code> - for literal decimal;<br /><code>&lt;string&gt;{...}&lt;/string&gt;</code> - for literal string;<br /><code>&lt;datetime&gt;{...}&lt;/datetime&gt;</code> - for literal datetime2;<br /><code>&lt;date&gt;{...}&lt;/date&gt;</code> - for literal date;<br /><code>&lt;time&gt;{...}&lt;/time&gt;</code> - for literal time;<br /><code>&lt;name&gt;{...}&lt;/name&gt;</code> - for a name to quote.
</p>
        <p>
Note that you can use <code>xsi:nil</code>, so <code>&lt;int xsi:nil="true"/&gt;</code> means <code>null</code>.
</p>
        <p>
If you generate a field name from an input data then it worth to validate it against
a list of available names.
</p>
        <p>
          <strong>Tip #6. Validate input.</strong>
        </p>
        <p>
It worth to define xml schema for an input xml, and to validate parameters against
it.<br />
This makes code more secure, and also adds a documentation.
</p>
        <p>
          <strong>Tip #7. Don't abuse dynamic SQL</strong>
        </p>
        <p>
There are not too many cases when you need a dynamic SQL. Usually SQL engine knows
how to build a good execution plan. If your query contains optional conditions then
you can write it a way that SQL Server can optimize, e.g.:
</p>
        <p style="padding-left: 1em">
          <code> select<br />
*<br />
from<br />
T<br />
where<br />
((@name is null) or (Name = @name)) and<br />
((@date is null) or (Date = @date))<br />
option(recompile)</code>
        </p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=8cac7e9a-f811-488b-844b-85d983ba534b" />
      </body>
      <title>Dealing with dynamic SQL in SQL Server</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,8cac7e9a-f811-488b-844b-85d983ba534b.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2014/02/11/DealingWithDynamicSQLInSQLServer.aspx</link>
      <pubDate>Tue, 11 Feb 2014 09:48:07 GMT</pubDate>
      <description>  &lt;p&gt;
These are initial positions for this writing: 
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
SQL Server allows to execute dynamic SQL.&lt;/li&gt;
&lt;li&gt;
Dynamic SQL is useful and often unavoidable, e.g. when you have to filter or order
data in a way that you cannot code efficiently in advance.&lt;/li&gt;
&lt;li&gt;
Dynamic SQL has proven to be a dangerous area, as with improper use it can open hole
in a security.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
In general nothing stops you from building and then excuting of SQL string. Our goal,
however, is to define rules that make work with dynamic SQL is more managable and
verifiable. 
&lt;/p&gt;
&lt;p&gt;
Here we outline these rules, and then give some examples and tips. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Rule #1. Isolate dynamic SQL&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Put all logic related to building of dynamic SQL into a separate function.&lt;br /&gt;
We usually define a separate scheme &lt;code&gt;Dynamic&lt;/code&gt;, and define functions like &lt;code&gt;Dynamic.GetSQL_XXX(params)&lt;/code&gt;.&lt;br /&gt;
This makes it simple to perform code review. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Rule #2. Xml as parameters&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Use &lt;code&gt;xml&lt;/code&gt; type to pass parameters to a function that builds dynamic SQL.&lt;br /&gt;
In many cases dynamic SQL depends on variable number of parameters (like a list of
values to check against). 
&lt;br /&gt;
Xml fits here to represent structured information.&lt;br /&gt;
On a client (e.g. in C# or java) you can define a class with all parameters, populate
an instance and serialize it to an xml. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Rule #3. XQuery as template language&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Use XQuery to define SQL template and to generate SQL tree from the input parameters.&lt;br /&gt;
Here is an example of such XQuery:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;@data.query('&lt;br /&gt;
&amp;lt;sql&amp;gt;&lt;br /&gt;
select&lt;br /&gt;
T.*&lt;br /&gt;
from&lt;br /&gt;
Data.Ticket T&lt;br /&gt;
where&lt;br /&gt;
{&lt;br /&gt;
for $ticketID in data/ticketID return&lt;br /&gt;
&amp;lt;sql&amp;gt;(T.TicketID = &amp;lt;int&amp;gt;{$ticketID}&amp;lt;/int&amp;gt;) and &amp;lt;/sql&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
(1 = 1)&lt;br /&gt;
&amp;lt;/sql&amp;gt;')&lt;/code&gt; 
&lt;/p&gt;
&lt;p&gt;
You can see that output is an xml with &lt;code&gt;sql&lt;/code&gt; element to represent literal
SQL, and &lt;code&gt;int&lt;/code&gt; element to represent integer literal. 
&lt;/p&gt;
&lt;p&gt;
In fact whole output schema can be defined like this:
&lt;/p&gt;
&lt;p&gt;
&lt;code&gt;&amp;lt;xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"&amp;gt;&lt;br /&gt;
&amp;lt;xs:element name="sql"/&amp;gt;&lt;br /&gt;
&amp;lt;xs:element name="name"/&amp;gt;&lt;br /&gt;
&amp;lt;xs:element name="string" nillable="true"/&amp;gt;&lt;br /&gt;
&amp;lt;xs:element name="int" nillable="true"/&amp;gt;&lt;br /&gt;
&amp;lt;xs:element name="decimal" nillable="true"/&amp;gt;&lt;br /&gt;
&amp;lt;xs:element name="date" nillable="true"/&amp;gt;&lt;br /&gt;
&amp;lt;xs:element name="time" nillable="true"/&amp;gt;&lt;br /&gt;
&amp;lt;xs:element name="datetime" nillable="true"/&amp;gt;&lt;br /&gt;
&amp;lt;/xs:schema&amp;gt; &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
where &lt;code&gt;sql&lt;/code&gt; is to represent literal content, &lt;code&gt;name&lt;/code&gt; to represent
a name, and other elements to represent different literal values.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Rule #4. Escape literals&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Use function &lt;code&gt;Dynamic.ToSQL(@template)&lt;/code&gt; to build final SQL text.&lt;br /&gt;
Here we quote the definition:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;-- Builds a text of SQL function for an sql template.&lt;br /&gt;
create function Dynamic.ToSQL 
&lt;br /&gt;
( 
&lt;br /&gt;
-- SQL template. 
&lt;br /&gt;
@template xml 
&lt;br /&gt;
) 
&lt;br /&gt;
returns nvarchar(max) 
&lt;br /&gt;
with returns null on null input 
&lt;br /&gt;
as 
&lt;br /&gt;
begin 
&lt;br /&gt;
return 
&lt;br /&gt;
( 
&lt;br /&gt;
select&lt;br /&gt;
case 
&lt;br /&gt;
when N.Node.exist('*[xs:boolean(@xsi:nil)]') = 1 then 
&lt;br /&gt;
'null' 
&lt;br /&gt;
&lt;br /&gt;
when N.Node.exist('self::int') = 1 then 
&lt;br /&gt;
isnull(N.Node.value('xs:int(.)', 'nvarchar(max)'), '# int #') 
&lt;br /&gt;
&lt;br /&gt;
when N.Node.exist('self::string') = 1 then 
&lt;br /&gt;
'N''' + 
&lt;br /&gt;
replace 
&lt;br /&gt;
( 
&lt;br /&gt;
N.Node.value('.', 'nvarchar(max)'),&lt;br /&gt;
'''', 
&lt;br /&gt;
'''''' 
&lt;br /&gt;
) + 
&lt;br /&gt;
'''' 
&lt;br /&gt;
&lt;br /&gt;
when N.Node.exist('self::name') = 1 then 
&lt;br /&gt;
isnull 
&lt;br /&gt;
( 
&lt;br /&gt;
quotename(N.Node.value('.', 'nvarchar(128)'), '['), 
&lt;br /&gt;
'# name #' 
&lt;br /&gt;
) 
&lt;br /&gt;
&lt;br /&gt;
when N.Node.exist('self::datetime') = 1 then 
&lt;br /&gt;
isnull 
&lt;br /&gt;
( 
&lt;br /&gt;
'convert(datetime2, ''' + 
&lt;br /&gt;
N.Node.value('xs:dateTime(.)', 'nvarchar(128)') + 
&lt;br /&gt;
''', 126)', 
&lt;br /&gt;
'# datetime #' 
&lt;br /&gt;
) 
&lt;br /&gt;
&lt;br /&gt;
when N.Node.exist('self::date') = 1 then 
&lt;br /&gt;
isnull 
&lt;br /&gt;
( 
&lt;br /&gt;
'convert(date, ''' + 
&lt;br /&gt;
N.Node.value('xs:date(.)', 'nvarchar(128)') + 
&lt;br /&gt;
''', 126)', 
&lt;br /&gt;
'# date #' 
&lt;br /&gt;
) 
&lt;br /&gt;
&lt;br /&gt;
when N.Node.exist('self::time') = 1 then 
&lt;br /&gt;
isnull 
&lt;br /&gt;
( 
&lt;br /&gt;
'convert(time, ''' + 
&lt;br /&gt;
N.Node.value('xs:time(.)', 'nvarchar(128)') + 
&lt;br /&gt;
''', 114)', 
&lt;br /&gt;
'# time #' 
&lt;br /&gt;
) 
&lt;br /&gt;
&lt;br /&gt;
when N.Node.exist('self::decimal') = 1 then 
&lt;br /&gt;
isnull 
&lt;br /&gt;
( 
&lt;br /&gt;
N.Node.value('xs:decimal(.)', 'nvarchar(128)'), 
&lt;br /&gt;
'# decimal #' 
&lt;br /&gt;
) 
&lt;br /&gt;
&lt;br /&gt;
when N.Node.exist('self::*') = 1 then 
&lt;br /&gt;
'# invalid template #' 
&lt;br /&gt;
&lt;br /&gt;
else 
&lt;br /&gt;
N.Node.value('.', 'nvarchar(max)') 
&lt;br /&gt;
end 
&lt;br /&gt;
from 
&lt;br /&gt;
@template.nodes('//sql/node()[not(self::sql)]') N(Node) 
&lt;br /&gt;
for xml path(''), type&lt;br /&gt;
).value('.', 'nvarchar(max)'); 
&lt;br /&gt;
end; &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Now, we want to stress that this function plays an important role in prevention of
the SQL injection, as it escapes literals from the SQL tree.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Rule #5 (optional). Collect data&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Use SQL to collect additional data required to build dynamic SQL. Here is an example
of how we get a &lt;code&gt;Ticket&lt;/code&gt; by &lt;code&gt;StatusID&lt;/code&gt;, while on input we receive
a &lt;code&gt;StatusName&lt;/code&gt;:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;create function Dynamic.GetSQL_GetTicketByStatus(@data xml)&lt;br /&gt;
returns nvarchar(max)&lt;br /&gt;
as&lt;br /&gt;
begin&lt;br /&gt;
&lt;span style="color: red"&gt; set @data = 
&lt;br /&gt;
(&lt;br /&gt;
select 
&lt;br /&gt;
@data, 
&lt;br /&gt;
(&lt;br /&gt;
select&lt;br /&gt;
T.StatusID&lt;br /&gt;
from&lt;br /&gt;
@data.nodes('/data/status') N(Node)&lt;br /&gt;
inner join&lt;br /&gt;
Metadata.Status T&lt;br /&gt;
on&lt;br /&gt;
T.StatusName = Node.value('.', 'nvarchar(128)')&lt;br /&gt;
for xml auto, type, elements&lt;br /&gt;
) 
&lt;br /&gt;
for xml path('')&lt;br /&gt;
);&lt;br /&gt;
&lt;/span&gt; 
&lt;br /&gt;
return Dynamic.ToSQL&lt;br /&gt;
(&lt;br /&gt;
@data.query&lt;br /&gt;
('&lt;br /&gt;
&amp;lt;sql&amp;gt;&lt;br /&gt;
select&lt;br /&gt;
T.*&lt;br /&gt;
from&lt;br /&gt;
Data.Ticket T&lt;br /&gt;
where&lt;br /&gt;
T.Status in ({ for $status in /T/StatusID return &amp;lt;sql&amp;gt;&amp;lt;int&amp;gt;{$status}&amp;lt;/int&amp;gt;,&amp;lt;/sql&amp;gt;
} null)&lt;br /&gt;
&amp;lt;/sql&amp;gt;&lt;br /&gt;
')&lt;br /&gt;
);&lt;br /&gt;
end; &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Notice code in red that collects some more data before calling XQuery.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Rule #6. Execute&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
The final step is to call dynamic SQL.&lt;br /&gt;
This is done like this:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;-- build&lt;br /&gt;
declare @sql nvarchar(max) = Dynamic.GetSQL_GetTicket(@data);&lt;br /&gt;
&lt;br /&gt;
-- execute&lt;br /&gt;
execute sp_executesql 
&lt;br /&gt;
@sql&lt;br /&gt;
-- {, N'@parameter_name data_type [ OUT | OUTPUT ][ ,...n ]' } 
&lt;br /&gt;
-- { , [ @param1 = ] 'value1' [ ,...n ] }&lt;br /&gt;
with result sets&lt;br /&gt;
( 
&lt;br /&gt;
(&lt;br /&gt;
TicketID int not null,&lt;br /&gt;
CreatedAt datetime2 not null,&lt;br /&gt;
Summary nvarchar(256) null,&lt;br /&gt;
Status int,&lt;br /&gt;
Severity int,&lt;br /&gt;
DeadLineAt datetime2 null&lt;br /&gt;
)&lt;br /&gt;
);&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Notice that the use of dynamic SQL does not prevent static parameters.&lt;br /&gt;
Notice also that &lt;code&gt;with result sets&lt;/code&gt; clause is used to specify output.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Example. Tickets system&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Let&amp;#39;s assume you&amp;#39;re dealing with a tickets system (like Bugzilla), and you
have a table &lt;code&gt;Data.Ticket&lt;/code&gt; to describe tickets. Assume that DDL for this
table is like this:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;create table Data.Ticket&lt;br /&gt;
(&lt;br /&gt;
TicketID bigint not null primary key,&lt;br /&gt;
CreatedAt datetime2 not null,&lt;br /&gt;
Summary nvarchar(128) null,&lt;br /&gt;
Status int not null,&lt;br /&gt;
UpdatedAt datetime2(7) not null&lt;br /&gt;
) &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Suppose you have to build C# code to search different tickets, where Entity Framework
is used to access the database.&lt;br /&gt;
Search should be done by a range of &lt;code&gt;CreatedAt&lt;/code&gt;, a range of &lt;code&gt;UpdatedAt&lt;/code&gt;, &lt;code&gt;Summary&lt;/code&gt;,
or by different &lt;code&gt;Status&lt;/code&gt; values. It should be possible to order results
in different ways.
&lt;/p&gt;
&lt;p&gt;
We start out solution from the C# and define classes for a request:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; public enum Direction&lt;br /&gt;
{&lt;br /&gt;
Asc,&lt;br /&gt;
Desc&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public struct Order 
&lt;br /&gt;
{&lt;br /&gt;
public string Field { get; set; }&lt;br /&gt;
public Direction Direction {get; set; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class DateRange&lt;br /&gt;
{&lt;br /&gt;
public DateTime? From { get; set; }&lt;br /&gt;
&lt;br /&gt;
// This property is to omit From element if value is null.&lt;br /&gt;
// See rules for xml serialization.&lt;br /&gt;
public bool FromSpecified { get { return From != null; } }&lt;br /&gt;
&lt;br /&gt;
public DateTime? To { get; set; }&lt;br /&gt;
public bool ToSpecified { get { return To != null; } }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public class TicketsRequest&lt;br /&gt;
{&lt;br /&gt;
public DateRange CreatedAt { get; set; }&lt;br /&gt;
public string Summary { get; set; }&lt;br /&gt;
public DateRange UpdatedAt { get; set; }&lt;br /&gt;
[XmlElement]&lt;br /&gt;
public Order[] Order { get; set; }&lt;br /&gt;
[XmlElement]&lt;br /&gt;
public int[] Status { get; set; }&lt;br /&gt;
} &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Notice that we&amp;#39;re going to use &lt;code&gt;XmlSerializer&lt;/code&gt; to convert request to
xml and then to pass parameter into EF&amp;#39;s model. Here is utility method to perform
such conversion:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; public static string ToXmlString&amp;lt;T&amp;gt;(T value)&lt;br /&gt;
{&lt;br /&gt;
if (value == null)&lt;br /&gt;
{&lt;br /&gt;
return null;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var serializer = new XmlSerializer(typeof(T));&lt;br /&gt;
var builder = new StringBuilder();&lt;br /&gt;
&lt;br /&gt;
var writer = XmlWriter.Create(&lt;br /&gt;
builder,&lt;br /&gt;
new XmlWriterSettings&lt;br /&gt;
{&lt;br /&gt;
OmitXmlDeclaration = true,&lt;br /&gt;
Indent = false&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
serializer.Serialize(writer, value);&lt;br /&gt;
writer.Flush();&lt;br /&gt;
&lt;br /&gt;
return builder.ToString();&lt;br /&gt;
} &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Now we proceed to the database and define a procedure that runs the search:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;-- Gets tickets.&lt;br /&gt;
create procedure Data.GetTickets&lt;br /&gt;
(&lt;br /&gt;
-- A query parameters.&lt;br /&gt;
@params xml&lt;br /&gt;
)&lt;br /&gt;
as&lt;br /&gt;
begin&lt;br /&gt;
set nocount on;&lt;br /&gt;
&lt;br /&gt;
-- This is for EF to guess type of result.&lt;br /&gt;
if (1 = 0)&lt;br /&gt;
begin&lt;br /&gt;
select&lt;br /&gt;
TicketID,&lt;br /&gt;
CreatedAt,&lt;br /&gt;
Summary,&lt;br /&gt;
Status,&lt;br /&gt;
UpdatedAt&lt;br /&gt;
from&lt;br /&gt;
Data.Ticket;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
declare @sql nvarchar(max) = Dynamic.GetSQL_GetTickets(@params);&lt;br /&gt;
&lt;br /&gt;
execute sp_executesql @sql&lt;br /&gt;
with result sets&lt;br /&gt;
( 
&lt;br /&gt;
(&lt;br /&gt;
TicketID int not null,&lt;br /&gt;
CreatedAt datetime2 not null,&lt;br /&gt;
Summary nvarchar(256) null,&lt;br /&gt;
Status int,&lt;br /&gt;
UpdatedAt datetime2 null&lt;br /&gt;
)&lt;br /&gt;
);&lt;br /&gt;
end; &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Switch back to C#, import the &lt;code&gt;Data.GetTickets&lt;/code&gt; into the EF model, and
create a search method:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; public IEnumerable&amp;lt;Ticket&amp;gt; GetTickets(TicketsRequest request)&lt;br /&gt;
{ 
&lt;br /&gt;
var model = new Model();&lt;br /&gt;
&lt;br /&gt;
return model.GetTickets(ToXmlString(request));&lt;br /&gt;
} &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
The last ingredient is &lt;code&gt;Dynamic.GetSQL_GetTickets()&lt;/code&gt; function.
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;create function Dynamic.GetSQL_GetTickets(@data xml)&lt;br /&gt;
returns nvarchar(max)&lt;br /&gt;
as&lt;br /&gt;
begin&lt;br /&gt;
return Dynamic.ToSQL&lt;br /&gt;
(&lt;br /&gt;
@data.query('&lt;br /&gt;
&amp;lt;sql&amp;gt;&lt;br /&gt;
select&lt;br /&gt;
T.TicketID,&lt;br /&gt;
T.CreatedAt,&lt;br /&gt;
T.Summary,&lt;br /&gt;
T.Status,&lt;br /&gt;
T.UpdatedAt&lt;br /&gt;
from&lt;br /&gt;
Data.Ticket T&lt;br /&gt;
where&lt;br /&gt;
{&lt;br /&gt;
for $range in */CreatedAt return&lt;br /&gt;
(&lt;br /&gt;
for $date in $range/From return&lt;br /&gt;
&amp;lt;sql&amp;gt;&lt;br /&gt;
(T.CreatedAt &amp;gt;= &amp;lt;datetime&amp;gt;{$date}&amp;lt;/datetime&amp;gt;) and&lt;br /&gt;
&amp;lt;/sql&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
for $date in $range/To return&lt;br /&gt;
&amp;lt;sql&amp;gt;&lt;br /&gt;
(&amp;lt;datetime&amp;gt;{$date}&amp;lt;/datetime&amp;gt; &amp;gt; T.CreatedAt) and&lt;br /&gt;
&amp;lt;/sql&amp;gt;&lt;br /&gt;
),&lt;br /&gt;
&lt;br /&gt;
for $range in */UpdatedAt return&lt;br /&gt;
(&lt;br /&gt;
for $date in $range/From return&lt;br /&gt;
&amp;lt;sql&amp;gt;&lt;br /&gt;
(T.UpdatedAt &amp;gt;= &amp;lt;datetime&amp;gt;{$date}&amp;lt;/datetime&amp;gt;) and&lt;br /&gt;
&amp;lt;/sql&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
for $date in $range/To return&lt;br /&gt;
&amp;lt;sql&amp;gt;&lt;br /&gt;
(&amp;lt;datetime&amp;gt;{$date}&amp;lt;/datetime&amp;gt; &amp;gt; T.UpdatedAt) and&lt;br /&gt;
&amp;lt;/sql&amp;gt;&lt;br /&gt;
),&lt;br /&gt;
&lt;br /&gt;
for $summary in */Summary return&lt;br /&gt;
&amp;lt;sql&amp;gt;&lt;br /&gt;
(T.Summary like &amp;lt;string&amp;gt;{$summary}&amp;lt;/string&amp;gt;) and&lt;br /&gt;
&amp;lt;/sql&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
if (*/Status) then&lt;br /&gt;
&amp;lt;sql&amp;gt;&lt;br /&gt;
T.Status in 
&lt;br /&gt;
({&lt;br /&gt;
for $status in */Status return&lt;br /&gt;
&amp;lt;sql&amp;gt;&amp;lt;int&amp;gt;{$status}&amp;lt;/int&amp;gt;, &amp;lt;/sql&amp;gt;&lt;br /&gt;
} null) and&lt;br /&gt;
&amp;lt;/sql&amp;gt;&lt;br /&gt;
else ()&lt;br /&gt;
}&lt;br /&gt;
(1 = 1)&lt;br /&gt;
order by&lt;br /&gt;
{&lt;br /&gt;
for $order in 
&lt;br /&gt;
*/Order 
&lt;br /&gt;
[&lt;br /&gt;
Field = ("TicketID", "CreatedAt", "Summary", "UpdatedAt", "Status")&lt;br /&gt;
]&lt;br /&gt;
return&lt;br /&gt;
&amp;lt;sql&amp;gt;&lt;br /&gt;
&amp;lt;name&amp;gt;{$order/Field}&amp;lt;/name&amp;gt;&lt;br /&gt;
{" desc"[$order[Direction = "Desc"]]},&lt;br /&gt;
&amp;lt;/sql&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
(select null)&lt;br /&gt;
&amp;lt;/sql&amp;gt;&lt;br /&gt;
') 
&lt;br /&gt;
);&lt;br /&gt;
end;&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;SQL text from Dynamic.GetSQL_GetTickets()&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Consider now SQL text produced by this function. For an input:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;&amp;lt;TicketsRequest&amp;gt;&lt;br /&gt;
&amp;lt;CreatedAt&amp;gt;&lt;br /&gt;
&amp;lt;From&amp;gt;2014-01-01T00:00:00&amp;lt;/From&amp;gt;&lt;br /&gt;
&amp;lt;/CreatedAt&amp;gt;&lt;br /&gt;
&amp;lt;Summary&amp;gt;hello%&amp;lt;/Summary&amp;gt;&lt;br /&gt;
&amp;lt;Order&amp;gt;&lt;br /&gt;
&amp;lt;Field&amp;gt;Status&amp;lt;/Field&amp;gt;&lt;br /&gt;
&amp;lt;Direction&amp;gt;Desc&amp;lt;/Direction&amp;gt;&lt;br /&gt;
&amp;lt;/Order&amp;gt;&lt;br /&gt;
&amp;lt;Status&amp;gt;1&amp;lt;/Status&amp;gt;&lt;br /&gt;
&amp;lt;Status&amp;gt;3&amp;lt;/Status&amp;gt;&lt;br /&gt;
&amp;lt;/TicketsRequest&amp;gt;&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
the output is:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; select&lt;br /&gt;
T.TicketID,&lt;br /&gt;
T.CreatedAt,&lt;br /&gt;
T.Summary,&lt;br /&gt;
T.Status,&lt;br /&gt;
T.UpdatedAt&lt;br /&gt;
from&lt;br /&gt;
Data.Ticket T&lt;br /&gt;
where&lt;br /&gt;
&lt;br /&gt;
(T.CreatedAt &amp;gt;= convert(datetime2, '2014-01-01T00:00:00', 126)) and&lt;br /&gt;
&lt;br /&gt;
(T.Summary like N'hello%') and&lt;br /&gt;
&lt;br /&gt;
T.Status in 
&lt;br /&gt;
(1, 3, null) and&lt;br /&gt;
&lt;br /&gt;
(1 = 1)&lt;br /&gt;
order by&lt;br /&gt;
[Status] desc,&lt;br /&gt;
&lt;br /&gt;
(select null)&lt;br /&gt;
&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Though the text is not formatted as we would like, it&amp;#39;s perfectly valid SQL.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Tips for building XQuery templates&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
What is called XQuery in SQL Server is in fact a very limited subset of XQuery 1.0.
Microsoft clearly states this fact. What is trivial in XQuery is often impossible
or ugly in XQuery of SQL Server. 
&lt;/p&gt;
&lt;p&gt;
Nevertheless XQuery in SQL Server works rather well as SQL template language. To make
it most efficient, however, you should learn several tips. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Tip #1. Where clause&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
In template you might want to build a &lt;code&gt;where&lt;/code&gt; clause: 
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;&amp;lt;sql&amp;gt;&lt;br /&gt;
select 
&lt;br /&gt;
... 
&lt;br /&gt;
where 
&lt;br /&gt;
{&lt;br /&gt;
if (...) then&lt;br /&gt;
&amp;lt;sql&amp;gt;...&amp;lt;/sql&amp;gt;&lt;br /&gt;
else ()&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/sql&amp;gt;&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
and it might happen that for a certain input a condition under &lt;code&gt;where&lt;/code&gt; might
collapse, and you will be left with &lt;code&gt;where&lt;/code&gt; keyword without a real condition,
which is wrong. A simple work around is to always add some true condition under ther &lt;code&gt;where&lt;/code&gt; like
this:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;&amp;lt;sql&amp;gt;&lt;br /&gt;
select 
&lt;br /&gt;
... 
&lt;br /&gt;
where 
&lt;br /&gt;
{&lt;br /&gt;
if (...) then&lt;br /&gt;
&amp;lt;sql&amp;gt;... &lt;span style="color: red"&gt;and&lt;/span&gt; &amp;lt;/sql&amp;gt;&lt;br /&gt;
else ()&lt;br /&gt;
} &lt;span style="color: red"&gt;(1 = 1)&lt;/span&gt;
&lt;br /&gt;
&amp;lt;/sql&amp;gt;&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Tip #2. &amp;quot;in&amp;quot; expression&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
If you want to generate &amp;quot;in&amp;quot; expression like this:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;value in (item1, item2,...)&lt;/code&gt; 
&lt;/p&gt;
&lt;p&gt;
then you might find that it&amp;#39;s much easier generate equivalent a code like this: 
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;value in (item1, item2,..., null)&lt;/code&gt;.
&lt;/p&gt;
&lt;p&gt;
Here is a XQuery to generate such template:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;value in 
&lt;br /&gt;
({&lt;br /&gt;
for $item in ... return&lt;br /&gt;
&amp;lt;sql&amp;gt;&amp;lt;int&amp;gt;{$item}&amp;lt;/int&amp;gt;, &amp;lt;/sql&amp;gt;&lt;br /&gt;
} null) and&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Tip #3. Order by&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
You can conclude an &lt;code&gt;order by&lt;/code&gt; clause built from a data with a dummy expression
like this:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;order by&lt;br /&gt;
{&lt;br /&gt;
for $item in ... return&lt;br /&gt;
&amp;lt;sql&amp;gt;&lt;br /&gt;
&amp;lt;name&amp;gt;{$item/Field}&amp;lt;/name&amp;gt;&lt;br /&gt;
{&amp;quot; desc&amp;quot;[$item/Direction = &amp;quot;Desc&amp;quot;]},&lt;br /&gt;
&amp;lt;/sql&amp;gt;&lt;br /&gt;
} &lt;span style="color: red"&gt;(select null)&lt;/span&gt;&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Alternatively you can use first column from a clustered index.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Tip #4. Group by&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
In a &lt;code&gt;group by&lt;/code&gt; clause we cannot introduce terminator expression as it
was with &lt;code&gt;order by&lt;/code&gt;, so a code is a less trivial:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;{&lt;br /&gt;
let $items := ... return&lt;br /&gt;
&lt;br /&gt;
if ($items) then&lt;br /&gt;
&amp;lt;sql&amp;gt;&lt;br /&gt;
group by &amp;lt;name&amp;gt;{$items[1]}&amp;lt;/name&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
for $item in $items[position() &amp;gt; 1] return&lt;br /&gt;
&amp;lt;sql&amp;gt;, &amp;lt;name&amp;gt;{$item}&amp;lt;/name&amp;gt;&amp;lt;/sql&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;lt;/sql&amp;gt;&lt;br /&gt;
else ()&lt;br /&gt;
}&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
In fact similar logic may work with &lt;code&gt;order by&lt;/code&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Tip #5. Escape literals&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
It&amp;#39;s crusial not to introduce SQL injection while building SQL. Thus use:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;&amp;lt;int&amp;gt;{...}&amp;lt;/int&amp;gt;&lt;/code&gt; - for literal int;&lt;br /&gt;
&lt;code&gt;&amp;lt;decimal&amp;gt;{...}&amp;lt;/decimal&amp;gt;&lt;/code&gt; - for literal decimal;&lt;br /&gt;
&lt;code&gt;&amp;lt;string&amp;gt;{...}&amp;lt;/string&amp;gt;&lt;/code&gt; - for literal string;&lt;br /&gt;
&lt;code&gt;&amp;lt;datetime&amp;gt;{...}&amp;lt;/datetime&amp;gt;&lt;/code&gt; - for literal datetime2;&lt;br /&gt;
&lt;code&gt;&amp;lt;date&amp;gt;{...}&amp;lt;/date&amp;gt;&lt;/code&gt; - for literal date;&lt;br /&gt;
&lt;code&gt;&amp;lt;time&amp;gt;{...}&amp;lt;/time&amp;gt;&lt;/code&gt; - for literal time;&lt;br /&gt;
&lt;code&gt;&amp;lt;name&amp;gt;{...}&amp;lt;/name&amp;gt;&lt;/code&gt; - for a name to quote.
&lt;/p&gt;
&lt;p&gt;
Note that you can use &lt;code&gt;xsi:nil&lt;/code&gt;, so &lt;code&gt;&amp;lt;int xsi:nil="true"/&gt;&lt;/code&gt; means &lt;code&gt;null&lt;/code&gt;.
&lt;/p&gt;
&lt;p&gt;
If you generate a field name from an input data then it worth to validate it against
a list of available names.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Tip #6. Validate input.&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
It worth to define xml schema for an input xml, and to validate parameters against
it.&lt;br /&gt;
This makes code more secure, and also adds a documentation.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Tip #7. Don&amp;#39;t abuse dynamic SQL&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
There are not too many cases when you need a dynamic SQL. Usually SQL engine knows
how to build a good execution plan. If your query contains optional conditions then
you can write it a way that SQL Server can optimize, e.g.:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; select&lt;br /&gt;
*&lt;br /&gt;
from&lt;br /&gt;
T&lt;br /&gt;
where&lt;br /&gt;
((@name is null) or (Name = @name)) and&lt;br /&gt;
((@date is null) or (Date = @date))&lt;br /&gt;
option(recompile)&lt;/code&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=8cac7e9a-f811-488b-844b-85d983ba534b" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,8cac7e9a-f811-488b-844b-85d983ba534b.aspx</comments>
      <category>SQL Server puzzle</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=ab2110fa-c136-4b6b-bfdc-aa0dce059a97</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,ab2110fa-c136-4b6b-bfdc-aa0dce059a97.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,ab2110fa-c136-4b6b-bfdc-aa0dce059a97.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=ab2110fa-c136-4b6b-bfdc-aa0dce059a97</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Consider how would you implement Style object in the HTML DOM?
</p>
        <p>
These are some characteristics of that object:
</p>
        <ul>
          <li>
It has a long list of properties, e.g. in IE 11 there are more than 300 properties
over a style object.</li>
          <li>
Any specific instance usually have only several properties assigned.</li>
          <li>
Reads of properties are much more frequent than writes. In fact style often stays
unchanged after initialization.</li>
          <li>
DOM contains many style instances (often thousands).</li>
          <li>
The number of distinct instances in terms of values of properties is moderate (usually
dozens).</li>
        </ul>
        <p>
Here is how would we approached to such an object.
</p>
        <p>
1. Styles are sparse objects, thus there is no point to implement plain class with
all those properties, as it's wasteful.
</p>
        <p>
We would rather use two techniques to keep style's state:
</p>
        <ul>
          <li>
A dictionary of properties with their values;</li>
          <li>
An aggregation of objects, where all properies are grouped into families, each group
is defined by a separate type, and a style's state is an aggregation of that groups.</li>
        </ul>
        <p>
A current style of an element is an aggregation of styles of ancestor element. It
can either by dynamic or be fused into a single style instance.
</p>
        <p>
2. Make style's state immutable, and share all these states among all style instances.
</p>
        <p>
In this implementation property write turns into a state transition operation: <code>state
= set(state, property, value)</code>. Thus no state is modified but replaced with
other state that corresponds to a required change.
</p>
        <p>
If state is seen as a dictionary then API may look like this :
</p>
        <p style="padding-left: 1em">
          <code> public class State&lt;K, V&gt;<br />
{<br />
// Gets shared dictionary for an input dictionary.<br />
public IDictionary&lt;K, V&gt; Get(IDictionary&lt;K, V&gt; dictionary);<br /><br />
// Gets a shared dictionary for an input dictionary with key set to a value. 
<br />
public IDictionary&lt;K, V&gt; Set(IDictionary&lt;K, V&gt; dictionary, K key, V value);<br /><br />
// Gets a shared dictionary for an input dictionary.<br />
public IDictionary&lt;K, V&gt; Remove(IDictionary&lt;K, V&gt; dictionary, K key);<br /><br />
// Gets typed value.<br />
public T Get&lt;T&gt;(IDictionary&lt;K, V&gt; dictionary, K key)<br />
where T: V<br />
{<br />
V value;<br /><br />
if ((dictionary == null) || !dictionary.TryGetValue(key, out value))<br />
{<br />
return default(T);<br />
}<br /><br />
return (T)value;<br />
}<br /><br />
// Sets or removes a typed value.<br />
// dictionary can be null.<br />
// null returned if output dictionary would be empty. 
<br />
public IDictionary&lt;K, V&gt; Set&lt;T&gt;(IDictionary&lt;K, V&gt; dictionary, K key, T value)<br />
where T : V<br />
{<br />
return value == null ? Remove(dictionary, key) : 
<br />
Set(dictionary, key, (V)value);<br />
}<br />
}</code>
        </p>
        <p>
States can be cached. Provided the cache keeps states in a weak way, no unsued state
will be stored for a long time. We may use weak table of dictionary to dictionary <code>WeakTable&lt;Dictionary&lt;K,
V&gt;, Dictionary&lt;K, V&gt;&gt;</code> as a storage for such a cache. All required
API is described in the <a href="http://www.nesterovsky-bros.com/weblog/2014/01/08/WeakTable.aspx">WeakTable</a> and <a href="http://www.nesterovsky-bros.com/weblog/2014/01/13/HashCodeOfDictionary.aspx">Hash
Code of Dictionary</a> posts.
</p>
        <p>
3. Style can be implemented as a structure with shared state as a storage. Here is
a scetch:
</p>
        <p style="padding-left: 1em">
          <code>[Serializable]<br />
public struct Style<br />
{<br />
// All properties.<br />
public enum Property<br />
{<br />
Background,<br />
BorderColor,<br />
BorderStyle,<br />
Color,<br />
FontFamily,<br />
FontSize,<br />
// ...<br />
}<br /><br />
public int? Background<br />
{<br />
get { return states.Get&lt;int?&gt;(state, Property.Background); }<br />
set { state = states.Set(state, Property.Background, value); }<br />
}<br /><br />
public int? BorderColor<br />
{<br />
get { return states.Get&lt;int?&gt;(state, Property.BorderColor); }<br />
set { state = states.Set(state, Property.BorderColor, value); }<br />
}<br /><br />
public string BorderStyle<br />
{<br />
get { return states.Get&lt;string&gt;(state, Property.BorderStyle); }<br />
set { state = states.Set(state, Property.BorderStyle, value); }<br />
}<br /><br />
public int? Color<br />
{<br />
get { return states.Get&lt;int?&gt;(state, Property.Color); }<br />
set { state = states.Set(state, Property.Color, value); }<br />
}<br /><br />
public string FontFamily<br />
{<br />
get { return states.Get&lt;string&gt;(state, Property.FontFamily); }<br />
set { state = states.Set(state, Property.FontFamily, value); }<br />
}<br /><br />
public double? FontSize<br />
{<br />
get { return states.Get&lt;double?&gt;(state, Property.FontSize); }<br />
set { state = states.Set(state, Property.FontSize, value); }<br />
}<br /><br />
// ...<br /><br />
[OnDeserialized]<br />
private void OnDeserialized(StreamingContext context)<br />
{<br />
state = states.Get(state);<br />
}<br /><br />
// A state.<br />
private IDictionary&lt;Property, object&gt; state;<br /><br />
// A states cache.<br />
private static readonly State&lt;Property, object&gt; states =<br />
new State&lt;Property, object&gt;();<br />
} </code>
        </p>
        <p>
Note that:
</p>
        <ul>
          <li>
default state is a <code>null</code> dictionary;</li>
          <li>
states are application wide shared.</li>
        </ul>
        <p>
The following link is our implementation of <code><a href="http://www.nesterovsky-bros.com/download/State.cs.txt">State&lt;K,
V&gt;</a></code> class: <a href="http://www.nesterovsky-bros.com/download/State.cs.txt">State.cs</a>.
</p>
        <p>
        </p>
        <p>
Here we have outlined the idea of shared state object, and how it can be applied to
sparse mostly immutable objects. We used HTML style as an example of such an object.
Shared state object may work in many other areas, but for it to shine its use case
should fit to the task.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=ab2110fa-c136-4b6b-bfdc-aa0dce059a97" />
      </body>
      <title>Shared state</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,ab2110fa-c136-4b6b-bfdc-aa0dce059a97.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2014/01/22/SharedState.aspx</link>
      <pubDate>Wed, 22 Jan 2014 19:43:25 GMT</pubDate>
      <description>    &lt;p&gt;
Consider how would you implement Style object in the HTML DOM?
&lt;/p&gt;
&lt;p&gt;
These are some characteristics of that object:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
It has a long list of properties, e.g. in IE 11 there are more than 300 properties
over a style object.&lt;/li&gt;
&lt;li&gt;
Any specific instance usually have only several properties assigned.&lt;/li&gt;
&lt;li&gt;
Reads of properties are much more frequent than writes. In fact style often stays
unchanged after initialization.&lt;/li&gt;
&lt;li&gt;
DOM contains many style instances (often thousands).&lt;/li&gt;
&lt;li&gt;
The number of distinct instances in terms of values of properties is moderate (usually
dozens).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Here is how would we approached to such an object.
&lt;/p&gt;
&lt;p&gt;
1. Styles are sparse objects, thus there is no point to implement plain class with
all those properties, as it&amp;#39;s wasteful.
&lt;/p&gt;
&lt;p&gt;
We would rather use two techniques to keep style&amp;#39;s state:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
A dictionary of properties with their values;&lt;/li&gt;
&lt;li&gt;
An aggregation of objects, where all properies are grouped into families, each group
is defined by a separate type, and a style&amp;#39;s state is an aggregation of that groups.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
A current style of an element is an aggregation of styles of ancestor element. It
can either by dynamic or be fused into a single style instance.
&lt;/p&gt;
&lt;p&gt;
2. Make style&amp;#39;s state immutable, and share all these states among all style instances.
&lt;/p&gt;
&lt;p&gt;
In this implementation property write turns into a state transition operation: &lt;code&gt;state
= set(state, property, value)&lt;/code&gt;. Thus no state is modified but replaced with
other state that corresponds to a required change.
&lt;/p&gt;
&lt;p&gt;
If state is seen as a dictionary then API may look like this :
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; public class State&amp;lt;K, V&gt;&lt;br /&gt;
{&lt;br /&gt;
// Gets shared dictionary for an input dictionary.&lt;br /&gt;
public IDictionary&amp;lt;K, V&gt; Get(IDictionary&amp;lt;K, V&gt; dictionary);&lt;br /&gt;
&lt;br /&gt;
// Gets a shared dictionary for an input dictionary with key set to a value. 
&lt;br /&gt;
public IDictionary&amp;lt;K, V&gt; Set(IDictionary&amp;lt;K, V&gt; dictionary, K key, V value);&lt;br /&gt;
&lt;br /&gt;
// Gets a shared dictionary for an input dictionary.&lt;br /&gt;
public IDictionary&amp;lt;K, V&gt; Remove(IDictionary&amp;lt;K, V&gt; dictionary, K key);&lt;br /&gt;
&lt;br /&gt;
// Gets typed value.&lt;br /&gt;
public T Get&amp;lt;T&gt;(IDictionary&amp;lt;K, V&gt; dictionary, K key)&lt;br /&gt;
where T: V&lt;br /&gt;
{&lt;br /&gt;
V value;&lt;br /&gt;
&lt;br /&gt;
if ((dictionary == null) || !dictionary.TryGetValue(key, out value))&lt;br /&gt;
{&lt;br /&gt;
return default(T);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
return (T)value;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Sets or removes a typed value.&lt;br /&gt;
// dictionary can be null.&lt;br /&gt;
// null returned if output dictionary would be empty. 
&lt;br /&gt;
public IDictionary&amp;lt;K, V&gt; Set&amp;lt;T&gt;(IDictionary&amp;lt;K, V&gt; dictionary, K key, T value)&lt;br /&gt;
where T : V&lt;br /&gt;
{&lt;br /&gt;
return value == null ? Remove(dictionary, key) : 
&lt;br /&gt;
Set(dictionary, key, (V)value);&lt;br /&gt;
}&lt;br /&gt;
}&lt;/code&gt; 
&lt;/p&gt;
&lt;p&gt;
States can be cached. Provided the cache keeps states in a weak way, no unsued state
will be stored for a long time. We may use weak table of dictionary to dictionary &lt;code&gt;WeakTable&amp;lt;Dictionary&amp;lt;K,
V&amp;gt;, Dictionary&amp;lt;K, V&amp;gt;&amp;gt;&lt;/code&gt; as a storage for such a cache. All required
API is described in the &lt;a href="http://www.nesterovsky-bros.com/weblog/2014/01/08/WeakTable.aspx"&gt;WeakTable&lt;/a&gt; and &lt;a href="http://www.nesterovsky-bros.com/weblog/2014/01/13/HashCodeOfDictionary.aspx"&gt;Hash
Code of Dictionary&lt;/a&gt; posts.
&lt;/p&gt;
&lt;p&gt;
3. Style can be implemented as a structure with shared state as a storage. Here is
a scetch:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;[Serializable]&lt;br /&gt;
public struct Style&lt;br /&gt;
{&lt;br /&gt;
// All properties.&lt;br /&gt;
public enum Property&lt;br /&gt;
{&lt;br /&gt;
Background,&lt;br /&gt;
BorderColor,&lt;br /&gt;
BorderStyle,&lt;br /&gt;
Color,&lt;br /&gt;
FontFamily,&lt;br /&gt;
FontSize,&lt;br /&gt;
// ...&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public int? Background&lt;br /&gt;
{&lt;br /&gt;
get { return states.Get&amp;lt;int?&gt;(state, Property.Background); }&lt;br /&gt;
set { state = states.Set(state, Property.Background, value); }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public int? BorderColor&lt;br /&gt;
{&lt;br /&gt;
get { return states.Get&amp;lt;int?&gt;(state, Property.BorderColor); }&lt;br /&gt;
set { state = states.Set(state, Property.BorderColor, value); }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public string BorderStyle&lt;br /&gt;
{&lt;br /&gt;
get { return states.Get&amp;lt;string&gt;(state, Property.BorderStyle); }&lt;br /&gt;
set { state = states.Set(state, Property.BorderStyle, value); }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public int? Color&lt;br /&gt;
{&lt;br /&gt;
get { return states.Get&amp;lt;int?&gt;(state, Property.Color); }&lt;br /&gt;
set { state = states.Set(state, Property.Color, value); }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public string FontFamily&lt;br /&gt;
{&lt;br /&gt;
get { return states.Get&amp;lt;string&gt;(state, Property.FontFamily); }&lt;br /&gt;
set { state = states.Set(state, Property.FontFamily, value); }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public double? FontSize&lt;br /&gt;
{&lt;br /&gt;
get { return states.Get&amp;lt;double?&gt;(state, Property.FontSize); }&lt;br /&gt;
set { state = states.Set(state, Property.FontSize, value); }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ...&lt;br /&gt;
&lt;br /&gt;
[OnDeserialized]&lt;br /&gt;
private void OnDeserialized(StreamingContext context)&lt;br /&gt;
{&lt;br /&gt;
state = states.Get(state);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// A state.&lt;br /&gt;
private IDictionary&amp;lt;Property, object&gt; state;&lt;br /&gt;
&lt;br /&gt;
// A states cache.&lt;br /&gt;
private static readonly State&amp;lt;Property, object&gt; states =&lt;br /&gt;
new State&amp;lt;Property, object&gt;();&lt;br /&gt;
} &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Note that:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
default state is a &lt;code&gt;null&lt;/code&gt; dictionary;&lt;/li&gt;
&lt;li&gt;
states are application wide shared.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
The following link is our implementation of &lt;code&gt;&lt;a href="http://www.nesterovsky-bros.com/download/State.cs.txt"&gt;State&amp;lt;K,
V&amp;gt;&lt;/a&gt;&lt;/code&gt; class: &lt;a href="http://www.nesterovsky-bros.com/download/State.cs.txt"&gt;State.cs&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Here we have outlined the idea of shared state object, and how it can be applied to
sparse mostly immutable objects. We used HTML style as an example of such an object.
Shared state object may work in many other areas, but for it to shine its use case
should fit to the task.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=ab2110fa-c136-4b6b-bfdc-aa0dce059a97" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,ab2110fa-c136-4b6b-bfdc-aa0dce059a97.aspx</comments>
      <category>.NET</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=bc06427b-87e2-4e14-9ebb-1a186f875e3a</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,bc06427b-87e2-4e14-9ebb-1a186f875e3a.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,bc06427b-87e2-4e14-9ebb-1a186f875e3a.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=bc06427b-87e2-4e14-9ebb-1a186f875e3a</wfw:commentRss>
      <title>Hash Code of Dictionary</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,bc06427b-87e2-4e14-9ebb-1a186f875e3a.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2014/01/13/HashCodeOfDictionary.aspx</link>
      <pubDate>Mon, 13 Jan 2014 20:33:31 GMT</pubDate>
      <description>    &lt;p&gt;
Dealing recently with some task (the same that inspired us to implement &lt;a href="http://www.nesterovsky-bros.com/weblog/2014/01/08/WeakTable.aspx"&gt;WeakTable&lt;/a&gt;),
we were in a position to use a dictionary as a key in another dictionary.
&lt;/p&gt;
&lt;p&gt;
What are the rules for the class to be used as key:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
key should be immutable;&lt;/li&gt;
&lt;li&gt;
key should implement a &lt;code&gt;GetHashCode()&lt;/code&gt; method;&lt;/li&gt;
&lt;li&gt;
key should implement a &lt;code&gt;Equals()&lt;/code&gt; method.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
The first requirement is usually implemented as a documentation contract like this:
&lt;/p&gt;
&lt;p style="padding-left: 1em; font-style: italic"&gt;
As long as an object is used as a key in the &lt;code&gt;Dictionary&amp;lt;TKey, TValue&gt;&lt;/code&gt;,
it must not change in any way that affects its hash value.
&lt;/p&gt;
&lt;p&gt;
The third requirement about equals is trivially implemented as a method:
&lt;/p&gt;
&lt;p style="padding-left: 1em;"&gt;
&lt;code&gt; public bool Equals(IDictionary&amp;lt;K, V&gt; x, IDictionary&amp;lt;K, V&gt; y)&lt;br /&gt;
{&lt;br /&gt;
if (x == y)&lt;br /&gt;
{&lt;br /&gt;
return true;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
if ((x == null) || (y == null) || (x.Count != y.Count))&lt;br /&gt;
{&lt;br /&gt;
return false;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
foreach(var entry in x)&lt;br /&gt;
{&lt;br /&gt;
V value;&lt;br /&gt;
&lt;br /&gt;
if (!y.TryGetValue(entry.Key, out value) ||&lt;br /&gt;
!valueComparer.Equals(entry.Value, value))&lt;br /&gt;
{&lt;br /&gt;
return false;&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
return true;&lt;br /&gt;
} &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
But how would you implement hash code?
&lt;/p&gt;
&lt;p&gt;
We argued like this.
&lt;/p&gt;
&lt;p&gt;
1. Let&amp;#39;s consider the dictionary as a sparse array of values with only populated
items that correspond to key hash codes.
&lt;/p&gt;
&lt;p&gt;
2. Hash code is constructed using some fair algorithm. E.g like that used in java
to calculate &lt;a href="http://en.wikipedia.org/wiki/Java_hashCode()"&gt;string&amp;#39;s hash
code&lt;/a&gt;:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; n-1&lt;br /&gt;
h(s) = SUM (s[i]*p^(n-1-i)) mod m, where m = 2^31&lt;br /&gt;
i=0&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
In our case:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;n&lt;/code&gt; can be arbitrary large &lt;code&gt;int&lt;/code&gt; value, so in fact it&amp;#39;s &lt;code&gt;2^32&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
items are enumerated in unknown order;&lt;/li&gt;
&lt;li&gt;
there is only limited set of items, so most &lt;code&gt;s[i]&lt;/code&gt; are zeros.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
As result we cannot use recurrent function to calculate a power &lt;code&gt;p^k mod m.&lt;/code&gt; Fortunately
one can build fast exponentiation arguing like this:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; 32/s - 1&lt;br /&gt;
p^k = p^ SUM 2^((s*i)*k[i]) mod m, where s some int: 1, 2, 4, 8, 16, or 32.&lt;br /&gt;
i=0&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Thus
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; 32/s - 1&lt;br /&gt;
p^k = PRODUCT (p^(2^(s*i)))^k[i] mod m&lt;br /&gt;
i=0&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
If &lt;code&gt;s = 1&lt;/code&gt; then &lt;code&gt;k[i]&lt;/code&gt; is either &lt;code&gt;1&lt;/code&gt; or &lt;code&gt;0&lt;/code&gt; (a
bit), and there is &lt;code&gt;32&lt;/code&gt; different &lt;code&gt;p^(2^i) mod m&lt;/code&gt; values, which
can be precalculated.
&lt;/p&gt;
&lt;p&gt;
On the other hand, if we select &lt;code&gt;s = 8&lt;/code&gt; we can write the formula as:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt;p^k = p^k[0] * (p^(2^8))^k[1] * (p^(2^16))^k[2] * (p^(2^24))^k[3] mod m&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
where &lt;code&gt;k[i]&lt;/code&gt; is a &lt;code&gt;8&lt;/code&gt; bit value (byte). 
&lt;/p&gt;
&lt;p style="direction: ltr"&gt;
Precalculating all values &lt;code&gt;p^n, (p^(2^8))^n&lt;/code&gt;, &lt;code&gt;(p^(2^16))^n&lt;/code&gt;, &lt;code&gt;(p^(2^24))^n&lt;/code&gt; for &lt;code&gt;n&lt;/code&gt; in &lt;code&gt;0&lt;/code&gt; to &lt;code&gt;255&lt;/code&gt; we
reach the formula with &lt;code&gt;4&lt;/code&gt; multiplications and with &lt;code&gt;1024&lt;/code&gt; precalculated
values.
&lt;/p&gt;
&lt;p&gt;
Here is the whole utility to calculate hash factors:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; /// &amp;lt;summary&gt;&lt;br /&gt;
/// Hash utilities.&lt;br /&gt;
/// &amp;lt;/summary&gt;&lt;br /&gt;
public class Hash&lt;br /&gt;
{ 
&lt;br /&gt;
/// &amp;lt;summary&gt;&lt;br /&gt;
/// Returns a P^value mod 2^31, where P is hash base.&lt;br /&gt;
/// &amp;lt;/summary&gt;&lt;br /&gt;
/// &amp;lt;param name="value"&gt;A value to get hash factor for.&amp;lt;/param&gt;&lt;br /&gt;
/// &amp;lt;returns&gt;A hash factor value.&amp;lt;/returns&gt;&lt;br /&gt;
public static int GetHashFactor(int value)&lt;br /&gt;
{&lt;br /&gt;
return factors[(uint)value &amp; 0xff] *&lt;br /&gt;
factors[(((uint)value &gt;&gt; 8) &amp; 0xff) | 0x100] *&lt;br /&gt;
factors[(((uint)value &gt;&gt; 16) &amp; 0xff) | 0x200] *&lt;br /&gt;
factors[(((uint)value &gt;&gt; 24) &amp; 0xff) | 0x300];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/// &amp;lt;summary&gt;&lt;br /&gt;
/// Initializes hash factors.&lt;br /&gt;
/// &amp;lt;/summary&gt;&lt;br /&gt;
static Hash()&lt;br /&gt;
{&lt;br /&gt;
var values = new int[4 * 256];&lt;br /&gt;
var value = P;&lt;br /&gt;
var current = 1;&lt;br /&gt;
var i = 0;&lt;br /&gt;
&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
values[i++] = current;&lt;br /&gt;
current *= value;&lt;br /&gt;
}&lt;br /&gt;&lt; 256);&lt;br /&gt;
while(i 
&lt;br /&gt;
value = current;&lt;br /&gt;
current = 1;&lt;br /&gt;
&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
values[i++] = current;&lt;br /&gt;
current *= value;&lt;br /&gt;
}&lt;br /&gt;&lt; 512);&lt;br /&gt;
while(i 
&lt;br /&gt;
value = current;&lt;br /&gt;
current = 1;&lt;br /&gt;
&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
values[i++] = current;&lt;br /&gt;
current *= value;&lt;br /&gt;
}&lt;br /&gt;&lt; 768);&lt;br /&gt;
while(i 
&lt;br /&gt;
value = current;&lt;br /&gt;
current = 1;&lt;br /&gt;
&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
values[i++] = current;&lt;br /&gt;
current *= value;&lt;br /&gt;
}&lt;br /&gt;&lt; 1024);&lt;br /&gt;
while(i 
&lt;br /&gt;
factors = values;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/// &amp;lt;summary&gt;&lt;br /&gt;
/// A base to calculate hash factors.&lt;br /&gt;
/// &amp;lt;/summary&gt;&lt;br /&gt;
public const int P = 1103515245;&lt;br /&gt;
&lt;br /&gt;
/// &amp;lt;summary&gt;&lt;br /&gt;
/// Hash factors.&lt;br /&gt;
/// &amp;lt;/summary&gt;&lt;br /&gt;
private static readonly int[] factors;&lt;br /&gt;
} &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
With this API hash code for a dictionary is a trivial operation:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; public int GetHashCode(IDictionary&amp;lt;K, V&gt; dictionary)&lt;br /&gt;
{&lt;br /&gt;
if (dictionary == null)&lt;br /&gt;
{&lt;br /&gt;
return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var result = 0;&lt;br /&gt;
&lt;br /&gt;
foreach(var entry in dictionary)&lt;br /&gt;
{&lt;br /&gt;
if ((entry.Key == null) || (entry.Value == null))&lt;br /&gt;
{&lt;br /&gt;
continue;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
result += Hash.GetHashFactor(keyComparer.GetHashCode(entry.Key)) *&lt;br /&gt;
valueComparer.GetHashCode(entry.Value);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
return result;&lt;br /&gt;
} &lt;/code&gt; 
&lt;/p&gt;
&lt;p&gt;
And finally, here is a reference to a class &lt;code&gt;&lt;a href="http://nesterovsky-bros.com/download/DictionaryEqualityComparer.cs.txt"&gt;DictionaryEqualityComparer&amp;lt;K,
V&gt;&lt;/a&gt;: IEqualityComparer&amp;lt;IDictionary&amp;lt;K, V&gt;&amp;gt;&lt;/code&gt; that allows a dictionary
to be a key in another dictionary.
&lt;/p&gt;
&lt;p style="font-weight: bold"&gt;
Update
&lt;/p&gt;
&lt;p&gt;
We have commited some tests, and have found that with suffiently &amp;quot;good&amp;quot;
implementation of GetHashCode() of key or value we achieve results almost of the same
quality, as the results of the algorithm we have outlined above with much simpler
and straightforward algorithm like this:
&lt;/p&gt;
&lt;p style="padding-left: 1em"&gt;
&lt;code&gt; public int GetHashCode(IDictionary&amp;lt;K, V&gt; dictionary)&lt;br /&gt;
{&lt;br /&gt;
if (dictionary == null)&lt;br /&gt;
{&lt;br /&gt;
return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var result = 0;&lt;br /&gt;
&lt;br /&gt;
foreach(var entry in dictionary)&lt;br /&gt;
{&lt;br /&gt;
if ((entry.Key == null) || (entry.Value == null))&lt;br /&gt;
{&lt;br /&gt;
continue;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var k = entry.Key.GetHashCode();&lt;br /&gt;
var v = entry.Value.GetHashCode();&lt;br /&gt;
&lt;br /&gt;&lt;&lt; 5) + k;&lt;br /&gt;&lt;&lt; (k &gt;
k = (k v = (v &gt; 3)) + v;&lt;br /&gt;
&lt;br /&gt;
result += k ^ v;&lt;br /&gt;
&lt;br /&gt;
//result += Hash.GetHashFactor(keyComparer.GetHashCode(entry.Key)) *&lt;br /&gt;
// valueComparer.GetHashCode(entry.Value);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
return result;&lt;br /&gt;
} &lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
It was worth to blog about this just to find out that we have outwitted ourselves,
and finally to reach to a trivial hash code implementation for the dictionary.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=bc06427b-87e2-4e14-9ebb-1a186f875e3a" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,bc06427b-87e2-4e14-9ebb-1a186f875e3a.aspx</comments>
      <category>.NET</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=4abc49ac-23b2-448e-9951-f94e2393d672</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,4abc49ac-23b2-448e-9951-f94e2393d672.aspx</pingback:target>
      <dc:creator>Arthur Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,4abc49ac-23b2-448e-9951-f94e2393d672.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=4abc49ac-23b2-448e-9951-f94e2393d672</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Dealing recently with some task, we were in a position to use a weak dictionary in
the .NET. Instinctively we assumed that it should exist somewhere in the standard
library. We definitely knew that there is a <code>WeakReference</code> class to for
a single instance. We also knew that there is <code>WeakHashMap</code> in java, and
that it's based on java's <code>WeakReference</code>.
</p>
        <p>
So, we were surprised to find that there is no such thing out of the box in .NET.
</p>
        <p>
We have found that java's and .NET's weak references are different. In java
weak references whose targets are GCed can be automatically put into a queue, which
can be used to build clean up logic to remove dead keys from weak hash map. There
is nothing similar in .NET, where weak reference just silently loses it's value.
</p>
        <p>
Internet is full with custom implementations of weak dictionaries in .NET.
</p>
        <p>
.NET 4.5 finally defines a class <a href="http://msdn.microsoft.com/en-us/library/dd287757(v=vs.110).aspx"><code>ConditionalWeakTable&lt;TKey,
TValue&gt;</code></a>, which solves the problem in case when you need to match keys
by instance identity.
</p>
        <p>
Unfortunately in our case we needed to match keys using key's <code>GetHashCode()</code> and <code>Equals()</code>.
So, <code>ConditionalWeakTable&lt;TKey, TValue&gt;</code> did not directly work, but
then we found a way to make it work for us.
</p>
        <p>
Here is a quote from the definition:
</p>
        <p style="padding-left: 1em; font-style: italic">
A <code>ConditionalWeakTable&lt;TKey, TValue&gt;</code> object is a dictionary that binds
a managed object, which is represented by a key, to its attached property, which is
represented by a value. The object's keys are the individual instances of the TKey
class to which the property is attached, and its values are the property values that
are assigned to the corresponding objects.<br /><br />
...in the <code>ConditionalWeakTable&lt;TKey, TValue&gt;</code> class, adding a key/value
pair to the table does not ensure that the key will persist, even if it can be reached
directly from a value stored in the table... Instead, ConditionalWeakTable&lt;TKey,
TValue&gt; automatically removes the key/value entry as soon as no other references to
a key exist outside the table. 
</p>
        <p>
This property of <code>ConditionalWeakTable&lt;TKey, TValue&gt;</code> has helped
us to build a way to get a notification when the key is being finalized, which is
the missed ingredient in .NET's weak references.
</p>
        <p>
Assume you have an instance <code>key</code> of type <code>Key</code>. To get a notification
you should define a class <code>Finalizer</code> that will call some handler when
it's finalized, and you should bind <code>key</code> and a finalizer instance
using weak table.
</p>
        <p>
The code looks like this:
</p>
        <p>
          <code>public class Finalizer&lt;K&gt;<br />
  where K: class<br />
{<br />
  public static void Bind(K key, Action&lt;K&gt; handler)<br />
  {<br />
    var finalizer = table.GetValue(key, k =&gt; new Finalizer&lt;K&gt;
{ key = k });<br /><br />
    finalizer.Handler += handler;<br />
  }<br /><br />
  public static void Unbind(K key, Action&lt;K&gt; handler)<br />
  {<br />
    Finalizer finalizer;<br /><br />
    if (table.TryGetValue(key, out finalizer))<br />
    {<br />
      finalizer.Handler -= handler;<br />
    }<br />
  }<br /><br />
  ~Finalizer()<br />
  {<br />
    var handler = Handler;<br /><br />
    if (handler != null)<br />
    {<br />
      handler(key);<br />
    }<br />
  }<br /><br />
  private event Action&lt;K&gt; Handler;<br />
  private K key;<br /><br />
  private static readonly ConditionalWeakTable&lt;K, Finalizer&gt; table =<br />
    new ConditionalWeakTable&lt;K, Finalizer&gt;();<br />
}<br /><br /><br />
Key key = ...<br /><br />
Finalizer.Bind(key, k =&gt; { /* clean up. */ });</code>
        </p>
        <p>
Using this approach we have created a class <a href="http://nesterovsky-bros.com/download/WeakTable.cs.txt">WeakTable&lt;K,
V&gt;</a> modeled after ConditionalWeakTable&lt;TKey, TValue&gt;.
</p>
        <p>
So, this is our take in the problem: <a href="http://nesterovsky-bros.com/download/WeakTable.cs.txt">WeakTable.cs</a>.
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=4abc49ac-23b2-448e-9951-f94e2393d672" />
      </body>
      <title>WeakTable</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,4abc49ac-23b2-448e-9951-f94e2393d672.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2014/01/08/WeakTable.aspx</link>
      <pubDate>Wed, 08 Jan 2014 21:57:16 GMT</pubDate>
      <description>    &lt;p&gt;
Dealing recently with some task, we were in a position to use a weak dictionary in
the .NET. Instinctively we assumed that it should exist somewhere in the standard
library. We definitely knew that there is a &lt;code&gt;WeakReference&lt;/code&gt; class to for
a single instance. We also knew that there is &lt;code&gt;WeakHashMap&lt;/code&gt; in java, and
that it&amp;#39;s based on java&amp;#39;s &lt;code&gt;WeakReference&lt;/code&gt;.
&lt;/p&gt;
&lt;p&gt;
So, we were surprised to find that there is no such thing out of the box in .NET.
&lt;/p&gt;
&lt;p&gt;
We have found that java&amp;#39;s and .NET&amp;#39;s weak references are different. In java
weak references whose targets are GCed can be automatically put into a queue, which
can be used to build clean up logic to remove dead keys from weak hash map. There
is nothing similar in .NET, where weak reference just silently loses it&amp;#39;s value.
&lt;/p&gt;
&lt;p&gt;
Internet is full with custom implementations of weak dictionaries in .NET.
&lt;/p&gt;
&lt;p&gt;
.NET 4.5 finally defines a class &lt;a href="http://msdn.microsoft.com/en-us/library/dd287757(v=vs.110).aspx"&gt;&lt;code&gt;ConditionalWeakTable&amp;lt;TKey,
TValue&amp;gt;&lt;/code&gt;&lt;/a&gt;, which solves the problem in case when you need to match keys
by instance identity.
&lt;/p&gt;
&lt;p&gt;
Unfortunately in our case we needed to match keys using key&amp;#39;s &lt;code&gt;GetHashCode()&lt;/code&gt; and &lt;code&gt;Equals()&lt;/code&gt;.
So, &lt;code&gt;ConditionalWeakTable&amp;lt;TKey, TValue&amp;gt;&lt;/code&gt; did not directly work, but
then we found a way to make it work for us.
&lt;/p&gt;
&lt;p&gt;
Here is a quote from the definition:
&lt;/p&gt;
&lt;p style="padding-left: 1em; font-style: italic"&gt;
A &lt;code&gt;ConditionalWeakTable&amp;lt;TKey, TValue&gt;&lt;/code&gt; object is a dictionary that binds
a managed object, which is represented by a key, to its attached property, which is
represented by a value. The object's keys are the individual instances of the TKey
class to which the property is attached, and its values are the property values that
are assigned to the corresponding objects.&lt;br /&gt;
&lt;br /&gt;
...in the &lt;code&gt;ConditionalWeakTable&amp;lt;TKey, TValue&gt;&lt;/code&gt; class, adding a key/value
pair to the table does not ensure that the key will persist, even if it can be reached
directly from a value stored in the table... Instead, ConditionalWeakTable&amp;lt;TKey,
TValue&gt; automatically removes the key/value entry as soon as no other references to
a key exist outside the table. 
&lt;/p&gt;
&lt;p&gt;
This property of &lt;code&gt;ConditionalWeakTable&amp;lt;TKey, TValue&amp;gt;&lt;/code&gt; has helped
us to build a way to get a notification when the key is being finalized, which is
the missed ingredient in .NET&amp;#39;s weak references.
&lt;/p&gt;
&lt;p&gt;
Assume you have an instance &lt;code&gt;key&lt;/code&gt; of type &lt;code&gt;Key&lt;/code&gt;. To get a notification
you should define a class &lt;code&gt;Finalizer&lt;/code&gt; that will call some handler when
it&amp;#39;s finalized, and you should bind &lt;code&gt;key&lt;/code&gt; and a finalizer instance
using weak table.
&lt;/p&gt;
&lt;p&gt;
The code looks like this:
&lt;/p&gt;
&lt;p&gt;
&lt;code&gt;public class Finalizer&amp;lt;K&amp;gt;&lt;br /&gt;
&amp;nbsp; where K: class&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; public static void Bind(K key, Action&amp;lt;K&amp;gt; handler)&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; var finalizer = table.GetValue(key, k =&amp;gt; new Finalizer&amp;lt;K&amp;gt;
{ key = k });&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; finalizer.Handler += handler;&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; public static void Unbind(K key, Action&amp;lt;K&amp;gt; handler)&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Finalizer finalizer;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (table.TryGetValue(key, out finalizer))&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; finalizer.Handler -= handler;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; ~Finalizer()&lt;br /&gt;
&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; var handler = Handler;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (handler != null)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; handler(key);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; private event Action&amp;lt;K&amp;gt; Handler;&lt;br /&gt;
&amp;nbsp; private K key;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; private static readonly ConditionalWeakTable&amp;lt;K, Finalizer&amp;gt; table =&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; new ConditionalWeakTable&amp;lt;K, Finalizer&amp;gt;();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Key key = ...&lt;br /&gt;
&lt;br /&gt;
Finalizer.Bind(key, k =&amp;gt; { /* clean up. */ });&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
Using this approach we have created a class &lt;a href="http://nesterovsky-bros.com/download/WeakTable.cs.txt"&gt;WeakTable&amp;lt;K,
V&amp;gt;&lt;/a&gt; modeled after ConditionalWeakTable&amp;lt;TKey, TValue&amp;gt;.
&lt;/p&gt;
&lt;p&gt;
So, this is our take in the problem: &lt;a href="http://nesterovsky-bros.com/download/WeakTable.cs.txt"&gt;WeakTable.cs&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=4abc49ac-23b2-448e-9951-f94e2393d672" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,4abc49ac-23b2-448e-9951-f94e2393d672.aspx</comments>
      <category>.NET</category>
      <category>Java</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=c68bb7ae-17f0-42f6-81d0-d93ebc20008c</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,c68bb7ae-17f0-42f6-81d0-d93ebc20008c.aspx</pingback:target>
      <dc:creator>Arthur Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,c68bb7ae-17f0-42f6-81d0-d93ebc20008c.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=c68bb7ae-17f0-42f6-81d0-d93ebc20008c</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
A day ago we had installed on our laptops Win 8.1. We thought it will be better than
Win 8, but now we afraid of next release of Windows... So far, so worse.
</p>
        <p>
ICS became unusable: in Windows 7 we've shared Internet connection from USB 3G dongle
between our two computers, in Windows 8 we've succeeded to share only file system
access, but not Internet. In Windows 8.1 neither Internet nor file system are accessible...
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=c68bb7ae-17f0-42f6-81d0-d93ebc20008c" />
      </body>
      <title>Windows: so far so worse</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,c68bb7ae-17f0-42f6-81d0-d93ebc20008c.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2013/11/04/WindowsSoFarSoWorse.aspx</link>
      <pubDate>Mon, 04 Nov 2013 11:20:28 GMT</pubDate>
      <description>&lt;p&gt;
A day ago we had installed on our laptops Win 8.1. We thought it will be better than
Win 8, but now we afraid of next release of Windows... So far, so worse.
&lt;/p&gt;
&lt;p&gt;
ICS became unusable: in Windows 7 we've shared Internet connection from USB 3G dongle
between our two computers, in Windows 8 we've succeeded to share only file system
access, but not Internet. In Windows 8.1 neither Internet nor file system are accessible...
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=c68bb7ae-17f0-42f6-81d0-d93ebc20008c" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,c68bb7ae-17f0-42f6-81d0-d93ebc20008c.aspx</comments>
      <category>Thinking aloud</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=7cf68687-5531-41ee-bf63-10b62592157a</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,7cf68687-5531-41ee-bf63-10b62592157a.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,7cf68687-5531-41ee-bf63-10b62592157a.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=7cf68687-5531-41ee-bf63-10b62592157a</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Till recently we were living in simple world of string comparisons in SQL style, and
now everything has changed. 
</p>
        <p>
From the university years we knew that strings in SQL are compared by first trimming
traling spaces, and then comparing in C style. 
</p>
        <p>
Well, the picture was a little more complex, as collations were involved (national,
case sensivity), and as different SQL vendors implemented it differently. 
</p>
        <p>
Next,<br />
we're dealing with programs converted from COBOL, which we originally thought
follow SQL rules when strings are compared. 
</p>
        <p>
  
</p>
        <p>
Here is where the problem has started. 
</p>
        <p>
Once we have found that java program has branched differently than original COBOL,
and the reason was that the COBOL and java compared two strings differently: 
</p>
        <ul>
          <li>
COBOL: <code>"A\n" &lt; "A"</code>;</li>
          <li>
Java: <code>"A\n" &gt; "A"</code></li>
        </ul>
        <p>
We have looked into <a href="http://pic.dhe.ibm.com/infocenter/pdthelp/v1r1/index.jsp?topic=%2Fcom.ibm.entcobol.doc_3.4%2Frlpdsalp.htm"> COBOL
Language Reference</a> and found the rules: 
</p>
        <div style="padding-left: 1em; font-style: italic">
          <dl>
            <dt style="font-weight: bold">Operands of equal size</dt>
            <dd>
Characters in corresponding positions of the two operands are compared, beginning
with the leftmost character and continuing through the rightmost character. 
<p>
If all pairs of characters through the last pair test as equal, the operands are considered
as equal. 
</p><p>
If a pair of unequal characters is encountered, the characters are tested to determine
their relative positions in the collating sequence. The operand that contains the
character higher in the sequence is considered the greater operand. 
</p></dd>
            <dt style="font-weight: bold">Operands of unequal size</dt>
            <dd>
If the operands are of unequal size, the comparison is made as though the shorter
operand were extended to the right with enough spaces to make the operands equal in
size. 
</dd>
          </dl>
        </div>
        <p>
You can see that strings must not be trimmed but padded with spaces to the longer
string, and only then they are compared. This subtle difference has significant impact
for characters below the space.
</p>
        <p>
So, here we've found that COBOL and SQL comparisons are different.
</p>
        <p>
But then we have questioned how really SQL beheaves?
</p>
        <p>
We've tested comparisons in SQL Server and DB2, and have seen that our understanding
of SQL comparison holds. It works as if trimming spaces, and then comparing.
</p>
        <p>
But again we have looked into SQL-92 definition, and that's what we see there:
</p>
        <p style="font-style: italic; padding-left: 1em">
8.2 &lt;comparison predicate&gt;<br />
3) The comparison of two character strings is determined as follows:<br /><br />
a) If the length in characters of X is not equal to the length in characters of Y,
then the shorter string is effectively replaced, for the purposes of comparison, with
a copy of itself that has been extended to the length of the longer string by concatenation
on the right of one or more pad characters, where the pad character is chosen based
on CS. If CS has the NO PAD attribute, then the pad character is an implementation-dependent
character different from any character in the character set of X and Y that collates
less than any string under CS. Otherwise, the pad character is a &lt;space&gt;.
</p>
        <p>
So, what we see is that SQL-92 rules are very close to COBOL rules, but then we reach
the question: how come that at least SQL Server and DB2 implement string comparison
differently than SQL-92 dictates?
</p>
        <p>
          <b>Update: </b> we have found that both SQL Server and DB2 have their string collation
defined in a way that &lt;space&gt; is less than any other character. So the following
is always true: <code>'[' + char(13) + ']' &gt; '[ ]'</code>. 
</p>
        <img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=7cf68687-5531-41ee-bf63-10b62592157a" />
      </body>
      <title>String comparision: SQL vs COBOL</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,7cf68687-5531-41ee-bf63-10b62592157a.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2013/10/14/StringComparisionSQLVsCOBOL.aspx</link>
      <pubDate>Mon, 14 Oct 2013 20:23:11 GMT</pubDate>
      <description>  &lt;p&gt;
Till recently we were living in simple world of string comparisons in SQL style, and
now everything has changed. 
&lt;/p&gt;
&lt;p&gt;
From the university years we knew that strings in SQL are compared by first trimming
traling spaces, and then comparing in C style. 
&lt;/p&gt;
&lt;p&gt;
Well, the picture was a little more complex, as collations were involved (national,
case sensivity), and as different SQL vendors implemented it differently. 
&lt;/p&gt;
&lt;p&gt;
Next,&lt;br /&gt;
we&amp;#39;re dealing with programs converted from COBOL, which we originally thought
follow SQL rules when strings are compared. 
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
Here is where the problem has started. 
&lt;/p&gt;
&lt;p&gt;
Once we have found that java program has branched differently than original COBOL,
and the reason was that the COBOL and java compared two strings differently: 
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
COBOL: &lt;code&gt;&amp;quot;A\n&amp;quot; &amp;lt; &amp;quot;A&amp;quot;&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
Java: &lt;code&gt;&amp;quot;A\n&amp;quot; &amp;gt; &amp;quot;A&amp;quot;&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
We have looked into &lt;a href="http://pic.dhe.ibm.com/infocenter/pdthelp/v1r1/index.jsp?topic=%2Fcom.ibm.entcobol.doc_3.4%2Frlpdsalp.htm"&gt; COBOL
Language Reference&lt;/a&gt; and found the rules: 
&lt;/p&gt;
&lt;div style="padding-left: 1em; font-style: italic"&gt;
&lt;dl&gt;
&lt;dt style="font-weight: bold"&gt;Operands of equal size&lt;/dt&gt; 
&lt;dd&gt;
Characters in corresponding positions of the two operands are compared, beginning
with the leftmost character and continuing through the rightmost character. 
&lt;p&gt;
If all pairs of characters through the last pair test as equal, the operands are considered
as equal. 
&lt;/p&gt;
&lt;p&gt;
If a pair of unequal characters is encountered, the characters are tested to determine
their relative positions in the collating sequence. The operand that contains the
character higher in the sequence is considered the greater operand. 
&lt;/p&gt;
&lt;/dd&gt;
&lt;dt style="font-weight: bold"&gt;Operands of unequal size&lt;/dt&gt; 
&lt;dd&gt;
If the operands are of unequal size, the comparison is made as though the shorter
operand were extended to the right with enough spaces to make the operands equal in
size. 
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;
&lt;p&gt;
You can see that strings must not be trimmed but padded with spaces to the longer
string, and only then they are compared. This subtle difference has significant impact
for characters below the space.
&lt;/p&gt;
&lt;p&gt;
So, here we've found that COBOL and SQL comparisons are different.
&lt;/p&gt;
&lt;p&gt;
But then we have questioned how really SQL beheaves?
&lt;/p&gt;
&lt;p&gt;
We've tested comparisons in SQL Server and DB2, and have seen that our understanding
of SQL comparison holds. It works as if trimming spaces, and then comparing.
&lt;/p&gt;
&lt;p&gt;
But again we have looked into SQL-92 definition, and that&amp;#39;s what we see there:
&lt;/p&gt;
&lt;p style="font-style: italic; padding-left: 1em"&gt;
8.2 &amp;lt;comparison predicate&amp;gt;&lt;br /&gt;
3) The comparison of two character strings is determined as follows:&lt;br /&gt;
&lt;br /&gt;
a) If the length in characters of X is not equal to the length in characters of Y,
then the shorter string is effectively replaced, for the purposes of comparison, with
a copy of itself that has been extended to the length of the longer string by concatenation
on the right of one or more pad characters, where the pad character is chosen based
on CS. If CS has the NO PAD attribute, then the pad character is an implementation-dependent
character different from any character in the character set of X and Y that collates
less than any string under CS. Otherwise, the pad character is a &amp;lt;space&amp;gt;.
&lt;/p&gt;
&lt;p&gt;
So, what we see is that SQL-92 rules are very close to COBOL rules, but then we reach
the question: how come that at least SQL Server and DB2 implement string comparison
differently than SQL-92 dictates?
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;Update: &lt;/b&gt; we have found that both SQL Server and DB2 have their string collation
defined in a way that &amp;lt;space&amp;gt; is less than any other character. So the following
is always true: &lt;code&gt;'[' + char(13) + ']' &gt; '[ ]'&lt;/code&gt;. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=7cf68687-5531-41ee-bf63-10b62592157a" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,7cf68687-5531-41ee-bf63-10b62592157a.aspx</comments>
      <category>Java</category>
      <category>SQL Server puzzle</category>
      <category>Thinking aloud</category>
      <category>Tips and tricks</category>
    </item>
    <item>
      <trackback:ping>http://www.nesterovsky-bros.com/weblog/Trackback.aspx?guid=90f39a37-545a-4176-b3e2-feedd23a3204</trackback:ping>
      <pingback:server>http://www.nesterovsky-bros.com/weblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.nesterovsky-bros.com/weblog/PermaLink,guid,90f39a37-545a-4176-b3e2-feedd23a3204.aspx</pingback:target>
      <dc:creator>Vladimir Nesterovsky</dc:creator>
      <georss:point>0 0</georss:point>
      <wfw:comment>http://www.nesterovsky-bros.com/weblog/CommentView,guid,90f39a37-545a-4176-b3e2-feedd23a3204.aspx</wfw:comment>
      <wfw:commentRss>http://www.nesterovsky-bros.com/weblog/SyndicationService.asmx/GetEntryCommentsRss?guid=90f39a37-545a-4176-b3e2-feedd23a3204</wfw:commentRss>
      <title>On Garbage Collectors</title>
      <guid isPermaLink="false">http://www.nesterovsky-bros.com/weblog/PermaLink,guid,90f39a37-545a-4176-b3e2-feedd23a3204.aspx</guid>
      <link>http://www.nesterovsky-bros.com/weblog/2013/07/14/OnGarbageCollectors.aspx</link>
      <pubDate>Sun, 14 Jul 2013 12:20:29 GMT</pubDate>
      <description>&lt;p&gt;
Recently we've seen an article &lt;a href="http://sealedabstract.com/rants/why-mobile-web-apps-are-slow/"&gt;Why
mobile web apps are slow&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
While title mentions web apps, the the criticism is directed purely to javascript
language. The answer presented there is twofold:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Raw javascript performance is ~5 times slower than performance of native code solving
the same task. 
&lt;p&gt;
This accounts for the most modern implementations that exploit JIT. Author does not
expect that this proportion will be significatly changed in javascript&amp;#39;s favor
in the near future.
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
Garbage Collection, which is essential part of javascript, does not work well in constrainted
environment of mobile devices. 
&lt;p&gt;
Here author quotes many references that show that:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
for GC to work on peer with non-GC application, it needs to have ~6 - 8 times size
of memory than an application needs;&lt;/li&gt;
&lt;li&gt;
at the same time for hardware reasons, mobile devices cannot provide such amount of
memory;&lt;/li&gt;
&lt;li&gt;
on the other hand with rise of CPU performance, GC pressure rises even faster.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
In the end author, while saying about some attempts to change the state, has no final
verdict, whether there can be anything done to remedy the problem.
&lt;/p&gt;
&lt;p&gt;
Having roots in C++, we&amp;#39;re GC unbelievers. But you know, who will ask your opinion
on that, while there are all those modern languages that try to abstract from memory
and implicitly or explicitly assume GC: java, C#, javascript, xslt, xquery, and so
on.
&lt;/p&gt;
&lt;p&gt;
There always is a solution to avoid GC completely, like C++ and other (e.g. Microsoft&amp;#39;s
C++/CX, or Apple&amp;#39;s ARC) do. But, assuming you&amp;#39;re entered GC world, what can
be done with it? How do you make it more predictable, less greedy, and probably more
fast?
&lt;/p&gt;
&lt;p&gt;
Our arguments are like this.
&lt;/p&gt;
&lt;p&gt;
How does native code manage object graphs? 
&lt;/p&gt;
&lt;p&gt;
Today&amp;#39;s solution is reference counting along with weak references to break cycles
in graph.
&lt;/p&gt;
&lt;p&gt;
Can be GC based on this?
&lt;/p&gt;
&lt;p&gt;
Yes. 
&lt;/p&gt;
&lt;p&gt;
In fact upcoming spec of javascript contains weak references. So, provided a developer
accurately defines relations in an object graph, one may immediately achieve the same
efficiency as native solution.
&lt;/p&gt;
&lt;p&gt;
If one does not use weak references consistently then object cycles can be created,
so there can appear a graph that is not referenced anywhere in a program. This graph
can be collected with classical GC that scans object roots.
&lt;/p&gt;
&lt;p&gt;
Classical GC part can be used as a debug mode leak detector, and will collect graph
cycles at runtime.
&lt;/p&gt;
&lt;p&gt;
Thus, we claim that a hybrid memory management: reference counting with weak references
plus classical GC is possible; it will be equal to a native memory management when
weak references are properly used, and it will be close to classical GC without use
of weak references.
&lt;/p&gt;
&lt;p&gt;
This solution gives a rule to mitigate GC drawbacks: just use weak references in appropriate
points, and you can continue to live in GC world, where GC is only a fallback. &gt;
&lt;img width="0" height="0" src="http://www.nesterovsky-bros.com/weblog/aggbug.ashx?id=90f39a37-545a-4176-b3e2-feedd23a3204" /&gt;</description>
      <comments>http://www.nesterovsky-bros.com/weblog/CommentView,guid,90f39a37-545a-4176-b3e2-feedd23a3204.aspx</comments>
      <category>javascript</category>
      <category>Thinking aloud</category>
    </item>
  </channel>
</rss>