<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>ESE/ESENT Database Stuff</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/laurionb/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/laurionb/feed.xml</link>
    <description />
    <lastBuildDate>Wed, 17 Apr 2019 03:24:11 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>ManagedEsent 1.6 released. LINQ support for PersistentDictionary.</title>
      <link>https://docs.microsoft.com/archive/blogs/laurionb/managedesent-1-6-released-linq-support-for-persistentdictionary</link>
      <pubDate>Tue, 15 Feb 2011 15:09:20 GMT</pubDate>
      <dc:creator><![CDATA[Laurion Burchall]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/laurionb/2011/02/15/managedesent-1-6-released-linq-support-for-persistentdictionary/</guid>
      <description><![CDATA[There is a new release of ManagedEsent on Codeplex. There are some new APIs, bugfixes and...]]></description>
      <content:encoded><![CDATA[<p>There is a new release of ManagedEsent on Codeplex. There are some new APIs, bugfixes and performance improvements. </p>
<p>The PersistentDictionary class now supports LINQ -- it&nbsp;can examine a query and retrieve only matching records from the database. Some examples of LINQ queries that work this way:</p>
<pre class="scroll"><code class="csharp">from x in persistentDictionary where x.Key &gt; 3 select x.Value;
<br />from x in persistentDictionary where x.Key.StartsWith("b") select x.Value
<br />from x in persistentDictionary where (x.Key.CompareTo("a") &gt; 0 &amp;&amp; x.Key.CompareTo("c") &lt;= 0) || x.Key.StartsWith("c") select x.Value;
</code><code class="csharp"></code></pre>
<p class="scroll"><code class="csharp"><span style="font-family: arial,helvetica,sans-serif;">I added a new&nbsp;<a href="https://managedesent.codeplex.com/wikipage?title=SystemStats">sample application</a> for the PersistentDictionary, which stores some performance data and allows a simple query.</span></code>&nbsp;</p>
<p class="scroll">For IronPython users there are performance enhancements to the DBM-like esedb module and a new esedbshelve module that provides shelf functionality.</p>
<p class="scroll">&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>ESENT Multivalue tutorial</title>
      <link>https://docs.microsoft.com/archive/blogs/laurionb/esent-multivalue-tutorial</link>
      <pubDate>Thu, 03 Jun 2010 14:48:10 GMT</pubDate>
      <dc:creator><![CDATA[Laurion Burchall]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/laurionb/2010/06/03/esent-multivalue-tutorial/</guid>
      <description><![CDATA[Multivalued columns can be very useful for simplifying data schema and improving performance, but...]]></description>
      <content:encoded><![CDATA[<p>Multivalued columns can be very useful for simplifying data schema and improving performance, but they can be complex to use (they also make Data Normalization geeks feel uneasy). I put a multi-value tutorial up on the ManagedEsent wiki. It uses the managed APIs but would be easy to translate to unmanaged code.</p>
<p><a href="https://managedesent.codeplex.com/wikipage?title=MultiValueTutorial">https://managedesent.codeplex.com/wikipage?title=MultiValueTutorial</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Using ManagedEsent from F#</title>
      <link>https://docs.microsoft.com/archive/blogs/laurionb/using-managedesent-from-f</link>
      <pubDate>Tue, 02 Mar 2010 11:32:00 GMT</pubDate>
      <dc:creator><![CDATA[Laurion Burchall]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/laurionb/2010/03/02/using-managedesent-from-f/</guid>
      <description><![CDATA[Cameron Taggart&nbsp;has a blog entry on using ManagedEsent from...]]></description>
      <content:encoded><![CDATA[<P>Cameron Taggart&nbsp;has a blog entry on using ManagedEsent from F#:&nbsp;</P>
<P><A href="https://blog.ctaggart.com/2010/02/microsofts-extensible-storage-engine.html">https://blog.ctaggart.com/2010/02/microsofts-extensible-storage-engine.html</A></P>
<P>The ESENT programming model centers around a database cursor (JET_TABLEID). The cursor is located on a record,&nbsp;can navigate to other records&nbsp;individual columns can be set/retrieved. This is quite different than a functional programming model, which would center around a stream (enumeration) of records instead of a stateful cursor. I&nbsp;find it interesting&nbsp;seeing what it takes to get&nbsp;the two models working together.</P>
<P mce_keep="true">&nbsp;</P>]]></content:encoded>
    </item>
    <item>
      <title>Version 1.5 of ManagedEsent released. PersistentDictionary goodness</title>
      <link>https://docs.microsoft.com/archive/blogs/laurionb/version-1-5-of-managedesent-released-persistentdictionary-goodness</link>
      <pubDate>Sat, 12 Sep 2009 22:02:00 GMT</pubDate>
      <dc:creator><![CDATA[Laurion Burchall]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/laurionb/2009/09/12/version-1-5-of-managedesent-released-persistentdictionary-goodness/</guid>
      <description><![CDATA[There is a new release of ManagedEsent on Codeplex. There are some new APIs, constants for the new...]]></description>
      <content:encoded><![CDATA[<P>There is a new release of ManagedEsent on <A href="https://managedesent.codeplex.com/" mce_href="https://managedesent.codeplex.com">Codeplex</A>. There are some new APIs, constants for the new Windows 7 ESENT features, bugfixes and performance improvements. </P>
<P>&nbsp;There is also a new Esent.Collections.dll which contains a PersistentDictionary generic class. This is a drop-in compatible replacement for the generic Dictionary or SortedDictionary classes for applications that need very simple data persistence.&nbsp;The database is stored in a location specified in the dictionary constructor.</P><CODE>
<P>var dict&nbsp;= new PersistentDictionary&lt;string, int&gt;("DataDirectory");<BR>dict["foo"] = 17;<BR>dict["bar"] = 18;</P></CODE>
<P>The&nbsp;dictionary entries are persisted automatically&nbsp;and updates are transacted providing data consistency and crash resilience.</P>]]></content:encoded>
    </item>
    <item>
      <title>6 New ESENT features in Windows 7</title>
      <link>https://docs.microsoft.com/archive/blogs/laurionb/6-new-esent-features-in-windows-7</link>
      <pubDate>Tue, 18 Aug 2009 17:35:00 GMT</pubDate>
      <dc:creator><![CDATA[Laurion Burchall]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/laurionb/2009/08/18/6-new-esent-features-in-windows-7/</guid>
      <description><![CDATA[A quick look at some of the new features that are available in the Windows 7 version of ESENT....]]></description>
      <content:encoded><![CDATA[<P>A quick look at some of the new features that are available in the Windows 7 version of ESENT. You'll need esent.h from the Windows 7 SDK to see these definitions:</P>
<P><STRONG>1. Column Compression</STRONG></P>
<P>Columns of type JET_coltypLongBinary and JET_coltypLongText can now be compressed. There are two ways of enabling compression.</P>
<UL>
<LI>Create the column with the JET_bitColumnCompressed flag. This can only be used with long-value columns, otherwise ESENT will return JET_errColumnCannotBeCompressed.</LI>
<LI>Set the column with JET_bitSetCompressed. This flag can be used with any column type, we just ignore it for non-compressable columns. Alternatively you can use JET_bitSetUncompressed when updating a compressed column with data that you don't want compressed.</LI></UL>
<P><EM>How does compression work?</EM></P>
<P>For 'short' columns (less than 1kb in size) we look to see if all the data is 7-bit ASCII characters. If so we compress each character to its 7-bit value. This is the only compression done for short values. It was added to help with the fact that Exchange stores a lot of strings which are often just 7-bit ASCII values, e-mail headers for example. Turning a 16-bit Unicode character to a 7-bit ASCII value gives a large savings and is cheap to do.</P>
<P>For 'long' columns (greater than 1kb) we apply Microsoft's XPRESS compression, which is similar to ZIP or RAR compression. We only store the compressed data if it is smaller than the uncompressed data. Of course determining that data doesn't compress well costs CPU cycles so if you are storing already compressed data you shouldn't use compressed columns.</P>
<P>Unlike SQL Server's page compression this feature is designed to compress large column values, not remove duplication when multiple records have similar values. This is done because this feature was added for Microsoft Exchange, where most of the data is stored in relatively large BLOB columns (e.g. e-mail bodies).</P>
<P><EM>What else do I need to know?</EM></P>
<P>Nothing, really. A compressed column looks just like a normal column and can be indexed, set and retrieved as normal. There is no way to retrieve the compressed data, you will always get uncompressed data when calling JetRetrieveColumn or a similar API. If you want to know how well a record compressed use the new JetGetRecordSize2 API which gives both the logical (uncompressed) and physical (compressed) size of a record.</P>
<P><STRONG>2. 32kb and 16kb page support</STRONG></P>
<P>ESENT now supports 32kb, 16kb and 2kb pages. Changing the page size affects b-tree performance and you may find your application runs faster with bigger pages. Bigger pages also allow more columns to be set in one record before getting JET_errRecordTooLarge.</P>
<P><STRONG>3. JetPrereadKeys</STRONG></P>
<P>If you want to retrieve non-contiguous records quickly you can use JetMakeKey to calculate their keys and then call JetPrereadKeys. Prereading the records will issue the I/O as efficiently as possible, which makes retrieving the records a LOT faster if I/O is involved. Records must be preread in either ascending or descending key order. JetPrereadKeys may not be able to preread all the records so it tells you how many keys were preread so that you can issue a preread call for the rest after processing the initial batch.</P>
<P><STRONG>4. Space Hints</STRONG></P>
<P>In older versions of ESENT you could specify the initial size of a table/index, but didn't have much control over how the table size grew. Space hints allow you to give the initial size of a table/index and then indicate how much space the table should use as it grows. This feature is designed to allow databases with large numbers of tables where the tables start out small (perhaps one page) and then grow their allocation size so that they have contiguous space.</P>
<P><STRONG>5. JET_paramWaypointLatency and JET_bitReplayIgnoreLostLogs</STRONG></P>
<P>Write-ahead logging depends on the underlying storage being durable, which isn't really true for inexpensive desktop-class machines. To improve database recoverability we have added a 'Lost Log Resiliency' (LLR) feature to the Windows 7 version of ESENT. Setting the JET_paramWaypointLatency parameter to a non-zero value will enable the LLR feature, causing ESENT to delay writes to the database until N logfiles have been generated, where N is the waypoint depth.</P>
<P>For example, if the waypoint is set to 1 and the current log generation is 28 then ESENT will not write any pages to the database that have been modified by log records in generation 28. This means that the database can be recovered without the most recent log but there will be data loss! If you are comfortable with some potential data loss and want to emphasise database recovery then set JET_paramWaypointLatency to 1 (or a small value, there is a performance penalty for maintaining the waypoint). You have to use the JET_bitReplayIgnoreLostLogs option with JetInit2 to tell ESENT that it is OK to perform a lossy recovery.</P>
<P>This will allow you to recover your database even if a system crash loses the most recent log. In our power-down testing this improves the chances of a sucessful database recovery after a machine with non-battery-backed write caching is powered down.</P>
<P><BR><STRONG>6. JET_bitTermDirty</STRONG></P>
<P>If you want to shutdown REALLY quickly you can use JET_bitTermDirty, which won't even flush the database cache. Recovery will take longer the next time but no data will be lost.</P>
<P><BR>I know this was a very quick summary. If you have specific questions, leave them in the comments or use the 'contact me' area and I'll try to answer them or provide samples.</P>
<P mce_keep="true">&nbsp;</P>]]></content:encoded>
    </item>
    <item>
      <title>Multimethods in C# 4.0 with 'dynamic'</title>
      <link>https://docs.microsoft.com/archive/blogs/laurionb/multimethods-in-c-4-0-with-dynamic</link>
      <pubDate>Thu, 13 Aug 2009 15:01:00 GMT</pubDate>
      <dc:creator><![CDATA[Laurion Burchall]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/laurionb/2009/08/13/multimethods-in-c-4-0-with-dynamic/</guid>
      <description><![CDATA[(Continuing from the post on implementing the Visitor pattern in C# 4.0)
A virtual method is...]]></description>
      <content:encoded><![CDATA[<P>(Continuing from the post on implementing the Visitor pattern in C# 4.0)</P>
<P>A virtual method is polymorphic in one dimension (the runtime class of the object the method is attached to). Multimethods (multiple dispatch) are polymorphic in multiple dimensions, which can be very useful in some cases. The dynamic keyword in C# 4.0 allows for method selection that depends on the runtime class of the arguments, not just the attached object. This allows true multimethods. (Of course the lookup rules for dynamic&nbsp;are complex so extremely complex cases might not resolve the way you want).</P>
<P>The basic idea is to create method overloads which take all the (subclass1, subclass2) combinations that you are interested in and then have the (superclass, superclass) method cast its arguments to dynamic and then call the method again and let runtime resolution do its thing. In the spirit of the Wikipedia article on multimethods, here is a spaceship/asteroid collision example:</P>
<P>&nbsp;(code edited to separate the names of the methods)</P><CODE>
<P>using System;</P>
<P>namespace MultiMethods<BR>{<BR>&nbsp;&nbsp;&nbsp; class Program<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class Thing { }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class Asteroid : Thing { }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class Spaceship : Thing { }</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static void CollideWithImpl(Asteroid x, Asteroid y) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine("Asteroid hits an Asteroid");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static void CollideWithImpl(Asteroid x, Spaceship y) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine("Asteroid hits a Spaceship");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static void CollideWithImpl(Spaceship x, Asteroid y) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine("Spaceship hits an Asteroid");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static void CollideWithImpl(Spaceship x, Spaceship y) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine("Spaceship hits a Spaceship");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static void CollideWith(Thing x, Thing y)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dynamic a = x;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dynamic b = y;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CollideWithImpl(a, b);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static void Main(string[] args)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var asteroid = new Asteroid();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var spaceship = new Spaceship();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CollideWith(asteroid, spaceship);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CollideWith(spaceship, spaceship);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }<BR>}</P>
<P mce_keep="true">&nbsp;</P></CODE>]]></content:encoded>
    </item>
    <item>
      <title>Implementing the Visitor pattern with the 'dynamic' feature of C# 4.0</title>
      <link>https://docs.microsoft.com/archive/blogs/laurionb/implementing-the-visitor-pattern-with-the-dynamic-feature-of-c-4-0</link>
      <pubDate>Thu, 28 May 2009 19:05:00 GMT</pubDate>
      <dc:creator><![CDATA[Laurion Burchall]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/laurionb/2009/05/28/implementing-the-visitor-pattern-with-the-dynamic-feature-of-c-4-0/</guid>
      <description><![CDATA[A lot of the talk around the new dynamic keyword in C# 4.0 (available in the beta of Visual Studio...]]></description>
      <content:encoded><![CDATA[<P>A lot of the talk around the new dynamic keyword in C# 4.0 (available in the <A href="https://www.microsoft.com/visualstudio/en-us/products/2010/default.mspx" mce_href="https://www.microsoft.com/visualstudio/en-us/products/2010/default.mspx">beta of Visual Studio 2010</A>) is around interaction with external components (dynamic languages, HTML DOM, COM) but I'm most excited about being able to stragetically add dynamic lookup to an ordinary C# program. Normally, when an object is passed to a method the method lookup&nbsp;depends on the compile-time type of the object. This means that code like this:</P><CODE>
<P>class MyClass<BR>{<BR>&nbsp;public void Foo(Stream s) { Console.WriteLine("Stream"); }<BR>&nbsp;public void Foo(MemoryStream s) { Console.WriteLine("MemoryStream"); }<BR>}</P>
<P>class Program<BR>{<BR>&nbsp;static void DoSomething(Stream s)<BR>&nbsp;{<BR>&nbsp;&nbsp;MyClass obj = new MyClass();<BR>&nbsp;&nbsp;obj.Foo(s);<BR>&nbsp;}</P>
<P>&nbsp;static void Main(string[] args)<BR>&nbsp;{<BR>&nbsp;&nbsp;DoSomething(new MemoryStream());</P>
<P>&nbsp;}<BR></P></CODE>
<P>Will print out 'Stream', not 'MemoryStream'.&nbsp;Method resolution for dynamic objects has&nbsp;to use the runtime type of the object, so simply by changing DoSomething() to take a dynamic instead of a Stream&nbsp;we get a program that prints out 'MemoryStream'. Basically, dynamic lets us implement<A href="https://en.wikipedia.org/wiki/Multimethods" mce_href="https://en.wikipedia.org/wiki/Multimethods"> multi-methods</A> in C#! (Which I really do find very exciting).</P>
<P>A&nbsp;good use of this feature is&nbsp;when implementing the Visitor pattern.&nbsp;C# code that visits all the nodes in a Linq expression tree tends to be quite ugly, with&nbsp;a huge&nbsp;switch statement and a lot of casts to traverse the tree. By casting the Expression class to dynamic we can call a Visit() method which depends on the exact subclass of Expression. The code below prints an expression tree without needing any explicit conditional or loop statements (using dynamic makes the runtime do all the boring lookup work for us).&nbsp;It is also quite a bit shorter than the C# 3.0 equivalent. Note that if there isn't an implementation for a specific expression type then the Visit method for the parent class will be called.</P><CODE>
<P mce_keep="true">using System;<BR>using System.CodeDom.Compiler;<BR>using System.IO;<BR>using System.Linq.Expressions;</P>
<P mce_keep="true">namespace MultiMethods<BR>{<BR>&nbsp;&nbsp;&nbsp; class ExpressionPrinter<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private readonly IndentedTextWriter output;</P>
<P mce_keep="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public ExpressionPrinter(TextWriter output)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.output = new IndentedTextWriter(output);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P mce_keep="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void Print(Expression exp)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <STRONG>dynamic</STRONG> d = exp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.Visit(d);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P mce_keep="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void Visit(Expression exp)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; output.WriteLine("Expression");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P mce_keep="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void Visit(BinaryExpression exp)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; output.WriteLine("BinaryExpression: {0}", exp.NodeType);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.VisitSubExpression(exp.Left);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.VisitSubExpression(exp.Right);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P mce_keep="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void Visit(ConditionalExpression exp)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; output.WriteLine("ConditionalExpression");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.VisitSubExpression(exp.Test);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.VisitSubExpression(exp.IfTrue);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.VisitSubExpression(exp.IfFalse);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P mce_keep="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void Visit(ConstantExpression exp)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; output.WriteLine("ConstantExpression: {0}", exp.Value);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P mce_keep="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void Visit(MethodCallExpression exp)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; output.WriteLine("MethodCall: {0}", exp.Method.Name);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P mce_keep="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void Visit(ParameterExpression exp)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; output.WriteLine("ParameterExpression: {0}", exp.Name);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P mce_keep="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void Visit(UnaryExpression exp)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; output.WriteLine("UnaryExpression: {0}", exp.NodeType);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.VisitSubExpression(exp.Operand);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P mce_keep="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void VisitSubExpression(Expression exp)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; output.Indent++;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <STRONG>dynamic</STRONG> d = exp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.Visit(d);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; output.Indent--;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }</P>
<P mce_keep="true">&nbsp;&nbsp;&nbsp; class Program<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static void Main(string[] args)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var p = new ExpressionPrinter(Console.Out);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Expression&lt;Func&lt;int, int&gt;&gt; e = i =&gt; (0 == i%2) ? -i * i : Math.Abs(i);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p.Print(e.Body);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }<BR>}</P></CODE>
<P mce_keep="true">The output is:</P><CODE>
<P mce_keep="true">ConditionalExpression<BR>&nbsp;&nbsp;&nbsp; BinaryExpression: Equal<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ConstantExpression: 0<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BinaryExpression: Modulo<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ParameterExpression: i<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ConstantExpression: 2<BR>&nbsp;&nbsp;&nbsp; BinaryExpression: Multiply<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UnaryExpression: Negate<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ParameterExpression: i<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ParameterExpression: i<BR>&nbsp;&nbsp;&nbsp; MethodCall: Abs</P></CODE>]]></content:encoded>
    </item>
    <item>
      <title>Kobe - the Web 2.0 application that wasn't</title>
      <link>https://docs.microsoft.com/archive/blogs/laurionb/kobe-the-web-2-0-application-that-wasnt</link>
      <pubDate>Fri, 17 Apr 2009 15:22:00 GMT</pubDate>
      <dc:creator><![CDATA[Laurion Burchall]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/laurionb/2009/04/17/kobe-the-web-2-0-application-that-wasnt/</guid>
      <description><![CDATA[Microsoft has released&nbsp;Kobe, "a getting started resource kit for planning, architecting, and...]]></description>
      <content:encoded><![CDATA[<P>Microsoft has released&nbsp;<A href="https://msdn.microsoft.com/en-us/architecture/bb194897.aspx" mce_href="https://msdn.microsoft.com/en-us/architecture/bb194897.aspx">Kobe</A>, "a getting started resource kit for planning, architecting, and implementing Web 2.0 applications and services using the Microsoft Platform" and a lot of the response has been quite critical (<A href="https://ayende.com/Blog/archive/2009/04/17/kobe-ndash-in-the-nuts-amp-bolts-and-donrsquot-really.aspx" mce_href="https://ayende.com/Blog/archive/2009/04/17/kobe-ndash-in-the-nuts-amp-bolts-and-donrsquot-really.aspx">Ayende</A>, <A href="https://codebetter.com/blogs/karlseguin/archive/2009/04/16/kobe-oh-dead-lord-why.aspx" mce_href="https://codebetter.com/blogs/karlseguin/archive/2009/04/16/kobe-oh-dead-lord-why.aspx">Karl Seguin</A>). While the code, architecture and lack of tests have all been thoroughly criticized I think there is an even higher-level point&nbsp;that has been&nbsp;missed -- Kobe, a Web 2.0 sample, was released and managed in a very Web 1.0 way.</P>
<P>Although&nbsp;the Kobe Project Overview video talks about a Web 2.0 application as having an online community and&nbsp;fostering "active and social user engagement" Kobe itself is available though an inactive, non-social MSDN page with no hint of community. The response on the other hand was far more Web 2.0, with people discussing the project through blogs and&nbsp;on Twitter. At this&nbsp;point the web page is updated to&nbsp;say "<SPAN style="COLOR: #ff0000"><STRONG>This sample application is being updated to incorporate community feedback. An updated version will be released shortly.</STRONG><FONT color=#000000>", but that level of interaction&nbsp;is too little, too late.</FONT></SPAN></P>
<P>I think the biggest mistake here is not releasing a bad Web 2.0 sample, but being unprepared to engage with the online community discussing your bad&nbsp;Web 2.0 sample. Authentic participation on twitter, informative blogging and frequent updates would go a long way here.</P>]]></content:encoded>
    </item>
    <item>
      <title>iiobo C++ ESE library</title>
      <link>https://docs.microsoft.com/archive/blogs/laurionb/iiobo-c-ese-library</link>
      <pubDate>Mon, 06 Apr 2009 23:54:00 GMT</pubDate>
      <dc:creator><![CDATA[Laurion Burchall]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/laurionb/2009/04/06/iiobo-c-ese-library/</guid>
      <description><![CDATA[(I saw a link to this from the Wikipedia entry on esent)
A company called iiobo has released a C++...]]></description>
      <content:encoded><![CDATA[<P>(I saw a link to this from the Wikipedia entry on esent)</P>
<P>A company called iiobo has released a C++ toolkit for using esent (I'm guessing they developed it for internal use). I haven't looked at the code, but their website says that they have:</P>
<P><EM>"C++ classes that provide a higher level abstraction of Extensible Storage Engine e.g DbCursor, DbTable, DbSchema etc. These well designed abstractions allow you to seamlessly work with transactions and other database considerations inside object-oriented C++ code."</EM></P>
<P>Their code is released under the BSD license.</P>
<P><A href="https://www.iiobo.com/ExtensibleStorageEngine.aspx" mce_href="https://www.iiobo.com/ExtensibleStorageEngine.aspx">https://www.iiobo.com/ExtensibleStorageEngine.aspx</A></P>]]></content:encoded>
    </item>
    <item>
      <title>Version 1.2 of ManagedEsent available on CodePlex</title>
      <link>https://docs.microsoft.com/archive/blogs/laurionb/version-1-2-of-managedesent-available-on-codeplex</link>
      <pubDate>Mon, 06 Apr 2009 23:07:00 GMT</pubDate>
      <dc:creator><![CDATA[Laurion Burchall]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/laurionb/2009/04/06/version-1-2-of-managedesent-available-on-codeplex/</guid>
      <description><![CDATA[Version 1.2 of the ManagedEsent interop layer for the&nbsp;ESENT&nbsp;database engine&nbsp;is...]]></description>
      <content:encoded><![CDATA[<P>Version 1.2 of the ManagedEsent interop layer for the&nbsp;ESENT&nbsp;database engine&nbsp;is now&nbsp;available on&nbsp;CodePlex.&nbsp;The three most useful additions here are:</P>
<UL>
<LI>JetEscrowUpdate</LI>
<LI>JetIntersectIndexes</LI>
<LI>Helper functions to set/retrieve columns as DateTime</LI></UL>
<P>JetEscrowUpdate works like Interlocked.Add, allowing a column to be updated in an atomic fashion by mutliple sessions without conflicts. There are several restrictions -- the column must have a default value, has to be JET_coltypLong and cannot be indexed.</P>
<P>JetIntersectIndexes takes a set of &nbsp;index ranges and returns the records which are found in all the index ranges. This can be used to select records that meet multiple criteria. The StockSample.cs sample application shows how to use JetIntersectIndexes.</P>
<P><A href="https://managedesent.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=25756" mce_href="https://managedesent.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=25756">The release is up on Codeplex.</A></P>
<P><EM>The source code now contains the source code for Pixie which is a 'work in progress' managed object layer for ESENT. It is nowhere near complete and will be changing a lot over the coming months.</EM></P>
<P mce_keep="true">&nbsp;</P>]]></content:encoded>
    </item>
  </channel>
</rss>