Stop-gap implementation of coarse-to-fine connection topology.

Unfinished.
This commit is contained in:
Bård Skaflestad
2010-08-27 12:35:13 +00:00
parent 0c6a564cbb
commit 1489e72bc4
2 changed files with 198 additions and 36 deletions

View File

@@ -8,14 +8,25 @@
#define GOLDEN_RAT (0.6180339887498949) /* (sqrt(5) - 1) / 2 */
#define IS_POW2(x) (((x) & ((x) - 1)) == 0)
struct hash_table {
size_t m;
int *a;
struct hash_set {
size_t m; /* Table/set capacity (1<<p for some p) */
int *s; /* Set representation */
};
struct block_neighbour {
int b; /* Neighbouring block */
struct hash_set *fconns; /* Constituent connections */
};
struct block_neighbours {
int nneigh; /* Number of neighbours. */
int cpty; /* Neighbour capacity. */
struct block_neighbour **neigh; /* Actual neighbours (sorted on neigh[i]->b) */
};
/* ---------------------------------------------------------------------- */
static size_t
hash_table_size(size_t m)
hash_set_size(size_t m)
/* ---------------------------------------------------------------------- */
{
size_t i;
@@ -46,7 +57,7 @@ hash_table_size(size_t m)
/* ---------------------------------------------------------------------- */
static size_t
hash_table_idx(int k, size_t m)
hash_set_idx(int k, size_t m)
/* ---------------------------------------------------------------------- */
{
return floor(m * fmod(k * GOLDEN_RAT, 1.0));
@@ -55,7 +66,7 @@ hash_table_idx(int k, size_t m)
/* ---------------------------------------------------------------------- */
static size_t
hash_table_insert_core(int k, size_t m, int *a)
hash_set_insert_core(int k, size_t m, int *s)
/* ---------------------------------------------------------------------- */
{
size_t h1, h2, i, j;
@@ -63,22 +74,22 @@ hash_table_insert_core(int k, size_t m, int *a)
assert ((0 < m) && (m < (size_t)(-1)));
assert (IS_POW2(m));
j = h1 = hash_table_idx(k, m);
j = h1 = hash_set_idx(k, m);
assert (h1 < m);
if (a[j] == -1) { a[j] = k; }
if (a[j] == k) { return j; }
if (s[j] == -1) { s[j] = k; }
if (s[j] == k) { return j; }
/* Double hash probing. h2 relatively prime to 'm' */
h2 = 2 * hash_table_idx(k, (m << 1) - 1) - 1;
h2 = 2 * hash_set_idx(k, (m << 1) - 1) - 1;
for (i = 1; (a[j] != -1) && (a[j] != k) && (i < m); i++) {
for (i = 1; (s[j] != -1) && (s[j] != k) && (i < m); i++) {
j += h2;
j &= m - 1; /* Modulo m since IS_POW2(m). */
}
if (i < m) {
a[j] = k; /* Possibly no-op. */
s[j] = k; /* Possibly no-op. */
} else {
j = m + 1; /* Invalid. Caveat emptor. */
}
@@ -89,25 +100,25 @@ hash_table_insert_core(int k, size_t m, int *a)
/* ---------------------------------------------------------------------- */
static int
hash_table_expand(size_t m, struct hash_table *t)
hash_set_expand(size_t m, struct hash_set *t)
/* ---------------------------------------------------------------------- */
{
int ret, *a, *p;
int ret, *s, *p;
size_t i;
assert (m > t->m);
a = malloc(m * sizeof *a);
if (a != NULL) {
memset(a, -1, m * sizeof *a);
s = malloc(m * sizeof *s);
if (s != NULL) {
memset(s, -1, m * sizeof *s);
for (i = 0; i < t->m; i++) {
ret = hash_table_insert_core(t->a[i], m, a);
assert (ret == t->a[i]);
ret = hash_set_insert_core(t->s[i], m, s);
assert (ret == t->s[i]);
}
p = t->a;
t->a = a;
p = t->s;
t->s = s;
t->m = m;
free(p);
@@ -123,11 +134,11 @@ hash_table_expand(size_t m, struct hash_table *t)
/* ---------------------------------------------------------------------- */
static void
hash_table_deallocate(struct hash_table *t)
hash_set_deallocate(struct hash_set *t)
/* ---------------------------------------------------------------------- */
{
if (t != NULL) {
free(t->a);
free(t->s);
}
free(t);
@@ -135,24 +146,24 @@ hash_table_deallocate(struct hash_table *t)
/* ---------------------------------------------------------------------- */
static struct hash_table *
hash_table_allocate(int m)
static struct hash_set *
hash_set_allocate(int m)
/* ---------------------------------------------------------------------- */
{
size_t sz;
struct hash_table *new;
size_t sz;
struct hash_set *new;
new = malloc(1 * sizeof *new);
if (new != NULL) {
sz = hash_table_size(m);
new->a = malloc(sz * sizeof *new->a);
sz = hash_set_size(m);
new->s = malloc(sz * sizeof *new->s);
if (new->a == NULL) {
hash_table_deallocate(new);
if (new->s == NULL) {
hash_set_deallocate(new);
new = NULL;
} else {
memset(new->a, -1, sz * sizeof *new->a);
memset(new->s, -1, sz * sizeof *new->s);
new->m = sz;
}
}
@@ -163,7 +174,7 @@ hash_table_allocate(int m)
/* ---------------------------------------------------------------------- */
static int
hash_table_insert(int k, struct hash_table *t)
hash_set_insert(int k, struct hash_set *t)
/* ---------------------------------------------------------------------- */
{
int ret;
@@ -173,14 +184,14 @@ hash_table_insert(int k, struct hash_table *t)
assert (t != NULL);
assert (IS_POW2(t->m));
i = hash_table_insert_core(k, t->m, t->a);
i = hash_set_insert_core(k, t->m, t->s);
if (i == t->m + 1) {
/* Table full. Preferable an infrequent occurrence. Expand
* table and re-insert key (if possible). */
ret = hash_table_expand(t->m << 1, t);
ret = hash_set_expand(t->m << 1, t);
if (ret > 0) {
i = hash_table_insert_core(k, t->m, t->a);
i = hash_set_insert_core(k, t->m, t->s);
assert (i < t->m);
ret = k;
@@ -191,3 +202,151 @@ hash_table_insert(int k, struct hash_table *t)
return ret;
}
/* ---------------------------------------------------------------------- */
static void
block_neighbour_deallocate(struct block_neighbour *bn)
/* ---------------------------------------------------------------------- */
{
if (bn != NULL) {
hash_set_deallocate(bn->fconns);
}
free(bn);
}
/* ---------------------------------------------------------------------- */
static struct block_neighbour *
block_neighbour_allocate(int nconn)
/* ---------------------------------------------------------------------- */
{
struct block_neighbour *new;
new = malloc(1 * sizeof *new);
if (new != NULL) {
if (nconn > 0) {
new->fconns = hash_set_allocate(nconn);
if (new->fconns != NULL) {
new->b = -1;
} else {
block_neighbour_deallocate(new);
new = NULL;
}
} else {
new->b = -1;
new->fconns = NULL;
}
}
return new;
}
/* ---------------------------------------------------------------------- */
static int
block_neighbour_insert_fconn(int fconn, struct block_neighbour *bn)
/* ---------------------------------------------------------------------- */
{
int ret;
assert (bn != NULL);
ret = 0;
if (bn->fconns != NULL) {
ret = hash_set_insert(fconn, bn->fconns);
}
return ret;
}
/* ---------------------------------------------------------------------- */
static void
block_neighbours_deallocate(struct block_neighbours *bns)
/* ---------------------------------------------------------------------- */
{
int i;
if (bns != NULL) {
if (bns->neigh != NULL) {
for (i = bns->nneigh - 1; i >= 0; i--) {
block_neighbour_deallocate(bns->neigh[i]);
}
}
free(bns->neigh);
}
free(bns);
}
/* ---------------------------------------------------------------------- */
static struct block_neighbours *
block_neighbours_allocate(int nneigh)
/* ---------------------------------------------------------------------- */
{
struct block_neighbours *new;
new = malloc(1 * sizeof *new);
if (new != NULL) {
if (nneigh > 0) {
new->neigh = malloc(nneigh * sizeof *new->neigh);
if (new->neigh != NULL) {
new->nneigh = 0;
new->cpty = nneigh;
} else {
block_neighbours_deallocate(new);
new = NULL;
}
} else {
new->nneigh = 0;
new->cpty = 0;
new->neigh = NULL;
}
}
return new;
}
/* ---------------------------------------------------------------------- */
static int
block_neighbours_expand(int nneigh, struct block_neighbours *bns)
/* ---------------------------------------------------------------------- */
{
int ret;
struct block_neighbour **neigh;
assert (bns != NULL);
neigh = realloc(bns->neigh, nneigh * sizeof *neigh);
if (neigh != NULL) {
bns->neigh = neigh;
bns->cpty = nneigh;
ret = nneigh;
} else {
ret = -1;
}
return ret;
}
/* ---------------------------------------------------------------------- */
static int
block_neighbours_insert_neighbour(int b, int fconn,
struct block_neighbours *bns)
/* ---------------------------------------------------------------------- */
{
assert (bns != NULL);
}

3
coarse_conn.h Normal file
View File

@@ -0,0 +1,3 @@
#ifndef COARSE_CONN_H_INCLUDED
#define COARSE_CONN_H_INCLUDED
#endif /* COARSE_CONN_H_INCLUDED */