Things that matter most

January 17, 2013

Things that matter most
Must never be at the mercy of things that matter least.

— Johann Wolfgang von Goethe

7BitInts

January 15, 2013

While working on Bastion, I noticed that the BinaryReader and BinaryWriter classes have protected member functions Read7BitEncodedInt and Write7BitEncodedInt respectively and it got me wondering what the heck is a 7BitEncodedInt?

Turns out, it’s a super clever way of variable length encoding an integer.  Google calls them varints and it’s a critical component of ProtocolBuffers.  Finding an implementation back in 2009 was unexpectedly difficult and .NET made them protected members for some reason, so we ended up rolling our own public extension methods.

public static class SystemIOExtensions
{
    public static void Write7BitEncodedInt( this BinaryWriter writer, int value )
    {
        writer.Write7BitEncodedInt( (uint)value );
    }

    public static void Write7BitEncodedInt( this BinaryWriter writer, uint value )
    {
		uint v = value;
		while( v >= 0x80 )
		{
			byte b = (byte)( v | 0x80);
			writer.Write( b );
			v = v >> 7;
		}
		writer.Write( (byte)v );
    }

	public static int Read7BitEncodedInt( this BinaryReader reader )
	{
		int v = 0;
		int shift = 0;

		while( shift < (5 * 7) )
		{
			byte b = reader.ReadByte();
			v |= ((b & 0x7F) << shift);
			shift += 7;
			if( ( b & 0x80 ) == 0 )
				return v;
		}

		throw new FormatException( "Stream corrupted, unable to read 7bit int" );
	}
}

 

Tags

Removing items from a list during iteration

January 10, 2013

Standard practice is to iterate over the list backwards like so:

for( int i = items.Count - 1; i >= 0; --i )
{
    if( shouldRemove( items[i] ) )
        item.RemoveAt( i );
}

This approach doesn’t use any extra memory which is nice, but it’s
O((n/2)2) run time (assuming RemoveAt() is O(n)) is less so.

A clever approach I found from Abe Pralle that is O(n) is to fill the gaps as you remove and iterate and then finally truncate the list at the end. Another way to think about it is bubbling the items that need removal to the end of the list.

int gap = 0;
for( int i = 0; i < items.Count; ++i )
{
    if( !shouldRemove( items[i] ) )
    {
        items[gap] = items[i];
        ++gap;
    }
}

items.RemoveRange( gap, items.Count - gap );

Pretty cool!

Tags

python index function

January 8, 2013

A cool, little Python index function I came across recently.  It’s simple and compact without being obscure; all good things.

def index(seq, f):
    """Return the index of the first item in seq where f(item) == True."""
    return next((i for i,v in enumerate(seq)) if f(v), None)

Tags

You need not see

January 1, 2013

You need not see what someone is doing
to know if it is his vocation,

you have only to watch his eyes:
a cook mixing a sauce, a surgeon

making a primary incision,
a clerk completing a bill of lading,

wear the same rapt expression,
forgetting themselves in a function.

How beautiful it is,
that eye-on-the-object look.

— W.H. Auden