2014-11-11 7 views
0

я генерация 64-битное hashcodes из строк и хранение этого значения в базе данных64bit HashCodes, IEqualityComparer и Intersect/За исключением

Можно ли переопределить GetHashCode с 64 битным длинным типом вместо 32 байт междами?

Если это невозможно, возможно ли реализовать Equals и GetHashCode в другом месте и использовать Except и Intersect?

public class RecordComparer : IEqualityComparer<Record> 
{ 
    public bool Equals(Record x, Record y) 
    { 
     if (ReferenceEquals(x, y)) return true; 
     if (x == null || y == null) return false; 
     return x.RecordHash.Equals(y.RecordHash); 
    } 

    public long GetHashCode(Record obj) 
    { 
     return obj.RecordHash; 
    } 
} 
+1

Неверно использовать хэши для равенства из-за хеш-коллизий. – AlexD

+0

Это для 32-битных целых хеш-символов ... столкновение начинается после 100 000 записей. Однако 64-битные хэши гарантируют очень низкую скорость столкновения. – mrb398

+1

«64-битные хешиты гарантируют очень низкую скорость столкновения»: да, они это делают. Но не _equality_. Для чего нужна правильная реализация 'IEqualityComparer ' или 'Equals()'. –

ответ

0

Предполагая, что вы не заботитесь о том, что возможные проблемы, возникающие из разных записей, имеющих равный хеш-коды и, таким образом, рассматривается равными, даже если они различны, вы можете просто реализовать RecordComparer так:

public class RecordComparer : IEqualityComparer<Record> 
{ 
    public bool Equals(Record x, Record y) 
    { 
     if (ReferenceEquals(x, y)) return true; 
     if (x == null || y == null) return false; 
     return x.RecordHash.Equals(y.RecordHash); 
    } 

    public int GetHashCode(Record obj) 
    { 
     return unchecked((int) obj.RecordHash); 
    } 
} 

IEqualityComparer<T> правильно реализован, возвращая 32-битный хэш-код, созданный путем усечения 64-битного хэш-кода, идентифицирующего запись.

Нет необходимости в том, чтобы GetHashCode должен был возвращать уникальные хэш-коды для неравных записей. Однако, избегая столкновений, общие коллекции, такие как Dictionary<Record>, будут работать лучше, а базовый 32-битный хеш-код в 64-битном хеш-коде, вероятно, лучше всего.

Если вы посмотрите на исходный код для Enumerable.Except и Enumerable.Intersect вы можете увидеть, что они используют внутренний класс Set<T>, который является своего рода хэш-таблицы, чтобы ваш реализация GetHashCode может повлиять на производительность вашего кода, но не правильность (как поскольку одинаковые записи возвращают один и тот же хэш-код).

+0

Мне кажется, что 64-битное значение будет преобразовано в 32-битное, прежде чем будет отправлено обратно, что на самом деле не помогло бы в моем случае пересечения двух списков 64-битных ints для различий. Но я никогда не использовал unchecked, поэтому мое мышление может быть неправильным – mrb398

+0

@ user1691808: 'unchecked' - это просто исключить любые исключения, если вы компилируете свой код с включенным' checked' (по умолчанию отключено). Приведение в основном обрезает 64-битное значение до 32 бит, и при выполнении этого вы не хотите «OverflowException». –

1

Ни одна из встроенных коллекций, алгоритмов и интерфейсов не поддерживает 64-битные хэш-коды. Вы должны все строить самостоятельно. Вам нужна целая параллельная инфраструктура.

Это, скорее всего, окажется нецелесообразным. Скорее, используйте 32-битный хэш-код и полагайтесь на свое сравнение равенства, чтобы убедиться, что ложных совпадений не произойдет. В любом случае это необходимо для правильности.

Может быть, этот вопрос основан на недоразумении:

В основном у меня будет 2 списки с 64 битными хэш-кода целых чисел. I должны иметь возможность использовать Except/Intersect в этих 2 списках, чтобы найти различия , основанные на значении 64-битного значения hascode. Поскольку все стоит, IEqualityComparer работает только с 32-битными целыми числами.

Просто рассматривайте этот хэш-код как ключ во встроенных коллекциях и алгоритмах. Вы можете обрабатывать эти списки, используя Except просто отлично.

+0

Возможно, я могу работать над этой идеей, однако мои списки на самом деле представляют собой объект, а одно свойство является хэш-значением, а другое свойство является идентификатором записи. Если я просто сделаю список длинный и пересекаюсь, мне придется также вывести список объектов, чтобы получить правильные идентификаторы записей, связанные с результатами Except/Intersect. – mrb398

+0

В Интернете существуют методы расширения, называемые ExceptBy и IntersectBy. Они делают то, что вам, по-видимому, нужно. Если вы не можете использовать их, используйте этот алгоритм самостоятельно, используя соединения или словари. Ничто из этого не затрагивает проблему хеш-кодов. – usr

 Смежные вопросы

  • Нет связанных вопросов^_^