mirror of
https://github.com/ashinn/chibi-scheme.git
synced 2025-05-19 13:49:17 +02:00
Using a hash for the fileno table.
This commit is contained in:
parent
676b39d82a
commit
152e66fbd6
1 changed files with 32 additions and 18 deletions
50
sexp.c
50
sexp.c
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue