Skip to content

Commit

Permalink
feat(range): improve hashing function
Browse files Browse the repository at this point in the history
  • Loading branch information
amaanq committed May 11, 2024
1 parent a3ce31b commit ce904b9
Showing 1 changed file with 9 additions and 34 deletions.
43 changes: 9 additions & 34 deletions tree_sitter/binding/range.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "range.h"

#define HASH_COMBINE_CONSTANT (sizeof(Py_hash_t) >= 8 ? 0x517cc1b727220a95 : 0x9e3779b9)

int range_init(Range *self, PyObject *args, PyObject *kwargs) {
uint32_t start_row, start_col, end_row, end_col, start_byte, end_byte;
char *keywords[] = {
Expand Down Expand Up @@ -32,42 +34,15 @@ PyObject *range_repr(Range *self) {
}

Py_hash_t range_hash(Range *self) {
// FIXME: replace with an efficient integer hashing algorithm
PyObject *row_tuple = PyTuple_Pack(2, PyLong_FromSize_t(self->range.start_point.row),
PyLong_FromLong(self->range.end_point.row));
if (!row_tuple) {
return NULL;
}

PyObject *col_tuple = PyTuple_Pack(2, PyLong_FromSize_t(self->range.start_point.column),
PyLong_FromSize_t(self->range.end_point.column));
if (!col_tuple) {
Py_DECREF(row_tuple);
return NULL;
}

PyObject *bytes_tuple = PyTuple_Pack(2, PyLong_FromSize_t(self->range.start_byte),
PyLong_FromSize_t(self->range.end_byte));
if (!bytes_tuple) {
Py_DECREF(row_tuple);
Py_DECREF(col_tuple);
return NULL;
}

PyObject *range_tuple = PyTuple_Pack(3, row_tuple, col_tuple, bytes_tuple);
if (!range_tuple) {
Py_DECREF(row_tuple);
Py_DECREF(col_tuple);
Py_DECREF(bytes_tuple);
return NULL;
}
Py_hash_t hash = 6581;

Py_hash_t hash = PyObject_Hash(range_tuple);
hash ^= self->range.start_point.row + HASH_COMBINE_CONSTANT + (hash << 6) + (hash >> 2);
hash ^= self->range.start_point.column + HASH_COMBINE_CONSTANT + (hash << 6) + (hash >> 2);
hash ^= self->range.start_byte + HASH_COMBINE_CONSTANT + (hash << 6) + (hash >> 2);
hash ^= self->range.end_point.row + HASH_COMBINE_CONSTANT + (hash << 6) + (hash >> 2);
hash ^= self->range.end_point.column + HASH_COMBINE_CONSTANT + (hash << 6) + (hash >> 2);
hash ^= self->range.end_byte + HASH_COMBINE_CONSTANT + (hash << 6) + (hash >> 2);

Py_DECREF(range_tuple);
Py_DECREF(row_tuple);
Py_DECREF(col_tuple);
Py_DECREF(bytes_tuple);
return hash;
}

Expand Down

0 comments on commit ce904b9

Please sign in to comment.