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;
}
/* TODO: use a faster lookup */
static sexp sexp_lookup_fileno(sexp ctx, int fd) {
sexp *data, x, vec = sexp_global(ctx, SEXP_G_FILE_DESCRIPTORS);
sexp_sint_t i, n = sexp_unbox_fixnum(sexp_global(ctx, SEXP_G_NUM_FILE_DESCRIPTORS));
static sexp* sexp_fileno_cell(sexp ctx, sexp vec, int fd) {
sexp *data;
sexp_sint_t i, cell, len;
if (!sexp_vectorp(vec))
return SEXP_FALSE;
return NULL;
len = sexp_vector_length(vec);
data = sexp_vector_data(vec);
for (i = 0; i < n; i++) {
if (sexp_ephemeronp(data[i])) {
x = sexp_ephemeron_key(data[i]);
if (sexp_filenop(x) && sexp_fileno_fd(x) == fd)
return x;
}
}
for (i = 0, cell = (fd * FNV_PRIME) % len; i < len; i++, cell=(cell+1)%len)
if (!sexp_ephemeronp(data[cell])
|| (sexp_filenop(sexp_ephemeron_key(data[cell]))
&& sexp_fileno_fd(sexp_ephemeron_key(data[cell])) == fd))
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;
}
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) {
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));
if (!sexp_vectorp(vec)) {
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)) {
data = sexp_vector_data(vec);
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)
n2 = n * 2;
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);
for (i = n = 0; i < sexp_vector_length(vec); i++)
if (sexp_ephemeronp(data[i]) && !sexp_brokenp(data[i]))
data2[n++] = data[i];
if (sexp_ephemeronp(data[i]) && !sexp_brokenp(data[i])
&& sexp_insert_fileno_ephemeron(ctx, tmp, data[i]))
n++;
vec = tmp;
}
sexp_vector_data(vec)[n] = sexp_make_ephemeron(ctx, fileno, SEXP_FALSE);
sexp_global(ctx, SEXP_G_NUM_FILE_DESCRIPTORS) = sexp_make_fixnum(n + 1);
if (sexp_insert_fileno_ephemeron(ctx, sexp_global(ctx, SEXP_G_FILE_DESCRIPTORS), sexp_make_ephemeron(ctx, fileno, SEXP_FALSE)))
n++;
sexp_global(ctx, SEXP_G_NUM_FILE_DESCRIPTORS) = sexp_make_fixnum(n);
}
#endif