通过字节数组键快速获取值(类似“Dictionary <byte [16],int>”)?</byte [16],int>

时间:2014-02-10 07:53:52

标签: c# dictionary bytearray hashtable binary-search-tree

在我的程序中,我有非常大的(很多很多的terrabytes)数据流作为输入,我需要从中获取密钥 - 字节数组(exacly 16字节 - 一些伪GUID),并且通过该密钥我需要获取一些其他键 - 整数,并通过第二个键我需要在内存中进行一些计算。但我不知道如何快速获得这个“第二把钥匙”..

在开始使用这个“非常大的数据流”之前,我可以得到所有“byte [16] - &gt; int”关联。 字典似乎相当快,但它不能正确使用byte [16]作为键 - 它只是检查对象引用相等(在我的sitiuation它将始终相等,因为它只是缓冲区对象),但我需要使用实际的字节数组值作为键,并快速执行此操作(每秒计数)...如何执行此操作?

嗯......我已经尝试基于二进制搜索来实现自己的关联数组类了。或者有没有任何标准的替代词,可以使用大于4字节的int作为键吗?

2 个答案:

答案 0 :(得分:3)

使用通用Dictionaryyou can supply your own IEqualityComparer comparer。您可以使用此类来比较键。

这将帮助您入门,可以优化性能:

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());

答案 1 :(得分:0)

或者,您可以编写一些代码来表示您的类型,如下所示。

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();
    }
}
相关问题