Question

In my programm i have very big(many-many terrabytes) stream of data as input, from which i need to get key - byte array(exacly 16 bytes - some pseudo-GUID), and by that key i need to get some other key - integer, and by that second key i need to do some calculations in memory. But i don't know how to get this "second key" really fast..

I can get all "byte[16] -> int" associations before start to work with this "very big stream of data". Dictionary seems to be pretty fast, but it don't work right with byte[16] as key - it's just check for object reference equality(in my sitiuation it will be always equal, because it's just buffer object), but i need use real byte-array values as key, and do this fast(every second counts)... How to do this?

Well... I'm already trying to implent own associative array class, based on binary search.. Or there any standart alternative to Dictionary, which can use something bigger than 4-byte int as key?

Was it helpful?

Solution

With the generic Dictionary, you can supply your own IEqualityComparer comparer. You can use this class to compare the keys.

This will get you started, performance can probably be optimized:

public class MyComparer : IEqualityComparer<byte[]> {
    public bool Equals(byte[] a, byte[] b) {
        return a.SequenceEqual(b);
    }

    public int GetHashCode(byte[] key) {
        if (key == null)
            throw new ArgumentNullException("key");
        return key.Sum(b => b);
    }
}


// usage:

myDict = new Dictionary(myByteArray, myInt, new MyComparer());

OTHER TIPS

Alternatively, you could write some code to represent your type, as below.

public struct PseudoGuid : IReadOnlyList<byte>, IEquatable<PseudoGuid>
{
    private readonly byte[] value;

    public PseudoGuid(IList<byte> value)
    {
        if (value.Count != 16)
        {
            throw new ArgumentException(...
        }

        this.value = value.ToArray();
    }

    public byte this[int index]
    {
        get
        {
            if (this.value != null)
            {
                return this.value[index]
            }

            return default(byte);
        }
    }

    public bool Equals(PseudoGuid other)
    {
        return this.SequenceEquals(other);
    }

    public override string ToString()
    {
        var result = new StringBuilder(32);
        for (var i = 0; i < 16; i++)
        {
            result.Append(this[i].ToString("X2"));
        }

        return result.ToString();
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj))
        {
            return false;
        }

        return obj is PseudoGuid && this.Equals((PseudoGuid)obj);
    }

    public override int GetHashCode()
    {
        if (this.value == null)
        {
            return 0;
        }

        return BitConvertor.ToInt32(this.value, 0) ^
            BitConvertor.ToInt32(this.value, 4) ^
            BitConvertor.ToInt32(this.value, 8) ^
            BitConvertor.ToInt32(this.value, 12);
    }

    public static bool operator ==(PseudoGuid left, PseudoGuid right)
    {
        return left.Equals(right);
    }

    public static bool operator !=(PseudoGuid left, PseudoGuid right)
    {
        return !left.Equals(right);
    }

    public int Count
    {
        get
        {
            return 16;
        }
    }

    public IEnumerator<byte> GetEnumerator()
    {
        if (this.value != null)
        {
            return ((IList<byte>)this.value).GetEnumerator();
        }

        return Enumerable.Repeat(default(byte), 16).GetEnumerator();
    }

    System.Collections.IEnumerator
             System.Collections.IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top