using System.Collections.Generic;
using System.Globalization;
using System.Threading.Tasks;
static string EMPTY_CELL = "------------";
public class Partition<T> : List<T>
public Partition(int capacity): base (capacity)
public string minInclusive
public string maxExclusive
public static void Main()
static void withShuffleWrite()
var partitionsNumber = 25;
var partitions = makePartitions(partitionsNumber);
var slugs = new string[] {"rey","foo","por","toc","rot"};
for (var i = 0; i < 20; i++)
var partitionKey = "div200";
var slug = slugs.OrderBy(a => Guid.NewGuid()).First();
partitionKey = partitionKey + slug;
var hashedGuid = hash(partitionKey);
var partition = partitions.FirstOrDefault(p => Convert.ToUInt64(p.minInclusive, 16) <= Convert.ToUInt64(hashedGuid, 16) && Convert.ToUInt64(hashedGuid, 16) < Convert.ToUInt64(p.maxExclusive, 16));
putRecord(partition, partitionKey);
Console.WriteLine("insert failed for key:" + partitionKey + " with error:" + e.Message);
static void noShuffleWrite()
var partitionsNumber = 25;
var partitions = makePartitions(partitionsNumber);
var partitionKey = "div200";
for (var i = 0; i < 20; i++)
var hashedGuid = hash(partitionKey);
var partition = partitions.FirstOrDefault(p => Convert.ToUInt64(p.minInclusive, 16) <= Convert.ToUInt64(hashedGuid, 16) && Convert.ToUInt64(hashedGuid, 16) < Convert.ToUInt64(p.maxExclusive, 16));
putRecord(partition, partitionKey);
Console.WriteLine("insert failed for key:" + partitionKey + " with error:" + e.Message);
static void putRecord(Partition<string> partition, string key)
if (key.Length < EMPTY_CELL.Length)
for(var t = 0 ; key.Length < EMPTY_CELL.Length; t++)
for (var i = 0; i < partition.Count(); i++)
if ((partition[i] as string).Equals(EMPTY_CELL))
throw new ApplicationException("Partition surpassed capacity it will now split");
static void dumpTable(List<Partition<string>> partitions)
var items = new List<string>();
for (var i = 0; i < 10; i++)
var row = new List<string>();
foreach (var partition in partitions)
row.Add(p + " " + partition[i]);
items.Add(string.Join("|", row));
foreach (var item in items)
static List<Partition<string>> makePartitions(int number)
var partitions = new List<Partition<string>>();
var partitionRanges = getPartitionRanges();
for (var i = 0; i < partitionRanges.Count(); i += 2)
var partition = new Partition<string>(10);
partition.minInclusive = partitionRanges[i];
partition.maxExclusive = partitionRanges[i + 1];
for (var j = 0; j < 10; j++)
partition.Add(EMPTY_CELL);
partitions.Add(partition);
static string[] getPartitionRanges()
return "0,05C1A53DB92960,05C1A53DB92960,05C1B53DB92960,05C1B53DB92960,05C1BF5D153D90,05C1BF5D153D90,05C1C53DB92960,05C1C53DB92960,05C1C9CD673378,05C1C9CD673378,05C1CF5D153D90,05C1CF5D153D90,05C1D1F5E1A3D4,05C1D1F5E1A3D4,05C1D53DB92960,05C1D53DB92960,05C1D7858FADEC,05C1D7858FADEC,05C1D9CD673378,05C1D9CD673378,05C1DD153DB904,05C1DD153DB904,05C1DF5D153D90,05C1DF5D153D90,05C1E151F5E18E,05C1E151F5E18E,05C1E1F5E1A3D4,05C1E1F5E1A3D4,05C1E399CD671A,05C1E399CD671A,05C1E53DB92960,05C1E53DB92960,05C1E5E1A3EBA6,05C1E5E1A3EBA6,05C1E7858FADEC,05C1E7858FADEC,05C1E9297B7132,05C1E9297B7132,05C1E9CD673378,05C1E9CD673378,05C1EB7151F5BE,05C1EB7151F5BE,05C1ED153DB904,05C1ED153DB904,05C1EDB9297B4A,05C1EDB9297B4A,05C1EF5D153D90,05C1EF5D153D90,FF".Split(',');
static string hash(string keyValue)
using (MemoryStream stream = new MemoryStream())
using (BinaryWriter writer = new BinaryWriter(stream))
writer.Write(Encoding.UTF8.GetBytes(keyValue));
hash = MurmurHash(stream.GetBuffer(), stream.Length, 0);
return ToHexEncodedBinaryString(hash);
static uint MurmurHash(byte[] bytes, long length, uint seed = 0)
for (int i = 0; i < (length - 3L); i += 4)
uint num5 = BitConverter.ToUInt32(bytes, i) * num;
num5 = RotateLeft(num5, 15) * num2;
n = (RotateLeft(n, 13) * 5) + 0xe6546b64;
if ((num7 <= 3L) && (num7 >= 1L))
switch (((int)(num7 - 1L)))
num6 ^= bytes[(int)((IntPtr)(length - 1L))];
num6 ^= (uint)(bytes[(int)((IntPtr)(length - 1L))] << 8);
num6 ^= bytes[(int)((IntPtr)(length - 2L))];
num6 ^= (uint)(bytes[(int)((IntPtr)(length - 1L))] << 0x10);
num6 ^= (uint)(bytes[(int)((IntPtr)(length - 2L))] << 8);
num6 ^= bytes[(int)((IntPtr)(length - 3L))];
num6 = RotateLeft(num6, 15) * num2;
return (n ^ (n >> 0x10));
static uint RotateLeft(uint n, int numBits) => ((n << numBits) | (n >> (0x20 - numBits)));
static string ToHexEncodedBinaryString(double value)
byte[] buffer = new byte[0x150];
using (MemoryStream stream = new MemoryStream(buffer))
using (BinaryWriter writer = new BinaryWriter(stream))
WriteForBinaryEncoding(writer, value);
str = ToHex(buffer, 0, (int)stream.Position);
static void WriteForBinaryEncoding(BinaryWriter binaryWriter, double value)
binaryWriter.Write((byte)5);
ulong num = EncodeDoubleAsUInt64(value);
binaryWriter.Write((byte)(num >> 0x38));
binaryWriter.Write(num2);
num2 = (byte)((num >> 0x38) | ((ulong)1L));
binaryWriter.Write((byte)(num2 & 0xfe));
static ulong EncodeDoubleAsUInt64(double value)
ulong num = (ulong)BitConverter.DoubleToInt64Bits(value);
ulong num2 = 9223372036854775808L;
return (~num + ((ulong)1L));
static string ToHex(byte[] bytes, int start, int length)
ushort[] lookupArray = new ushort[0x100];
for (int i = 0; i < 0x100; i++)
string str = i.ToString("X2", CultureInfo.InvariantCulture);
lookupArray[i] = (ushort)(str[0] + (str[1] << 8));
char[] chArray = new char[length * 2];
for (int i = 0; i < length; i++)
ushort num2 = lookupArray[bytes[i + start]];
chArray[2 * i] = (char)(num2 & 0xff);
chArray[(2 * i) + 1] = (char)(num2 >> 8);
return new string (chArray);