Archive for FluentCassandra

14 May 2012

BigDecimal type in .NET

No Comments FluentCassandra

Similar to the situation I previously posted about in my last blog entry on ZLIB Compression in .NET. I needed to support a byte array coming from Java’s BigDecimal type.

To understand why I can’t just use the decimal type in .NET you have to understand that BigDecimal is designed to scale way beyond typical numbers that anybody would realistically use in their day to day programming. And supporting one of these types as a standard type, would eat up much more memory than a typical programmer would want to use for a single number.

Java’s BigDecimal can scale from a number that is as small as 1 byte to as many as 64 bytes. When Java’s BigDecimal generates a byte array it can range from 5 bytes up to 68 bytes depending on the number being represented, with the last 4 bytes being an integer representing the number of decimal places in the number.

Here is what I came up with, which you can also find on GitHub’s Gist.

using System;
using System.Numerics;

/// 
/// A crude implimentation of the essentials needed from Java's BigDecimal
/// 
public struct BigDecimal
{
	private readonly BigInteger _unscaledValue;
	private readonly int _scale;

	public BigDecimal(byte[] value)
	{
		byte[] number = new byte[value.Length - 4];
		byte[] flags = new byte[4];

		Array.Copy(value, 0, number, 0, number.Length);
		Array.Copy(value, value.Length - 4, flags, 0, 4);

		_unscaledValue = new BigInteger(number);
		_scale = flags[0];
	}

	public static explicit operator decimal(BigDecimal value)
	{
		var scaleDivisor = BigInteger.Pow(new BigInteger(10), value._scale);
		var remainder = BigInteger.Remainder(value._unscaledValue, scaleDivisor);
		var scaledValue = BigInteger.Divide(value._unscaledValue, scaleDivisor);

		if (scaledValue > new BigInteger(Decimal.MaxValue))
			throw new ArgumentOutOfRangeException("value", "The value " + value._unscaledValue + " cannot fit into System.Decimal.");

		var leftOfDecimal = (decimal)scaledValue;
		var rightOfDecimal = ((decimal)remainder) / ((decimal)scaleDivisor);

		return leftOfDecimal + rightOfDecimal;
	}
}

To understand why I had to create my own BigDecimal type, you have to understand that the .NET decimal type always generates a byte array of 16 bytes, the first 12 being the integer, and the last 4 being the number of decimal places or the scale. And because .NET always generates 16 bytes it assumes you are always going to read in 16 bytes, which is a bad assumption, but it is what it is. And because of this 16 byte logic it brings me my problem. I was having trouble reading in any number that didn’t produce exactly 16 bytes for the decimal from Java’s BigDecimal. So I decided to create a very crude representation of the BigDecimal type in .NET.

I am putting this code out there, so nobody else has to hunt to find a solution to read in BigDecimal type from Java. Also there is a ton of room for expansion of this type, so if you do modify please let me know so I can update the gist.

12 May 2012

ZLIB Compression in .NET

3 Comments FluentCassandra

I recently encountered a situation where I needed to provide a compressed byte stream to Java’s Inflator class. This probably isn’t a situation that you run into a lot as a .NET developer, but to make a long story short, my FluentCassandra library had to send a compressed byte stream to the database server in order to execute a query.

The part that got me scratching my head is the fact that nothing in .NET Framework mentions ZLIB as a supportable compression type. So I had to start hunting down the specification and found that you can actually generate ZLIB compatible compression with the DeflateStream. However the format that Java and other libraries expect has a header in the stream as well as an adler-32 checksum at the end.

Here is the solution that I came up with that can be seen below and also on GitHub’s Gist.

public static byte[] ZlibCompress(byte[] data)
{
	using (MemoryStream outStream = new MemoryStream())
	{
		// zlib header
		outStream.WriteByte(0x58);
		outStream.WriteByte(0x85);

		// zlib body
		using (var compressor = new DeflateStream(outStream, CompressionMode.Compress, true))
			compressor.Write(data, 0, data.Length);

		// zlib checksum - a naive implementation of adler-32 checksum
		const uint A32Mod = 65521;
		uint s1 = 1, s2 = 0;
		foreach (byte b in data)
		{
			s1 = (s1 + b) % A32Mod;
			s2 = (s2 + s1) % A32Mod;
		}

		int adler32 = unchecked((int)((s2 << 16) + s1));
		outStream.Write(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(adler32)), 0, sizeof(uint));

		// zlib compatible compressed query
		var bytes = outStream.ToArray();
		outStream.Close();

		return bytes;
	}
}

I am putting this code out there, so nobody else has to hunt for hours trying to find a solution that should be built into .NET given the popularity of the ZLIB compression format.

21 Feb 2011

NuGet Fluent Cassandra

No Comments FluentCassandra

Fluent Cassandra is now available via NuGet.

FluentCassandra

If you have never heard of FluentCassandra then go here to learn more:

http://coderjournal.com/2010/06/your-first-fluent-cassandra-application/

If you have never heard of NuGet then go here to learn more:

http://nuget.codeplex.com/wikipage?title=Getting%20Started