Using a hash for the fileno table.

This commit is contained in:
Alex Shinn 2014-06-01 12:20:18 +09:00
parent 676b39d82a
commit 152e66fbd6

50
sexp.c
View file

@ -1651,29 +1651,41 @@ sexp sexp_make_ephemeron_op(sexp ctx, sexp self, sexp_sint_t n, sexp key, sexp v
return res; return res;
} }
/* TODO: use a faster lookup */ static sexp* sexp_fileno_cell(sexp ctx, sexp vec, int fd) {
static sexp sexp_lookup_fileno(sexp ctx, int fd) { sexp *data;
sexp *data, x, vec = sexp_global(ctx, SEXP_G_FILE_DESCRIPTORS); sexp_sint_t i, cell, len;
sexp_sint_t i, n = sexp_unbox_fixnum(sexp_global(ctx, SEXP_G_NUM_FILE_DESCRIPTORS));
if (!sexp_vectorp(vec)) if (!sexp_vectorp(vec))
return SEXP_FALSE; return NULL;
len = sexp_vector_length(vec);
data = sexp_vector_data(vec); data = sexp_vector_data(vec);
for (i = 0; i < n; i++) { for (i = 0, cell = (fd * FNV_PRIME) % len; i < len; i++, cell=(cell+1)%len)
if (sexp_ephemeronp(data[i])) { if (!sexp_ephemeronp(data[cell])
x = sexp_ephemeron_key(data[i]); || (sexp_filenop(sexp_ephemeron_key(data[cell]))
if (sexp_filenop(x) && sexp_fileno_fd(x) == fd) && sexp_fileno_fd(sexp_ephemeron_key(data[cell])) == fd))
return x; return &(data[cell]);
} return NULL;
} }
static sexp sexp_lookup_fileno(sexp ctx, int fd) {
sexp* cell = sexp_fileno_cell(ctx, sexp_global(ctx, SEXP_G_FILE_DESCRIPTORS), fd);
if (cell && sexp_ephemeronp(*cell)
&& sexp_fileno_fd(sexp_ephemeron_key(*cell)) == fd)
return sexp_ephemeron_key(*cell);
return SEXP_FALSE; return SEXP_FALSE;
} }
static sexp* sexp_insert_fileno_ephemeron(sexp ctx, sexp vec, sexp eph) {
sexp *data = sexp_fileno_cell(ctx, vec, sexp_fileno_fd(sexp_ephemeron_key(eph)));
if (data) *data = eph;
return data;
}
static void sexp_insert_fileno(sexp ctx, sexp fileno) { static void sexp_insert_fileno(sexp ctx, sexp fileno) {
sexp *data, *data2, tmp, vec = sexp_global(ctx, SEXP_G_FILE_DESCRIPTORS); sexp *data, *data2, tmp, vec = sexp_global(ctx, SEXP_G_FILE_DESCRIPTORS);
sexp_sint_t i, n2, n = sexp_unbox_fixnum(sexp_global(ctx, SEXP_G_NUM_FILE_DESCRIPTORS)); sexp_sint_t i, n2, n = sexp_unbox_fixnum(sexp_global(ctx, SEXP_G_NUM_FILE_DESCRIPTORS));
if (!sexp_vectorp(vec)) { if (!sexp_vectorp(vec)) {
vec = sexp_global(ctx, SEXP_G_FILE_DESCRIPTORS) vec = sexp_global(ctx, SEXP_G_FILE_DESCRIPTORS)
= sexp_make_vector(ctx, sexp_make_fixnum(128), SEXP_VOID); = sexp_make_vector(ctx, sexp_make_fixnum(128), SEXP_FALSE);
} else if (n >= sexp_vector_length(vec)) { } else if (n >= sexp_vector_length(vec)) {
data = sexp_vector_data(vec); data = sexp_vector_data(vec);
for (i = n2 = 0; i < sexp_vector_length(vec); i++) for (i = n2 = 0; i < sexp_vector_length(vec); i++)
@ -1682,15 +1694,17 @@ static void sexp_insert_fileno(sexp ctx, sexp fileno) {
if (n2 * 2 >= n) if (n2 * 2 >= n)
n2 = n * 2; n2 = n * 2;
tmp = sexp_global(ctx, SEXP_G_FILE_DESCRIPTORS) tmp = sexp_global(ctx, SEXP_G_FILE_DESCRIPTORS)
= sexp_make_vector(ctx, sexp_make_fixnum(n2), SEXP_VOID); = sexp_make_vector(ctx, sexp_make_fixnum(n2), SEXP_FALSE);
data2 = sexp_vector_data(tmp); data2 = sexp_vector_data(tmp);
for (i = n = 0; i < sexp_vector_length(vec); i++) for (i = n = 0; i < sexp_vector_length(vec); i++)
if (sexp_ephemeronp(data[i]) && !sexp_brokenp(data[i])) if (sexp_ephemeronp(data[i]) && !sexp_brokenp(data[i])
data2[n++] = data[i]; && sexp_insert_fileno_ephemeron(ctx, tmp, data[i]))
n++;
vec = tmp; vec = tmp;
} }
sexp_vector_data(vec)[n] = sexp_make_ephemeron(ctx, fileno, SEXP_FALSE); if (sexp_insert_fileno_ephemeron(ctx, sexp_global(ctx, SEXP_G_FILE_DESCRIPTORS), sexp_make_ephemeron(ctx, fileno, SEXP_FALSE)))
sexp_global(ctx, SEXP_G_NUM_FILE_DESCRIPTORS) = sexp_make_fixnum(n + 1); n++;
sexp_global(ctx, SEXP_G_NUM_FILE_DESCRIPTORS) = sexp_make_fixnum(n);
} }
#endif #endif