rktio: repairs

This commit is contained in:
Matthew Flatt 2017-06-16 18:59:34 -06:00
parent d34fcc31db
commit a1cf37eb0f
4 changed files with 47 additions and 15 deletions

View File

@ -33,6 +33,8 @@ void rktio_hash_free(rktio_hash_t *ht, int free_values)
free(ht->buckets); free(ht->buckets);
} }
free(ht);
} }
int rktio_hash_is_empty(rktio_hash_t *ht) int rktio_hash_is_empty(rktio_hash_t *ht)
@ -63,9 +65,9 @@ static void do_rehash(rktio_hash_t *ht, intptr_t new_size)
ht->buckets = calloc(new_size, sizeof(bucket_t)); ht->buckets = calloc(new_size, sizeof(bucket_t));
ht->count = 0; ht->count = 0;
for (i = old_size; --i; ) { for (i = old_size; i--; ) {
if (ht->buckets[i].v) if (old_buckets[i].v)
rktio_hash_set(ht, ht->buckets[i].key, ht->buckets[i].v); rktio_hash_set(ht, old_buckets[i].key, old_buckets[i].v);
} }
free(old_buckets); free(old_buckets);
@ -77,6 +79,7 @@ void *rktio_hash_get(rktio_hash_t *ht, intptr_t key)
if (ht->buckets) { if (ht->buckets) {
intptr_t mask = (ht->size - 1); intptr_t mask = (ht->size - 1);
intptr_t hc = key & mask; intptr_t hc = key & mask;
intptr_t init_hc = hc;
intptr_t d = ((key >> 3) & mask) | 0x1; intptr_t d = ((key >> 3) & mask) | 0x1;
while (1) { while (1) {
@ -86,6 +89,10 @@ void *rktio_hash_get(rktio_hash_t *ht, intptr_t key)
|| (ht->buckets[hc].key == -1)) { || (ht->buckets[hc].key == -1)) {
/* keep looking */ /* keep looking */
hc = (hc + d) & mask; hc = (hc + d) & mask;
if (hc == init_hc) {
/* didn't find in a table that has only full and vacated slots */
return NULL;
}
} else } else
return NULL; return NULL;
} }
@ -98,6 +105,7 @@ void rktio_hash_remove(rktio_hash_t *ht, intptr_t key, int dont_rehash)
if (ht->buckets) { if (ht->buckets) {
intptr_t mask = (ht->size - 1); intptr_t mask = (ht->size - 1);
intptr_t hc = key & mask; intptr_t hc = key & mask;
intptr_t init_hc = hc;
intptr_t d = ((key >> 3) & mask) | 0x1; intptr_t d = ((key >> 3) & mask) | 0x1;
while (1) { while (1) {
@ -109,10 +117,15 @@ void rktio_hash_remove(rktio_hash_t *ht, intptr_t key, int dont_rehash)
if (4 * ht->count <= ht->size) if (4 * ht->count <= ht->size)
do_rehash(ht, ht->size >> 1); do_rehash(ht, ht->size >> 1);
} }
return;
} else if (ht->buckets[hc].v } else if (ht->buckets[hc].v
|| (ht->buckets[hc].key == -1)) { || (ht->buckets[hc].key == -1)) {
/* keep looking */ /* keep looking */
hc = (hc + d) & mask; hc = (hc + d) & mask;
if (hc == init_hc) {
/* didn't find in a table that has only full and vacated slots */
return;
}
} else } else
break; break;
} }
@ -129,23 +142,35 @@ void rktio_hash_set(rktio_hash_t *ht, intptr_t key, void *v)
{ {
intptr_t mask = (ht->size - 1); intptr_t mask = (ht->size - 1);
intptr_t hc = key & mask; intptr_t hc = key & mask;
intptr_t init_hc = hc,use_hc = -1;
intptr_t d = ((key >> 3) & mask) | 0x1; intptr_t d = ((key >> 3) & mask) | 0x1;
while (1) { while (1) {
if (ht->buckets[hc].v) { if (ht->buckets[hc].v) {
if (ht->buckets[hc].key == -1) { if (ht->buckets[hc].key == key) {
/* use bucket whose content ws previously removed */ ht->buckets[hc].v = v;
break; return;
} else { } else {
if (ht->buckets[hc].key == -1) {
/* use bucket whose content was previously removed, but only
if we don't find it later */
if (use_hc < 0) use_hc = hc;
}
/* keep looking for a spot */ /* keep looking for a spot */
hc = (hc + d) & mask; hc = (hc + d) & mask;
if (hc == init_hc) {
/* didn't find in a table that has only full and vacated slots */
break;
}
} }
} else } else {
if (use_hc < 0) use_hc = hc;
break; break;
}
} }
ht->buckets[hc].key = key; ht->buckets[use_hc].key = key;
ht->buckets[hc].v = v; ht->buckets[use_hc].v = v;
ht->count++; ht->count++;
if (2 * ht->count >= ht->size) if (2 * ht->count >= ht->size)

View File

@ -15,6 +15,8 @@
#ifdef HAVE_POLL_SYSCALL #ifdef HAVE_POLL_SYSCALL
# include <unistd.h> # include <unistd.h>
# include <poll.h> # include <poll.h>
#elif defined(RKTIO_SYSTEM_UNIX)
# include <sys/select.h>
#endif #endif
#ifdef HAVE_EPOLL_SYSCALL #ifdef HAVE_EPOLL_SYSCALL
# include <sys/epoll.h> # include <sys/epoll.h>

View File

@ -91,6 +91,7 @@ rktio_poll_set_t *rktio_get_fdset(rktio_poll_set_t *fdarray, int pos)
void rktio_fdzero(rktio_poll_set_t *fd) void rktio_fdzero(rktio_poll_set_t *fd)
{ {
fd->data->count = 0; fd->data->count = 0;
fd->data->skip_sleep = 0;
} }
static int find_fd_pos(struct rktio_fd_set_data_t *data, int n) static int find_fd_pos(struct rktio_fd_set_data_t *data, int n)
@ -192,6 +193,9 @@ void rktio_merge_fd_sets(rktio_poll_set_t *fds, rktio_poll_set_t *src_fds)
rktio_clean_fd_set(fds); rktio_clean_fd_set(fds);
rktio_clean_fd_set(src_fds); rktio_clean_fd_set(src_fds);
if (src_data->skip_sleep)
data->skip_sleep = 1;
c = data->count; c = data->count;
sc = src_data->count; sc = src_data->count;
@ -810,8 +814,9 @@ void rktio_merge_fd_sets(rktio_poll_set_t *fds, rktio_poll_set_t *src_fds)
i = FDSET_LIMIT(sp); i = FDSET_LIMIT(sp);
FDSET_LIMIT(p) = i; FDSET_LIMIT(p) = i;
} }
# endif /* `i` is max fd, so add 1 to get count, then convert to bytes (rounding up) */
# if defined(USE_DYNAMIC_FDSET_SIZE) i = (i + 1 + 7) >> 3;
# elif defined(USE_DYNAMIC_FDSET_SIZE)
i = dynamic_fd_size; i = dynamic_fd_size;
# else # else
i = sizeof(fd_set); i = sizeof(fd_set);