Oren Eini

CEO of RavenDB

a NoSQL Open Source Document Database

Get in touch with me:

oren@ravendb.net +972 52-548-6969

Posts: 7,582
|
Comments: 51,212
Privacy Policy · Terms
filter by tags archive
time to read 1 min | 160 words

As a software developer, I tend to assume that any excuse that blame the harder is an excuse. But I just got two stories that are completely related to hardware to disprove myself.

A few weeks ago I shoved another 1GB RAM into my computer, and all was well, until I started to get random application failures and a BSOD from Windows. Completely random, completely unexpected. And that is after running seemlessly for over three years without really noticing that th OS existed. Turned out that I needed to play with the positioning of the RAM sticks on my board, and now it seems to be working.

The other thing just happened, I was having bad connectivity issues since just about forever, and today the technician found what the problem was, the connecting wires led to a concret bore, which was full of water... You can imagine what happened next.

Song search

time to read 1 min | 115 words

This post is for the readers from Israel, I just listened to a great song in the radio, but I didn't catch its name, and I can only remember two lines:

את כותבת שורות קצרות,
אני כותב לך מגילות

I heard it on Galgalatz, and I would like the name of the song and the singers.

time to read 3 min | 437 words

During the Tel Aviv Launch I had an argument with Justin about the performance of string comparisons. The issue was whatever it is good to use str == "" or str.Length == 0, and the meriths of string.IsNullOrEmpty(str) in .Net 2.0.

Since Stefano just posted a comparison in VB.Net, I thought I would make the same check on C# (since VB.Net uses a compatability layer for string comparison). I merely ported Stefano's code:

DateTime start = DateTime.Now;
string str = "";
for (int i = 0; i < 1000000000; i++)
{
   if(str == "")
   // if (str.Length == 0)
   // if (str == string.Empty)
   // if (string.IsNullOrEmpty(str))
   {
      ;
   }
}
TimeSpan elapsed = DateTime.Now - start;
Console.WriteLine(elapsed.TotalMilliseconds);

The results?

str == "": 11671.875
str.Length == 0: 3984.375
str == string.Empty: 22265.625
string.IsNullOrEmpty(str): 9703.125

I'm not sure what is the reason for the big different between comparing to "" and comparing the string.Empty. An interesting experiment that I did gave the following result:

object

.ReferenceEquals("", str) is true

object

.ReferenceEquals(string.Empty, str) is false

No idea what this means, though.

From my point of view, if a billion iterations are needed to even see the changes, it doesn't matter which you choose anyway. Just to give you a hint, a call to str=="" will cost you 0.00001 milli-seconds. You'll need to find a physicist to tell you how to call this amount of time, and even then, he will look at you strangely ever after.

More on .Old

time to read 1 min | 80 words

While discussing the afore-mentioned "system" of keeping track of changes with a friend, she mentioned (she used to deal with intrusion detection for web apps) that she broke several system by systematically trying "Page.aspx.old", "Page.aspx.tmp", "Page2.aspx", etc for all the pages in the application. The booty was usually the page source, and in most cases, that came along with the full (unencrypted, naturally) connection string, including the "sa" password.

What was your experiance?

time to read 1 min | 195 words

Imagine the following file listing:

do_stuff.old         do_stuff.tmp                  do_stff.sh1
do_stuff.bak        do_stuff.sh.jhon              so_dtuff.sh
do_stuff.sh.2       do_stuff.sh                    tmp_dostuff.sh
do_stuff2.sh        do_stuff2.new                
do_stuff3.old       do_stuff2.newer
do_stuff2.sql       do_stuffie.sql.old
do_stuff.sql         do_stuff.sql.dont-run

Quick, which file is the correct one? Now multiply that by ten, then add at least three different types of scripts, a truly random directory structure, file names that were written by someone with only half a keyboard and that was taxed per letter, and you may see what I did today. Oh, and just for kicks, spread the responsibilities randomly between shell scripts, sql scripts and stored procedures.

Did I mention a case senstivie file system yet?

time to read 1 min | 143 words

This is a release for a very specific case, you want to mock an internal class from a strongly signed assembly.

Now all you need is to add this declaration to you assembly and you're set:

[assembly: InternalsVisibleTo("DynamicAssemblyProxyGen, PublicKey=002400000480000094000000060200000024000052534131
0004000001000100fb4ff5a7c8bba6feb6a6b75b260cd57c1b8b85b63a45dedcb7081331740c870852af30abd2a74700cce1d7a01ae
ed019339db202e010ac808396b2922362877c6afc8993281092434a223b9920cac8ba409d138a97b73cd1baad813af450b886e3d7f
5a09ee450d415145eb0524778a6bd1ae733fd2b6ceebfd151620534bcb7"
)]

The new release is available here

time to read 5 min | 927 words

I've heard about code that write code, and dynamic programming, Lisp, Linq, Native Queries, and all sort of other stuff. Those are cool, this post is about the other dynamic program. The code is written in a mixture of unix shell scripts and PL/SQL. I'm running the code in my head, reading it in notepad. I'm certain that there are some very good tools to debug shell scripts, and there might be a way to debug PL/SQL, but I'm pretty sure that there isn't something that will let me seamlessly move between one and the other. My current task is to produce a rough documentation of what the code does, so we can decide what to do with it.

I can't really express my horror better than with the following story. The issue here is generating a view in a database. I'm tracing what happens through:

  • The main shell script:
    • Call to a second shell script
      • Run a SQL script
        • Generate a set of SQL commands by string concating with some values from the database
          • Run the generated script
            • The script calls to another shell script with some values
              • The script calls to a SQL script that generate code
                • The code that was generated actually create the view

And, and this is important, this is not the biggest WTF in this codebase. I'm not kidding.

The Yuck Factor

time to read 2 min | 255 words

I internally categorize a project on several factors:

  • Interest
  • Difficulity
  • Amount of new stuff that I learn
  • Yuck Factor

What I find is that while the first three things are very important, the Yuck Factor is usualy the thing that decides how I would remember the project, and how much I enjoy doing it. I'm not sure how I decide what is the Yuckiness of a project, though. It mostly has to do with design and it doesn't bear much in relation to the other factors. In my list of things to watch for are:

  • Hard to understand (#1 mistake).
  • Hard to modify / extend
  • Stupid! Stupid! Stupid!

I was very nearly in tears today when I saw what some people did to the poor machine. Some people really believe in dynamic programming (more on that later). And it means totally incomprehensible code. It doesn't matter that the project is intersting, not too difficult and I'm learning a lot of new stuff. It sucks to deal with it.

time to read 8 min | 1569 words

It probably surprises no one that I'm interested in creating a strongly typed query support for NHibernate. Cecil is going to do most of the hard work, which means that I'm left with the more interesting project of turning an AST into a query. Part of the problem is that the whole thing is exactly opposite to the way you think about it.

Consider this query:

string name = "Ayende"
delegate(Blog b) { return b.BlogName == name; });

This gets messy fast because both the C# compiler and Cecil has a go at obsfucating it. The object graph that I get looks something like this:

  • Assign
    • To: local_var_0
    • From: method_call:
      • Name: string::op_Equaility
      • Arguments:
        • Method call:
          • Blog::get_Name
        • Field reference:
          • some random name that the compiler generate for the anonymous method
  • Branch to:
    • Next instruction - no idea why this is there
  • Return:
    • local variable reference:
      • local_var_0

From this, I need to construct something that will resemble this:

session.CreateCriteria(typeof(Blog)).Add(Expression.Eq("Name""Ayende")).List(); 

I've some ideas as to how to get this, but none of them is very obvious, and all of them rely on the user not doing something very complex. Basically, the idea is to iterate over the method and create a reverse tree, from each return statement, we go backward to find out what is going on there. So, in this case, we will do something like:

  • Return local_var_0
    • Find last assignment to local_var_0
      • Get expression that did the assigment
        • ? This is the hard part, I'm guess here.
        • Determain which op_ was executed here or throw if this is not an operator action.
        • Determain whatever there is chaining via either && or ||, and add them as well.

Basically, two very hard parts (parsing the IL and generating the query) are done, they are working and can be used as is. The hard part is to match the two together.

FUTURE POSTS

  1. fsync()-ing a directory on Linux (and not Windows) - about one day from now

There are posts all the way to Jun 09, 2025

RECENT SERIES

  1. Webinar (7):
    05 Jun 2025 - Think inside the database
  2. Recording (16):
    29 May 2025 - RavenDB's Upcoming Optimizations Deep Dive
  3. RavenDB News (2):
    02 May 2025 - May 2025
  4. Production Postmortem (52):
    07 Apr 2025 - The race condition in the interlock
  5. RavenDB (13):
    02 Apr 2025 - .NET Aspire integration
View all series

Syndication

Main feed Feed Stats
Comments feed   Comments Feed Stats
}