コード例 #1
0
ファイル: hash_table.c プロジェクト: bjori/grpc
void census_ht_insert(census_ht *ht, census_ht_key key, void *data) {
  gpr_int32 idx = find_bucket_idx(ht, key);
  ht_entry *ptr = NULL;
  entry_locator loc = ht_find(ht, key);
  if (loc.found) {
    /* Replace old value with new value. */
    ptr = loc.is_first_in_chain ? ht->buckets[loc.bucket_idx].next
                                : loc.prev_entry->next;
    if (ht->options.delete_data != NULL) {
      ht->options.delete_data(ptr->data);
    }
    ptr->data = data;
    return;
  }

  /* first entry in the table. */
  if (ht->size == 0) {
    ht->buckets[idx].next_non_empty_bucket = -1;
    ht->buckets[idx].prev_non_empty_bucket = -1;
    ht->first_non_empty_bucket = idx;
    ht->last_non_empty_bucket = idx;
  } else if (ht->buckets[idx].next == NULL) {
    /* first entry in the bucket. */
    ht->buckets[ht->last_non_empty_bucket].next_non_empty_bucket = idx;
    ht->buckets[idx].prev_non_empty_bucket = ht->last_non_empty_bucket;
    ht->buckets[idx].next_non_empty_bucket = -1;
    ht->last_non_empty_bucket = idx;
  }
  ptr = (ht_entry *)gpr_malloc(sizeof(ht_entry));
  ptr->key = key;
  ptr->data = data;
  ptr->next = ht->buckets[idx].next;
  ht->buckets[idx].next = ptr;
  ht->size++;
}
コード例 #2
0
/* Modifies interpolated data.
 *
 * Finds point* pd in the underlying Delaunay triangulation such that
 * pd->x = p->x and pd->y = p->y, and copies p->z to pd->z. Exits with error
 * if the point is not found.
 *
 * @param nnhpi Natural Neighbours hashing point interpolator
 * @param p New data
 */
void nnhpi_modify_data(nnhpi* nnhpi, point* p)
{
    point* orig = ht_find(nnhpi->ht_data, p);

    assert(orig != NULL);
    orig->z = p->z;
}
コード例 #3
0
ファイル: test_hash.c プロジェクト: diegostamigni/hashtable
int main (int argc, char **argv) {
  if (argc != 3) {
    printf("Error on usage: %s <key> <value>\n", argv[0]);
    return EXIT_FAILURE;
  }

  char *key = argv[1];
  char *value = argv[2];

  // testing add function
  ht_add(key, value);
  ht_add("my", "diego");
  ht_add("baby", "looks");
  ht_add("rocks", "great!");
  printf("- Entity added for key %s is %s.\n", key, ht_find(key));

  // printing function
  printf("\nPrinting all entries:\n");
  ht_print();
  
  // testing remove function
  printf("\n- Trying to remove entry for key %s: %s.\n", key, (ht_remove(key) ? "done" : "fail"));

  // printing function
  printf("\nPrinting all entries:\n");
  ht_print();

  return EXIT_SUCCESS;
}
コード例 #4
0
ファイル: hash_table.c プロジェクト: bjori/grpc
void census_ht_erase(census_ht *ht, census_ht_key key) {
  entry_locator loc = ht_find(ht, key);
  if (loc.found == 0) {
    /* noop if not found */
    return;
  }
  ht->size--;
  if (loc.is_first_in_chain) {
    bucket *b = &ht->buckets[loc.bucket_idx];
    GPR_ASSERT(b->next != NULL);
    /* The only entry in the bucket */
    if (b->next->next == NULL) {
      int prev = b->prev_non_empty_bucket;
      int next = b->next_non_empty_bucket;
      if (prev != -1) {
        ht->buckets[prev].next_non_empty_bucket = next;
      } else {
        ht->first_non_empty_bucket = next;
      }
      if (next != -1) {
        ht->buckets[next].prev_non_empty_bucket = prev;
      } else {
        ht->last_non_empty_bucket = prev;
      }
    }
    REMOVE_NEXT(&ht->options, b);
  } else {
    GPR_ASSERT(loc.prev_entry->next != NULL);
    REMOVE_NEXT(&ht->options, loc.prev_entry);
  }
}
コード例 #5
0
ファイル: sexp.c プロジェクト: cansou/minimallisp
int hash_table_exists(SExp h, SExp key) {
	SHash* p;
	HashEntry* e;
	type_check(h, &TSHash);
	p = h.hash;
	e = ht_find(&p->ht, key.p);
	return e != NULL;
}
コード例 #6
0
ファイル: sexp.c プロジェクト: cansou/minimallisp
SExp intern(const char* name) {
	HashEntry* e = ht_find(&s_symbol_table, name);
	if (e != NULL) {
		return ptr2s(e->val);
	} else {
		return exec_intern(name);
	}
}
コード例 #7
0
ファイル: hash_table.c プロジェクト: bjori/grpc
void *census_ht_find(const census_ht *ht, census_ht_key key) {
  entry_locator loc = ht_find(ht, key);
  if (loc.found == 0) {
    return NULL;
  }
  return loc.is_first_in_chain ? ht->buckets[loc.bucket_idx].next->data
                               : loc.prev_entry->next->data;
}
コード例 #8
0
ファイル: state.c プロジェクト: Maijin/radare2
R_API RAnalBlock * r_anal_state_search_bb(RAnalState* state, ut64 addr) {
	/*
	 *   Return 0 if no rehash is needed, otherwise return 1
	 */
	const char *key = sdb_fmt (0, "0x%08"PFMT64x, addr);
	RAnalBlock *tmp_bb = ht_find (state->ht, key, NULL);
	return tmp_bb;
}
コード例 #9
0
ファイル: set.c プロジェクト: manuelmessner/libreset
void*
r_set_contains(
    struct r_set const* set,
    void const* cmp
) {
    set_dbg("Check whether set %p contains element which compares to %p",
            (void*) set,
            (void*) cmp);
    return ht_find(&set->ht, cmp, set->cfg);
}
コード例 #10
0
ファイル: cache.c プロジェクト: mholden/data_structs
block_t *cache_get(cache_t *cache, uint64_t blkno){
    block_t *block = NULL;
    
    pthread_mutex_lock(&cache->ca_lock);
    
    if (!ht_find(cache->ca_ht, &blkno, (void *)block)) // block is in the cache
        goto got_block;
    
    // it's not in the cache, so we need to read it in from disk
    if ((cache->ca_currsz + sizeof(block_t) + cache->ca_blksz) < cache->ca_maxsz) {
        // we're not at max size yet, so allocate some more memory
        block = malloc(sizeof(block_t));
        if (block == NULL) {
            printf("malloc() error\n");
            goto fail;
        }
        
        memset(block, 0, sizeof(block_t));
        pthread_rwlock_init(&block->bl_lock, NULL);
        block->bl_blkno = blkno;
        block->bl_refcnt = 0;
        block->bl_data = malloc(cache->ca_blksz);
        if (block->bl_data == NULL) {
            printf("malloc() error\n");
            goto fail;
        }

	// XXX shouldn't hold ca_lock over the pread.. set a flag on block and use condition variable to synchronize 
        if (pread(cache->ca_fd, block->bl_data, cache->ca_blksz, blkno * cache->ca_blksz) != cache->ca_blksz) {
            printf("pread() error\n");
            goto fail;
        }
    } else { // we're at max size, so we need to evict someone
        printf("cache eviction not yet supported\n");
        goto fail;
    }

got_block:
    if (block->bl_refcnt == 0) // remove it from the free list
        ll_remove(cache->ca_free_list, (void *)&blkno, LL_NO_FREE); // XXX don't do this if you just alloc'd it..
    
    block->bl_refcnt++;
    
    pthread_mutex_unlock(&cache->ca_lock);
    
    return block;

fail:
    printf("something failed and your code doesn't deal with failure yet..\n");
    
    pthread_mutex_unlock(&cache->ca_lock);
    
    return block;
}
コード例 #11
0
ファイル: hash.c プロジェクト: AlexanderC/saffire
/**
  * Saffire method: Returns object stored at "key" inside the hash (or NULL when not found)
  */
SAFFIRE_METHOD(hash, find) {
    t_string_object *key;

    if (! object_parse_arguments(SAFFIRE_METHOD_ARGS, "s", &key)) {
        saffire_warning("Error while parsing argument list\n");
        RETURN_NUMERICAL(0);
    }

    t_object *obj = ht_find(self->ht, key->value);
    if (obj == NULL) RETURN_NULL;
    RETURN_OBJECT(obj);
}
コード例 #12
0
ファイル: sexp.c プロジェクト: cansou/minimallisp
void hash_table_put(SExp h, SExp key, SExp val) {
	SHash* p;
	HashEntry* e;
	type_check(h, &TSHash);
	p = h.hash;
	e = ht_find(&p->ht, key.p);
	if (e != NULL) {
		e->val = S2PTR(val);
	} else {
		ht_add_direct(&p->ht, key.p, val.p);
	}
}
コード例 #13
0
ファイル: sexp.c プロジェクト: cansou/minimallisp
SExp hash_table_get(SExp h, SExp key) {
	SHash* p;
	HashEntry* e;
	type_check(h, &TSHash);
	p = h.hash;
	e = ht_find(&p->ht, key.p);
	if (e != NULL) {
		return ptr2s(e->val);
	} else {
		return sUNDEF;
	}
}
コード例 #14
0
ファイル: parser.c プロジェクト: amdoolittle/APRS_Projects
const struct CmdTemplate* parser_get_cmd_template(const char *input)
{
//	const struct CmdTemplate *cmdp;
//	int cmdlen;
	const char *begin = input, *end = input;

	// Skip the ID, and get the command
	if (!get_word(&begin, &end))
		return NULL;
	if (!get_word(&begin, &end))
		return NULL;

	return (const struct CmdTemplate*)ht_find(&commands, begin, end-begin);
}
コード例 #15
0
ファイル: parser.c プロジェクト: 7h0ma5/kiss-avraprs
/**
 * Find the template for the command contained in the text line.
 * The template can be used to tokenize the command and interpret
 * it.
 *
 * This function can be used to find out which command is contained
 * in a given text line without parsing all the parameters and
 * executing it.
 *
 * \param input Text line to be processed (ASCIIZ)
 *
 * \return The command template associated with the command contained
 * in the line, or NULL if the command is invalid.
 */
const struct CmdTemplate* parser_get_cmd_template(const char *input)
{
	const char *begin = input, *end = input;

#if CONFIG_ENABLE_COMPAT_BEHAVIOUR
	// Skip the ID, and get the command
	if (!get_word(&begin, &end))
		return NULL;
#endif

	if (!get_word(&begin, &end))
		return NULL;

	return (const struct CmdTemplate*)ht_find(&commands, begin, end-begin);
}
コード例 #16
0
void unregister_message_proc(MessageMap* _map, u32 _msg) {
	ht_node_t* pm = 0;
	ls_node_t* p = 0;
	union { Ptr ptr; u32 uint; } u;

	assert(_map);

	if(_msg < MESSAGE_TABLE_SIZE) {
		_map->fast_table[_msg] = 0;
	} else {
		pm = _map->proc_map;
		u.uint = _msg;
		p = ht_find(pm, u.ptr);
		if(p) {
			ht_remove(pm, p->extra);
		}
	}
}
コード例 #17
0
ファイル: ht_move.c プロジェクト: Niichan/snircd
/** \ingroup dbprim_hash
 * \brief Move an entry in the hash table.
 *
 * This function moves an existing entry in the hash table to
 * correspond to the new key.
 *
 * \param table	A pointer to a #hash_table_t.
 * \param entry	A pointer to a #hash_entry_t to be moved.  It must
 *		already be in the hash table.
 * \param key	A pointer to a #db_key_t describing the new key for
 *		the entry.
 *
 * \retval DB_ERR_BADARGS	An invalid argument was given.
 * \retval DB_ERR_UNUSED	Entry is not in a hash table.
 * \retval DB_ERR_WRONGTABLE	Entry is not in this hash table.
 * \retval DB_ERR_FROZEN	Hash table is frozen.
 * \retval DB_ERR_DUPLICATE	New key is a duplicate of an existing
 *				key.
 * \retval DB_ERR_READDFAILED	Unable to re-add entry to table.
 */
unsigned long
ht_move(hash_table_t *table, hash_entry_t *entry, db_key_t *key)
{
  unsigned long retval;

  initialize_dbpr_error_table(); /* initialize error table */

  if (!ht_verify(table) || !he_verify(entry) || !key) /* verify arguments */
    return DB_ERR_BADARGS;

  if (!entry->he_table) /* it's not in a table */
    return DB_ERR_UNUSED;
  if (entry->he_table != table) /* it's in the wrong table */
    return DB_ERR_WRONGTABLE;

  if (table->ht_flags & HASH_FLAG_FREEZE) /* don't mess with frozen tables */
    return DB_ERR_FROZEN;

  if (!ht_find(table, 0, key)) /* don't permit duplicates */
    return DB_ERR_DUPLICATE;

  /* remove the entry from the table */
  if ((retval = ll_remove(&table->ht_table[entry->he_hash], &entry->he_elem)))
    return retval;

  /* rekey the entry */
  entry->he_key = *key; /* thank goodness for structure copy! */

  /* get the new hash value for the entry */
  entry->he_hash =
    (*table->ht_func)(table, &entry->he_key) % table->ht_modulus;

  /* Now re-add it to the table */
  if ((retval = ll_add(&table->ht_table[entry->he_hash], &entry->he_elem,
		       LINK_LOC_HEAD, 0))) {
    table->ht_count--; /* decrement the count--don't worry about shrinking */
    entry->he_table = 0; /* zero the table pointer */
    return DB_ERR_READDFAILED;
  }

  return 0;
}
コード例 #18
0
ファイル: t_ht_addfind.c プロジェクト: jast/ircu-now
int
main(int argc, char **argv)
{
  hash_table_t table[] = { /* some tables to operate on */
    HASH_TABLE_INIT(0, check_func, check_comp, 0, TABLE0),
    HASH_TABLE_INIT(0, check_func, check_comp, 0, TABLE1),
    { DEADINT, DEADINT, DEADINT, DEADINT, DEADINT, DEADINT, DEADPTR,
      (hash_func_t)DEADPTR, (hash_comp_t)DEADPTR, (hash_resize_t)DEADPTR,
      DEADPTR } /* table[2] */
  };
  hash_entry_t entry[] = { /* some entries to operate on */
    HASH_ENTRY_INIT(OBJECT0),
    HASH_ENTRY_INIT(OBJECT1),
    HASH_ENTRY_INIT(OBJECT2),
    HASH_ENTRY_INIT(OBJECT3),
    HASH_ENTRY_INIT(OBJECT4),
    HASH_ENTRY_INIT(OBJECT5),
    { DEADINT, { DEADINT, DEADPTR, DEADPTR, DEADPTR, DEADPTR, DEADINT },
      DEADPTR, DEADINT, { DEADPTR, DEADINT }, DEADPTR } /* entry[6] */
  };
  hash_entry_t *entry_p;
  db_key_t key[] = { /* some keys... */
    DB_KEY_INIT("obj0", 0),
    DB_KEY_INIT("obj1", 1),
    DB_KEY_INIT("obj2", 2),
    DB_KEY_INIT("obj3", 3),
    DB_KEY_INIT("obj4", 4),
    DB_KEY_INIT("obj5", 5),
    DB_KEY_INIT("obj6", 6)
  };

  /* initialize the tables with a size */
  if (ht_init(&table[0], 0, check_func, check_comp, 0, TABLE0, 7) ||
      ht_init(&table[1], 0, check_func, check_comp, 0, TABLE1, 7))
    return -1; /* failed to initialize test */

  /* Check ht_find()'s handling of bad arguments */
  check_result(ht_find(0, 0, 0), DB_ERR_BADARGS, "ht_find_noargs",
	       "ht_find() with no valid arguments", 0);
  check_result(ht_find(&table[2], 0, &key[6]), DB_ERR_BADARGS,
	       "ht_find_badtable", "ht_find() with bad table", 0);
  check_result(ht_find(&table[0], 0, 0), DB_ERR_BADARGS,
	       "ht_find_badkey", "ht_find() with bad key", 0);

  /* Check if empty tables return DB_ERR_NOENTRY */
  check_result(ht_find(&table[0], 0, &key[6]), DB_ERR_NOENTRY,
	       "ht_find_emptytable", "ht_find() with empty table", 1);

  /* Check ht_add()'s handling of bad arguments */
  check_result(ht_add(0, 0, 0), DB_ERR_BADARGS, "ht_add_noargs",
	       "ht_add() with no valid arguments", 0);
  check_result(ht_add(&table[2], &entry[0], &key[0]), DB_ERR_BADARGS,
	       "ht_add_badtable", "ht_add() with bad table", 1);
  check_result(ht_add(&table[0], &entry[6], &key[6]), DB_ERR_BADARGS,
	       "ht_add_badentry", "ht_add() with bad entry", 1);
  check_result(ht_add(&table[0], &entry[0], 0), DB_ERR_BADARGS, "ht_add_nokey",
	       "ht_add() with no key", 1);

  /* Freeze the table temporarily */
  ht_flags(&table[0]) |= HASH_FLAG_FREEZE;
  /* Check adds to frozen tables */
  check_result(ht_add(&table[0], &entry[0], &key[0]), DB_ERR_FROZEN,
	       "ht_add_frozen", "ht_add() on frozen table", 1);
  /* Unfreeze the table */
  ht_flags(&table[0]) &= ~HASH_FLAG_FREEZE;

  /* Add an element to a hash table */
  check_result(ht_add(&table[1], &entry[5], &key[5]), 0, "ht_add_t1e5",
	       "Add entry 5 to table 1", 1);

  /* Now try to add the same element to another hash table */
  check_result(ht_add(&table[0], &entry[5], &key[5]), DB_ERR_BUSY,
	       "ht_add_busy", "Add busy entry 5 to table 0", 1);

  /* Try ht_find() to see if it can find elements */
  check_result(ht_find(&table[1], &entry_p, &key[5]), 0, "ht_find_t1e5",
	       "Look up entry 5 in table 1", 1);
  if (entry_p != &entry[5]) {
    printf("FAIL/ht_find_t1e5_entry:Attempt to look up entry 5 retrieved "
	   "%p (correct answer is %p)\n", (void *)entry_p, (void *)&entry[5]);
    return 0;
  } else
    printf("PASS/ht_find_t1e5_entry:Retrieved correct entry %p\n",
	   (void *)entry_p);

  /* Try looking up an element that isn't there in a populated table */
  check_result(ht_find(&table[1], 0, &key[6]), DB_ERR_NOENTRY,
	       "ht_find_t1e6", "Look up non-existant entry 5 in table 1", 1);

  /* Now we know that ht_find() works properly--finish testing ht_add() */
  check_result(ht_add(&table[1], &entry[0], &key[5]), DB_ERR_DUPLICATE,
	       "ht_add_duplicate", "Attempt to add duplicate entry to table",
	       1);

  /* Now try adding several entries to the table */
  check_result(ht_add(&table[0], &entry[0], &key[0]), 0, "ht_add_t0e0",
	       "Add entry 0 to table 0", 1);
  check_result(ht_add(&table[0], &entry[1], &key[1]), 0, "ht_add_t0e1",
	       "Add entry 1 to table 0", 1);
  check_result(ht_add(&table[0], &entry[2], &key[2]), 0, "ht_add_t0e2",
	       "Add entry 2 to table 0", 1);
  check_result(ht_add(&table[0], &entry[3], &key[3]), 0, "ht_add_t0e3",
	       "Add entry 3 to table 0", 1);
  check_result(ht_add(&table[0], &entry[4], &key[4]), 0, "ht_add_t0e4",
	       "Add entry 4 to table 0", 1);

  /* Check to see if an element can be found */
  check_result(ht_find(&table[0], 0, &key[2]), 0, "ht_find_t0e2",
	       "Find entry 2 in table 0", 1);

  return 0;
}
コード例 #19
0
ファイル: sdbht.c プロジェクト: m1ghtym0/radare2
char* sdb_ht_find(SdbHash* ht, const char* key, bool* found) {
	return (char *)ht_find (ht, key, found);
}
コード例 #20
0
ファイル: states.c プロジェクト: macosunity/rengine
const char *get_style(struct game_state *s, const char *name) {
	char *n = my_strlower(strdup(name));
	char *v = ht_find(s->styles, n);
	free(n);
	return v;
}
コード例 #21
0
/* Finds Natural Neighbours-interpolated value in a point.
 *
 * @param nnhpi NN point hashing interpolator
 * @param p Point to be interpolated (p->x, p->y -- input; p->z -- output)
 */
void nnhpi_interpolate(nnhpi* nnhpi, point* p)
{
    nnpi* nnpi = nnhpi->nnpi;
    delaunay* d = nnpi->d;
    hashtable* ht_weights = nnhpi->ht_weights;
    nn_weights* weights;
    int i;

    if (ht_find(ht_weights, p) != NULL) {
        weights = ht_find(ht_weights, p);
        if (nn_verbose)
            fprintf(stderr, "  <hashtable>\n");
    } else {
        nnpi_calculate_weights(nnpi, p);

        weights = malloc(sizeof(nn_weights));
        weights->vertices = malloc(sizeof(int) * nnpi->nvertices);
        weights->weights = malloc(sizeof(double) * nnpi->nvertices);

        weights->nvertices = nnpi->nvertices;

        for (i = 0; i < nnpi->nvertices; ++i) {
            weights->vertices[i] = nnpi->vertices[i];
            weights->weights[i] = nnpi->weights[i];
        }

        ht_insert(ht_weights, p, weights);

        if (nn_verbose) {
            if (nn_test_vertice == -1) {
                if (nnpi->n == 0)
                    fprintf(stderr, "weights:\n");
                fprintf(stderr, "  %d: {", nnpi->n);

                for (i = 0; i < nnpi->nvertices; ++i) {
                    fprintf(stderr, "(%d,%.5g)", nnpi->vertices[i], nnpi->weights[i]);

                    if (i < nnpi->nvertices - 1)
                        fprintf(stderr, ", ");
                }
                fprintf(stderr, "}\n");
            } else {
                double w = 0.0;

                if (nnpi->n == 0)
                    fprintf(stderr, "weights for vertex %d:\n", nn_test_vertice);
                for (i = 0; i < nnpi->nvertices; ++i) {
                    if (nnpi->vertices[i] == nn_test_vertice) {
                        w = nnpi->weights[i];

                        break;
                    }
                }
                fprintf(stderr, "%15.7g %15.7g %15.7g\n", p->x, p->y, w);
            }
        }

        nnpi->n++;
    }

    nnhpi->n++;

    if (weights->nvertices == 0) {
        p->z = NaN;
        return;
    }

    p->z = 0.0;
    for (i = 0; i < weights->nvertices; ++i) {
        if (weights->weights[i] < nnpi->wmin) {
            p->z = NaN;
            return;
        }
        p->z += d->points[weights->vertices[i]].z * weights->weights[i];
    }
}
コード例 #22
0
ファイル: interpreter.c プロジェクト: flijten/saffire
static t_snode *_interpreter(t_ast_element *p) {
    t_object *obj, *obj1, *obj2, *obj3;
    t_snode *node1, *node2, *node3;
    int initial_loop;
    t_ast_element *hte;
    char *ctx_name, *name;
    wchar_t *wchar_tmp;
    t_dll *dll;
    t_scope *scope;

    // Append to lineno
    dll_append(lineno_stack, (void *)p->lineno);

    // No element found, return NULL object
    if (!p) {
        RETURN_SNODE_OBJECT(Object_Null);
    }


    switch (p->type) {
        case typeAstNull :
            RETURN_SNODE_NULL();
            break;
        case typeAstInterface:
            // @TODO
            RETURN_SNODE_NULL();
            break;
        case typeAstString :
            DEBUG_PRINT("new string object: '%s'\n", p->string.value);

            // Allocate enough room to hold string in wchar and convert
            int len = strlen(p->string.value) * sizeof(wchar_t);
            wchar_tmp = (wchar_t *)smm_malloc(len * sizeof(wchar_t));
            memset(wchar_tmp, 0, len * sizeof(wchar_t));
            mbstowcs(wchar_tmp, p->string.value, strlen(p->string.value));

            // create string object
            obj = object_new(Object_String, wchar_tmp);

            // Free tmp wide string
            smm_free(wchar_tmp);
            RETURN_SNODE_OBJECT(obj);
            break;

        case typeAstNumerical :
            DEBUG_PRINT("new numerical object: %d\n", p->numerical.value);
            // Create numerical object
            obj = object_new(Object_Numerical, p->numerical.value);
            RETURN_SNODE_OBJECT(obj);
            break;

        case typeAstIdentifier :
            // Do constant vars
            if (strcasecmp(p->string.value, "True") == 0) {
                //RETURN_SNODE_OBJECT(Object_True);
                RETURN_SNODE_IDENTIFIER(NULL, Object_True);
            }
            if (strcasecmp(p->string.value, "False") == 0) {
                DEBUG_PRINT("Retuning false!");
                //RETURN_SNODE_OBJECT(Object_False);
                RETURN_SNODE_IDENTIFIER(NULL, Object_False);
            }
            if (strcasecmp(p->string.value, "Null") == 0) {
                //RETURN_SNODE_OBJECT(Object_Null);
                RETURN_SNODE_IDENTIFIER(NULL, Object_Null);
            }

            obj = si_find_var_in_context(p->string.value, NULL);
            RETURN_SNODE_IDENTIFIER(p->string.value, obj);
            break;

        case typeAstClass :
            obj = (t_object *)smm_malloc(sizeof(t_object));
            obj->ref_count = 0;
            obj->type = objectTypeAny;
            obj->name = smm_strdup(p->class.name);
            obj->flags = OBJECT_TYPE_CLASS;
            obj->parent = NULL;
            obj->implement_count = 0;
            obj->implements = NULL;
            obj->methods = ht_create();
            obj->properties = ht_create();
            obj->constants = ht_create();
            obj->operators = NULL;
            obj->comparisons = NULL;
            obj->funcs = &user_funcs;

            // @TODO: Add modifier flags to obj->flags


            // Check extends
            obj->parent = Object_Base;

            // Interpret body.
            t_object *saved_obj = current_obj;
            current_obj = obj;
            _interpreter(p->class.body);
            current_obj = saved_obj;

            // Add the object to the current context
            t_ns_context *ctx = si_get_current_context();
            si_context_add_object(ctx, obj);
            break;

        case typeAstMethod :
            if (current_obj == NULL) {
                saffire_error("Trying to define a method outside a class. This should be caught by the parser!");
            }
            DEBUG_PRINT("Adding method: %s to %s\n", p->method.name, current_obj->name);

            // @TODO: ADD FLAGS AND VISIBILITY
            int vis = 0;
            if (p->method.modifiers & MODIFIER_PUBLIC) vis |= METHOD_VISIBILITY_PUBLIC;
            if (p->method.modifiers & MODIFIER_PROTECTED) vis |= METHOD_VISIBILITY_PROTECTED;
            if (p->method.modifiers & MODIFIER_PRIVATE) vis |= METHOD_VISIBILITY_PRIVATE;

            int flags = 0;
            if (p->method.modifiers & MODIFIER_FINAL) flags |= METHOD_FLAG_FINAL;
            if (p->method.modifiers & MODIFIER_ABSTRACT) flags |= METHOD_FLAG_ABSTRACT;
            if (p->method.modifiers & MODIFIER_STATIC) flags |= METHOD_FLAG_STATIC;

            object_add_external_method(current_obj, p->method.name, flags, vis, p->method.body);
            break;

        case typeAstOpr :
            DEBUG_PRINT("opr.oper: %s(%d)\n", get_token_string(p->opr.oper), p->opr.oper);
            switch (p->opr.oper) {
                case T_PROGRAM :
                    SI0(p); // parse use declarations
                    SI1(p); // parse top statements
                    break;
                case T_TOP_STATEMENTS:
                case T_USE_STATEMENTS:
                case T_STATEMENTS :
                    for (int i=0; i!=OP_CNT(p); i++) {
                        _interpreter(p->opr.ops[i]);
                    }
                    // Statements do not return anything
                    RETURN_SNODE_NULL(); // (well, it should)
                    break;

                case T_IMPORT :
                    // Class to import
                    node1 = SI0(p);
                    obj1 = si_get_object(node1);
                    char *classname = OBJ2STR(obj1);

                    // Fetch alias
                    node2 = SI1(p);
                    if (IS_NULL(node2)) {
                        node2 = node1;  // Alias X as X if needed
                    }
                    obj2 = si_get_object(node2);
                    char *alias = OBJ2STR(obj2);

                    // context to import from
                    node3 = SI2(p);
                    obj3 = si_get_object(node3);
                    ctx_name = OBJ2STR(obj3);


                    // Check if variable is free
                    if (si_find_var_in_context(alias, NULL)) {
                        saffire_error("A variable named %s is already present or imported.", alias);
                    }

                    // Find class in context
                    ctx = si_get_context(ctx_name);
                    if (ctx == NULL) {
                        saffire_error("Cannot find context: %s", ctx_name);
                    }
                    obj = si_find_var_in_context(classname, ctx);
                    if (! obj) {
                        saffire_error("Cannot find class %s inside context: %s", classname, ctx_name);
                    }

                    // Add the object to the current context as the alias variable
                    si_create_var_in_context(alias, NULL, obj, CTX_CREATE_ONLY);

                    DEBUG_PRINT("Imported class %s as %s from %s into %s\n", classname, alias, ctx_name, ctx->name);
                    break;
                case T_USE :
                    // Class to use
                    node1 = SI0(p);
                    obj1 = si_get_object(node1);
                    name = OBJ2STR(obj1);

                    if (OP_CNT(p) > 1) {
                        // Fetch alias
                        node2 = SI1(p);
                        if (IS_NULL(node2)) {
                            node2 = node1;  // Alias X as X
                        }
                    } else {
                        node2 = node1;  // Alias X as X
                    }
                    obj2 = si_get_object(node2);
                    alias = OBJ2STR(obj2);

                    // Check if variable is free
                    ctx = si_find_context(alias);
                    if (ctx != NULL) {
                        saffire_error("A context named %s is already present or imported.", alias);
                    }

                    ctx = si_find_context(name);
                    if (ctx == NULL) {
                        saffire_error("Context %s was not found.", name);
                    }

                    si_create_context_alias(alias, ctx);
                    break;

                case T_RETURN :
                    // Check the current scope.
                    scope = get_current_scope();
                    if (scope->depth == 1) {
                        DEBUG_PRINT("Cannot leave the global scope!");
                    }
                    
                    node1 = SI0(p);
                    obj = si_get_object(node1);
                    RETURN_SNODE_OBJECT(obj);
                    break;

                case T_EXPRESSIONS :
                    // No expression, just return NULL
                    if (OP_CNT(p) == 0) {
                        RETURN_SNODE_NULL();
                    }

                    // Do all expressions
                    for (int i=0; i!=OP_CNT(p); i++) {
                        node1 = _interpreter(p->opr.ops[i]);
                        // Remember the first node
                        if (i == 0) node2 = node1;
                    }
                    return node2;
                    break;

                case T_ASSIGNMENT :
                    // Fetch LHS node
                    node1 = SI0(p);

                    // it should be a variable, otherwise we cannot write to it..

                    // @TODO: THIS IS WRONG. AN ID ALWAYS HAS AN KEY?
                    if (! HAS_IDENTIFIER_ID(node1)) {
                        saffire_error("Left hand side is not writable!");
                    }

                    // Check if we have a normal assignment. We only support this for now...
                    t_ast_element *e = p->opr.ops[1];
                    if (e->type != typeAstOpr || e->opr.oper != T_ASSIGNMENT) {
                        saffire_error("We only support = assignments (no += etc)");
                    }

                    // Evaluate the RHS
                    node3 = SI2(p);

                    // Get the object and store it
                    obj1 = si_get_object(node3);
                    si_set_object(node1, obj1);

                    RETURN_SNODE_OBJECT(obj1);
                    break;

                /**
                 * Control structures
                 */
                case T_DO :
                    do {
                        // Always execute our inner block at least once
                        SI0(p);

                        // Check condition
                        node1 = SI1(p);
                        obj1 = si_get_object(node1);
                        // Check if it's already a boolean. If not, cast this object to boolean
                        if (! OBJECT_IS_BOOLEAN(obj1)) {
                            obj2 = object_find_method(obj1, "boolean");
                            obj1 = object_call(obj1, obj2, 0);
                        }

                        // False, we can break our do-loop
                        if (obj1 == Object_False) {
                            break;
                        }
                    } while (1);

                    RETURN_SNODE_NULL();
                    break;

                case T_WHILE :
                    initial_loop = 1;
                    while (1) {
                        // Check condition first
                        node1 = SI0(p);
                        obj1 = si_get_object(node1);
                        // Check if it's already a boolean. If not, cast this object to boolean
                        if (! OBJECT_IS_BOOLEAN(obj1)) {
                            obj2 = object_find_method(obj1, "boolean");
                            obj1 = object_call(obj1, obj2, 0);
                        }

                        // if condition is true, execute our inner block
                        if (obj1 == Object_True) {
                            SI1(p);
                        } else {
                            // If the first loop is false and we've got an else statement, execute it.
                            if (initial_loop && OP_CNT(p) > 2) {
                                SI2(p);
                            }
                            break;
                        }

                        initial_loop = 0;
                    }

                    RETURN_SNODE_NULL();
                    break;

                case T_FOR :
                    // Evaluate first part
                    node1 = SI0(p);

                    while (1) {
                        // Check condition first
                        node2 = SI1(p);
                        obj1 = si_get_object(node2);
                        // Check if it's already a boolean. If not, cast this object to boolean
                        if (! OBJECT_IS_BOOLEAN(obj1)) {
                            obj2 = object_find_method(obj1, "boolean");
                            obj1 = object_call(obj1, obj2, 0);
                        }

                        // if condition is not true, break our loop
                        if (obj1 != Object_True) {
                            break;
                        }

                        // Condition is true, execute our inner loop
                        SI3(p);

                        // Finally, evaluate our last block
                        SI2(p);
                    }

                    // All done
                    break;

                /**
                 * Conditional statements
                 */
                case T_IF:
                    node1 = SI0(p);
                    obj1 = si_get_object(node1);

                    // Check if it's already a boolean. If not, cast this object to boolean
                    if (! OBJECT_IS_BOOLEAN(obj1)) {
                        obj2 = object_find_method(obj1, "boolean");
                        obj1 = object_call(obj1, obj2, 0);
                    }

                    if (obj1 == Object_True) {
                        // Execute if-block
                        node2 = SI1(p);
                    } else if (OP_CNT(p) > 2) {
                        // Execute (optional) else-block
                        node2 = SI2(p);
                    }
                    break;

                case T_ARGUMENT_LIST:
                    dll = dll_init();
                    for (int i=0; i!=OP_CNT(p); i++) {
                        node1 = _interpreter(p->opr.ops[i]);
                        obj1 = si_get_object(node1);
                        dll_append(dll, obj1);
                    }
                    RETURN_SNODE_DLL(dll);

                case T_METHOD_CALL :
                    // Get object
                    node1 = SI0(p);
                    obj1 = IS_NULL(node1) ? NULL : si_get_object(node1);

                    if (obj1 != NULL) {
                        hte = p->opr.ops[1];
                        obj2 = object_find_method(obj1,  hte->identifier.name);
                        if (! obj2) {
                            saffire_error("Cannot find method or property named '%s' in '%s'", hte->identifier.name, obj1->name);
                        }
                    } else {
                        // Get object
                        node2 = SI1(p);
                        obj2 = si_get_object(node2);
                    }



                    // Get arguments (or NULL)
                    t_dll *dll = NULL;
                    node2 = SI2(p);
                    if (IS_DLL(node2)) {
                        dll = node2->data.dll;
                    } else if (IS_NULL(node2)) {
                        dll = NULL;
                    } else {
                        saffire_error("Expected a DLL (or null)");
                    }

                    // assume nothing found
                    obj3 = Object_Null;

                    if (OBJECT_IS_METHOD(obj2)) {
                        /*
                         * Lots of method checks before we can actually call this
                         */
                        t_method_object *method = (t_method_object *)obj2;
                        if (METHOD_IS_CONSTRUCTOR(method)) {
                            saffire_error("Cannot call constructor");
                        }
                        if (METHOD_IS_DESTRUCTOR(method)) {
                            saffire_error("Cannot call destructor");
                        }
                        if (OBJECT_TYPE_IS_ABSTRACT(obj1)) {
                            saffire_error("Cannot call an abstract class");
                        }
                        if (OBJECT_TYPE_IS_INTERFACE(obj1)) {
                            saffire_error("Cannot call an interface");
                        }

                        if (OBJECT_TYPE_IS_INSTANCE(obj1) && METHOD_IS_STATIC(method)) {
                            saffire_error("Cannot call a static method from an instance. Hint: use %s.%s()", obj1->name, obj2->name);
                        }
                        if (OBJECT_TYPE_IS_CLASS(obj1) && ! METHOD_IS_STATIC(method)) {
                            saffire_error("Cannot call a non-static method directly from a class. Hint: instantiate first");
                        }


                        // Set new scope
                        enter_scope(p);

                        // We need to do a method call
                        DEBUG_PRINT("+++ Calling method %s \n", obj2->name);
                        obj3 = object_call_args(obj1, obj2, dll);

                        leave_scope();

                    } else if (OBJECT_TYPE_IS_CLASS(obj2)) {
                        // We need to instantiate
                        DEBUG_PRINT("+++ Instantiating a new class for %s\n", obj2->name);

                        enter_scope(p);

                        obj3 = object_new(obj2, dll);
                        if (! obj3) {
                            saffire_error("Cannot instantiate class %s", obj2->name);
                        }

                        leave_scope();
                    } else {
                        saffire_error("Cannot call or instantiate %s", obj2->name);
                    }

//                    } else {
//
//                        // get class or method name
//                        hte = p->opr.ops[1];
//                        if (hte->type != typeAstIdentifier) {
//                            saffire_error("Can only have identifiers here", hte->identifier.name);
//                        }
//
//                        method_name = smm_strdup(hte->identifier.name);
//                    }
//
//                    // At this point we need to fetch the objec,
//
//
//
////                    if (hte->type == typeAstNull && (obj->flags & OBJECT_TYPE_CLASS) == OBJECT_TYPE_CLASS) {
//
//                    if (instantiation) {
//                        // Instantiating
//                        DEBUG_PRINT("+++ Instantiating a new class for %s\n", obj1->name);
//
//                        if (! OBJECT_TYPE_IS_CLASS(obj1)) {
//                            saffire_error("Can only instantiate classes");
//                        }
//
//                        obj2 = object_new(obj1, dll);
//                        if (! obj2) {
//                            saffire_error("Cannot instantiate class %s", obj1->name);
//                        }
//
//                    } else {
//
//                        if (hte->type != typeAstIdentifier) {
//                            saffire_error("Can only have identifiers here", hte->identifier.name);
//                        }
//                        method_name = smm_strdup(hte->identifier.name);
//
//                        obj2 = object_call_args(obj1, method_name, dll);
//
//                        smm_free(method_name);
//                    }


                    if (dll) dll_free(dll);

                    RETURN_SNODE_OBJECT(obj3);
                    break;

                /* Comparisons */
                case '<' :
                    return si_comparison(p, COMPARISON_LT);
                    break;
                case '>' :
                    return si_comparison(p, COMPARISON_GT);
                    break;
                case T_GE :
                    return si_comparison(p, COMPARISON_GE);
                    break;
                case T_LE :
                    return si_comparison(p, COMPARISON_LE);
                    break;
                case T_NE :
                    return si_comparison(p, COMPARISON_NE);
                    break;
                case T_EQ :
                    return si_comparison(p, COMPARISON_EQ);
                    break;

                /* Operators */
                case '+' :
                    return si_operator(p, OPERATOR_ADD);
                    break;
                case '-' :
                    return si_operator(p, OPERATOR_SUB);
                    break;
                case '*' :
                    return si_operator(p, OPERATOR_MUL);
                    break;
                case '/' :
                    return si_operator(p, OPERATOR_DIV);
                    break;
                case T_AND :
                    return si_operator(p, OPERATOR_AND);
                    break;
                case T_OR :
                    return si_operator(p, OPERATOR_OR);
                    break;
                case '^' :
                    return si_operator(p, OPERATOR_XOR);
                    break;
                case T_SHIFT_LEFT :
                    return si_operator(p, OPERATOR_SHL);
                    break;
                case T_SHIFT_RIGHT :
                    return si_operator(p, OPERATOR_SHR);
                    break;

                /* Unary operators */
                case T_OP_INC :
                    // We must be a variable
                    node1 = SI0(p);
                    if (! HAS_IDENTIFIER_ID(node1)) {
                        saffire_error("Left hand side is not writable!");
                    }

                    obj1 = si_get_object(node1);
                    obj2 = object_new(Object_Numerical, 1);
                    obj3 = object_operator(obj1, OPERATOR_ADD, 0, 1, obj2);

                    si_set_object(node1, obj3);

                    RETURN_SNODE_OBJECT(obj3);
                    break;
                case T_OP_DEC :
                    // We must be a variable
                    node1 = SI0(p);
                    if (! HAS_IDENTIFIER_ID(node1)) {
                        saffire_error("Left hand side is not writable!");
                    }

                    obj1 = si_get_object(node1);
                    obj2 = object_new(Object_Numerical, 1);
                    obj3 = object_operator(obj1, OPERATOR_SUB, 0, 1, obj2);

                    si_set_object(node1, obj3);

                    RETURN_SNODE_OBJECT(obj3);
                    break;

                case '.' :
                    node1 = SI0(p);
                    obj1 = si_get_object(node1);

                    // get method name from object
                    hte = p->opr.ops[1];
                    if (hte->type != typeAstIdentifier) {
                        saffire_error("Can only have identifiers here", hte->identifier.name);
                    }

                    DEBUG_PRINT("Figuring out: '%s' in object '%s'\n", hte->identifier.name, obj1->name);
                    obj = ht_find(obj1->properties, hte->identifier.name);
                    if (obj == NULL) {
                        obj = ht_find(obj1->constants, hte->identifier.name);
                        if (obj == NULL) {
                            saffire_error("Cannot find constant or property '%s' from '%s'", hte->identifier.name, obj1->name);
                        }
                    }
                    RETURN_SNODE_OBJECT(obj);

                    break;

                case T_CONST :
                    if (current_obj == NULL) {
                        // @TODO: We could create constants OUTSIDE a class!
                        saffire_error("Defining constants outside classes is not yet supported!");
                    }

                    hte = p->opr.ops[0];
                    if (hte->type != typeAstIdentifier) {
                        saffire_error("Constant name needs to be an identifier");
                    }

                    node2 = SI1(p);
                    obj2 = si_get_object(node2);

                    DEBUG_PRINT("Added constant %s to %s\n", hte->identifier.name, current_obj->name);
                    ht_add(current_obj->constants, hte->identifier.name, obj2);
                    break;

                case T_PROPERTY :
                    if (current_obj == NULL) {
                        saffire_error("Cannot define properties outside classes. This should be caught by the parser!");
                    }

                    hte = p->opr.ops[0];
                    if (hte->type != typeAstNumerical) {
                        saffire_error("Flags name needs to be numerical");
                    }

                    hte = p->opr.ops[1];
                    if (hte->type != typeAstIdentifier) {
                        saffire_error("Property name needs to be an identifier");
                    }

                    node2 = SI2(p);
                    obj2 = si_get_object(node2);

                    DEBUG_PRINT("Added property %s to %s\n", hte->identifier.name, current_obj->name);
                    ht_add(current_obj->properties, hte->identifier.name, obj2);
                    break;

                default:
                    saffire_error("Unhandled opcode: %d\n", p->opr.oper);
                    break;
            }
            break;
    }
    RETURN_SNODE_NULL();
}
コード例 #23
0
ファイル: nnpi.c プロジェクト: epicsdeb/sdds
/* This is a central procedure for the Natural Neighbours interpolation. It
 * uses the Watson's algorithm for the required areas calculation and implies
 * that the vertices of the delaunay triangulation are listed in uniform
 * (clockwise or counterclockwise) order.
 */
static void nnpi_triangle_process(nnpi* nn, point* p, int i)
{
    delaunay* d = nn->d;
    triangle* t = &d->triangles[i];
    circle* c = &d->circles[i];
    circle cs[3];
    int j;

    /*
     * There used to be a useful assertion here:
     *
     * assert(circle_contains(c, p));
     *
     * I removed it after introducing flag `contains' to 
     * delaunay_circles_find(). It looks like the code is robust enough to
     * run without this assertion.
     */

    /*
     * Sibson interpolation by using Watson's algorithm 
     */
    for (j = 0; j < 3; ++j) {
        int j1 = (j + 1) % 3;
        int j2 = (j + 2) % 3;
        int v1 = t->vids[j1];
        int v2 = t->vids[j2];

        if (!circle_build2(&cs[j], &d->points[v1], &d->points[v2], p)) {
            point* p1 = &d->points[v1];
            point* p2 = &d->points[v2];

            if ((fabs(p1->x - p->x) + fabs(p1->y - p->y)) / c->r < EPS_SAME) {
                /*
                 * if (p1->x == p->x && p1->y == p->y) {
                 */
                nnpi_add_weight(nn, v1, BIGNUMBER);
                return;
            } else if ((fabs(p2->x - p->x) + fabs(p2->y - p->y)) / c->r < EPS_SAME) {
                /*
                 * } else if (p2->x == p->x && p2->y == p->y) {
                 */
                nnpi_add_weight(nn, v2, BIGNUMBER);
                return;
            }
        }
    }

    for (j = 0; j < 3; ++j) {
        int j1 = (j + 1) % 3;
        int j2 = (j + 2) % 3;
        double det = ((cs[j1].x - c->x) * (cs[j2].y - c->y) - (cs[j2].x - c->x) * (cs[j1].y - c->y));

        if (isnan(det)) {
            /*
             * Here, if the determinant is NaN, then the interpolation point
             * lies almost in between two data points. This case is difficult to
             * handle robustly because the areas (determinants) calculated by
             * Watson's algorithm are obtained as a diference between two big
             * numbers. This case is handled here in the following way.
             *
             * If a circle is recognised as very large in circle_build2(), then
             * its parameters are replaced by NaNs, which results in the
             * variable `det' above being NaN.
             * 
             * When this happens inside convex hall of the data, there is
             * always a triangle on another side of the edge, processing of
             * which also produces an invalid circle. Processing of this edge
             * yields two pairs of infinite determinants, with singularities 
             * of each pair cancelling if the point moves slightly off the edge.
             *
             * Each of the determinants corresponds to the (signed) area of a
             * triangle, and an inifinite determinant corresponds to the area of
             * a triangle with one vertex moved to infinity. "Subtracting" one
             * triangle from another within each pair yields a valid
             * quadrilateral (in fact, a trapezoid). The doubled area of these
             * quadrilaterals is calculated in the cycle over ii below.
             */
            int j1bad = isnan(cs[j1].x);
            int key[2];
            double* v = NULL;

            key[0] = t->vids[j];

            if (nn->bad == NULL)
                nn->bad = ht_create_i2(HT_SIZE);

            key[1] = (j1bad) ? t->vids[j2] : t->vids[j1];
            v = ht_find(nn->bad, &key);

            if (v == NULL) {
                v = malloc(8 * sizeof(double));
                if (j1bad) {
                    v[0] = cs[j2].x;
                    v[1] = cs[j2].y;
                } else {
                    v[0] = cs[j1].x;
                    v[1] = cs[j1].y;
                }
                v[2] = c->x;
                v[3] = c->y;
                (void) ht_insert(nn->bad, &key, v);
                det = 0.0;
            } else {
                int ii;

                if (j1bad) {
                    v[6] = cs[j2].x;
                    v[7] = cs[j2].y;
                } else {
                    v[6] = cs[j1].x;
                    v[7] = cs[j1].y;
                }
                v[4] = c->x;
                v[5] = c->y;

                det = 0;
                for (ii = 0; ii < 4; ++ii) {
                    int ii1 = (ii + 1) % 4;

                    det += (v[ii * 2] + v[ii1 * 2]) * (v[ii * 2 + 1] - v[ii1 * 2 + 1]);
                }
                det = fabs(det);

                free(v);
                ht_delete(nn->bad, &key);
            }
        }

        nnpi_add_weight(nn, t->vids[j], det);
    }
}
コード例 #24
0
/* This is a central procedure for the Natural Neighbours interpolation. It
 * uses the Watson's algorithm for the required areas calculation and implies
 * that the vertices of the delaunay triangulation are listed in uniform
 * (clockwise or counterclockwise) order.
 */
static void nnpi_triangle_process(nnpi* nn, point* p, int i)
{
    delaunay* d = nn->d;
    triangle* t = &d->triangles[i];
    circle* c = &d->circles[i];
    circle cs[3];
    int j;

    /*
     * There used to be a useful assertion here:
     *
     * assert(circle_contains(c, p));
     *
     * I removed it after introducing flag `contains' to 
     * delaunay_circles_find(). It looks like the code is robust enough to
     * run without this assertion.
     */

    /*
     * Sibson interpolation by using Watson's algorithm 
     */
    for (j = 0; j < 3; ++j) {
        int j1 = (j + 1) % 3;
        int j2 = (j + 2) % 3;
        int v1 = t->vids[j1];
        int v2 = t->vids[j2];

        if (!circle_build2(&cs[j], &d->points[v1], &d->points[v2], p)) {
            point* p1 = &d->points[v1];
            point* p2 = &d->points[v2];

	    if ((fabs(p1->x - p->x) + fabs(p1->y - p->y)) / c->r < EPS_SAME) {
		/*
		 * if (p1->x == p->x && p1->y == p->y) {
		 */
                nnpi_add_weight(nn, v1, BIGNUMBER);
                return;
	    } else if ((fabs(p2->x - p->x) + fabs(p2->y - p->y)) / c->r < EPS_SAME) {
		/*
		 * } else if (p2->x == p->x && p2->y == p->y) {
		 */
                nnpi_add_weight(nn, v2, BIGNUMBER);
                return;
            }
        }
    }

    for (j = 0; j < 3; ++j) {
        int j1 = (j + 1) % 3;
        int j2 = (j + 2) % 3;
        double det = ((cs[j1].x - c->x) * (cs[j2].y - c->y) - (cs[j2].x - c->x) * (cs[j1].y - c->y));

        if (isnan(det)) {
            /*
             * If the determinant is NaN, then the interpolation point lies
             * almost in between two data points. This case is difficult to
             * handle robustly because the areas calculated are obtained as a
             * diference between two big numbers.
             *
             * Here this is handles in the following way. If a circle is
             * recognised as very large in circle_build2(), then it parameters 
             * are replaced by NaNs, which results in det above being NaN.
             * The resulting area to be calculated for a vertex does not
             * change if the circle center is moved along some line. The closer
             * it is moved to the actual data point positions, the more
             * numerically robust the calculation of areas becomes. In
             * particular, it can be moved to coincide with one of the other
             * circle centers. When this is done, it is ticked by placing the
             * edge parameters into the hash table, so that when the
             * "cancelling" would be about to be done, this new position is
             * used instead.
             *
             * One complicated circumstance is that sometimes a circle is
             * recognised as very large in cases when it is actually not, 
             * when the interpolated point is close to a data point. This is
             * handled by a special treatment in _nnpi_calculate_weights().
             */
            int remove = 1;
            circle* cc = NULL;
            int key[2];

            key[0] = t->vids[j];

            if (nn->bad == NULL)
                nn->bad = ht_create_i2(HT_SIZE);

            if (isnan(cs[j1].x)) {
                key[1] = t->vids[j2];
                cc = ht_find(nn->bad, &key);

                if (cc == NULL) {
                    remove = 0;
                    cc = malloc(sizeof(circle));
                    cc->x = cs[j2].x;
                    cc->y = cs[j2].y;
                    assert(ht_insert(nn->bad, &key, cc) == NULL);
                }
                det = ((cc->x - c->x) * (cs[j2].y - c->y) - (cs[j2].x - c->x) * (cc->y - c->y));
            } else {            /* j2 */
                key[1] = t->vids[j1];
                cc = ht_find(nn->bad, &key);

                if (cc == NULL) {
                    remove = 0;
                    cc = malloc(sizeof(circle));
                    cc->x = cs[j1].x;
                    cc->y = cs[j1].y;
                    assert(ht_insert(nn->bad, &key, cc) == NULL);
                }
                det = ((cs[j1].x - c->x) * (cc->y - c->y) - (cc->x - c->x) * (cs[j1].y - c->y));
            }
            if (remove)
                assert(ht_delete(nn->bad, &key) != NULL);
        }

        nnpi_add_weight(nn, t->vids[j], det);
    }
}
コード例 #25
0
ファイル: hash.c プロジェクト: johanvdw/saga-debian
int main()
{
    double points[] = {
        922803.7855, 7372394.688, 0,
        922849.2037, 7372307.027, 1,
        922894.657, 7372219.306, 2,
        922940.1475, 7372131.528, 3,
        922985.6777, 7372043.692, 4,
        923031.2501, 7371955.802, 5,
        923076.8669, 7371867.857, 6,
        923122.5307, 7371779.861, 7,
        923168.2439, 7371691.816, 8,
        923214.0091, 7371603.722, 9,
        923259.8288, 7371515.583, 10,
        922891.3958, 7372440.117, 11,
        922936.873, 7372352.489, 12,
        922982.3839, 7372264.804, 13,
        923027.9308, 7372177.064, 14,
        923073.5159, 7372089.268, 15,
        923119.1415, 7372001.42, 16,
        923164.8099, 7371913.521, 17,
        923210.5233, 7371825.572, 18,
        923256.2841, 7371737.575, 19,
        923302.0946, 7371649.534, 20,
        923347.9572, 7371561.45, 21,
        922978.9747, 7372485.605, 22,
        923024.5085, 7372398.009, 23,
        923070.0748, 7372310.358, 24,
        923115.6759, 7372222.654, 25,
        923161.3136, 7372134.897, 26,
        923206.9903, 7372047.09, 27,
        923252.7079, 7371959.233, 28,
        923298.4686, 7371871.33, 29,
        923344.2745, 7371783.381, 30,
        923390.1279, 7371695.389, 31,
        923436.0309, 7371607.357, 32,
        923066.5232, 7372531.148, 33,
        923112.1115, 7372443.583, 34,
        923157.7311, 7372355.966, 35,
        923203.3842, 7372268.296, 36,
        923249.0725, 7372180.577, 37,
        923294.7981, 7372092.808, 38,
        923340.5628, 7372004.993, 39,
        923386.3686, 7371917.132, 40,
        923432.2176, 7371829.229, 41,
        923478.1116, 7371741.284, 42,
        923524.0527, 7371653.302, 43,
        923154.0423, 7372576.746, 44,
        923199.6831, 7372489.211, 45,
        923245.3541, 7372401.625, 46,
        923291.0572, 7372313.989, 47,
        923336.7941, 7372226.305, 48,
        923382.5667, 7372138.574, 49,
        923428.3766, 7372050.798, 50,
        923474.2256, 7371962.978, 51,
        923520.1155, 7371875.118, 52,
        923566.0481, 7371787.218, 53,
        923612.0252, 7371699.282, 54,
        923241.533, 7372622.396, 55,
        923287.2244, 7372534.889, 56,
        923332.9449, 7372447.334, 57,
        923378.6963, 7372359.731, 58,
        923424.4801, 7372272.081, 59,
        923470.2979, 7372184.385, 60,
        923516.1513, 7372096.646, 61,
        923562.0418, 7372008.866, 62,
        923607.9709, 7371921.046, 63,
        923653.9402, 7371833.188, 64,
        923699.9514, 7371745.296, 65,
        923328.9962, 7372668.095, 66,
        923374.7365, 7372580.617, 67,
        923420.5049, 7372493.091, 68,
        923466.303, 7372405.519, 69,
        923512.1321, 7372317.901, 70,
        923557.9936, 7372230.24, 71,
        923603.8889, 7372142.536, 72,
        923649.8192, 7372054.793, 73,
        923695.786, 7371967.011, 74,
        923741.7905, 7371879.193, 75,
        923787.8341, 7371791.342, 76,
        923416.4327, 7372713.844, 77,
        923462.2204, 7372626.393, 78,
        923508.0353, 7372538.895, 79,
        923553.8787, 7372451.353, 80,
        923599.7517, 7372363.766, 81,
        923645.6555, 7372276.137, 82,
        923691.5914, 7372188.467, 83,
        923737.5603, 7372100.757, 84,
        923783.5634, 7372013.011, 85,
        923829.6017, 7371925.231, 86,
        923875.6763, 7371837.419, 87,
        923503.8433, 7372759.64, 88,
        923549.6771, 7372672.214, 89,
        923595.5372, 7372584.744, 90,
        923641.4246, 7372497.23, 91,
        923687.3404, 7372409.673, 92,
        923733.2855, 7372322.074, 93,
        923779.2608, 7372234.436, 94,
        923825.2672, 7372146.759, 95,
        923871.3056, 7372059.047, 96,
        923917.3766, 7371971.301, 97,
        923963.4812, 7371883.524, 98,
        923591.2288, 7372805.481, 99,
        923637.1076, 7372718.081, 100,
        923683.0118, 7372630.638, 101,
        923728.9423, 7372543.151, 102,
        923774.8998, 7372455.622, 103,
        923820.8852, 7372368.052, 104,
        923866.8991, 7372280.443, 105,
        923912.9422, 7372192.797, 106,
        923959.015, 7372105.116, 107,
        924005.118, 7372017.402, 108,
        924051.2518, 7371929.657, 109,
        923678.5898, 7372851.367, 110,
        923724.5126, 7372763.992, 111,
        923770.46, 7372676.574, 112,
        923816.4328, 7372589.113, 113,
        923862.4314, 7372501.611, 114,
        923908.4564, 7372414.069, 115,
        923954.5083, 7372326.488, 116,
        924000.5875, 7372238.87, 117,
        924046.6941, 7372151.218, 118,
        924092.8286, 7372063.533, 119,
        924138.9911, 7371975.818, 120
    };

    int size = sizeof(points) / sizeof(double) / 3;
    hashtable* ht;
    int i;

    /*
     * double[2] key 
     */

    printf("\n1. Testing a table with key of double[2] type\n\n");

    printf("  creating a table...");
    ht = ht_create_d2(size);
    printf("done\n");

    printf("  inserting %d values from a file...", size);
    for (i = 0; i < size; ++i)
        ht_insert(ht, &points[i * 3], &points[i * 3 + 2]);
    printf("done\n");

    printf("  stats:\n");
    printf("    %d entries, %d table elements, %d filled elements\n", ht->n, ht->size, ht->nhash);
    printf("    %f entries per hash value in use\n", (double) ht->n / ht->nhash);

    printf("  finding and printing each 10th data:\n");
    for (i = 0; i < size; i += 10) {
        double* point = &points[i * 3];
        double* data = ht_find(ht, point);

        if (data != NULL)
            printf("    i = %d; data = \"%d\"\n", i, (int)* data);
        else
            printf("    i = %d; data = <none>\n", i);
    }

    printf("  removing every 3rd element...");
    for (i = 0; i < size; i += 3) {
        double* point = &points[i * 3];
        ht_delete(ht, point);
    }
    printf("done\n");

    printf("  stats:\n");
    printf("    %d entries, %d table elements, %d filled elements\n", ht->n, ht->size, ht->nhash);
    printf("    %f entries per hash value in use\n", (double) ht->n / ht->nhash);

    printf("  finding and printing each 10th data:\n");
    for (i = 0; i < size; i += 10) {
        double* point = &points[i * 3];
        double* data = ht_find(ht, point);

        if (data != NULL)
            printf("    i = %d; data = \"%d\"\n", i, (int)* data);
        else
            printf("    i = %d; data = <none>\n", i);
    }

    printf("  printing all data by calling ht_process():\n ");
    ht_process(ht, print_double);

    printf("\n  destroying the hash table...");
    ht_destroy(ht);
    printf("done\n");

    /*
     * char* key 
     */

    printf("\n2. Testing a table with key of char* type\n\n");

    printf("  creating a table...");
    ht = ht_create_str(size);
    printf("done\n");

    printf("  inserting %d elements with deep copy of each data string...", size);
    for (i = 0; i < size; ++i) {
        char key[BUFSIZE];
        char str[BUFSIZE];
        char* data;

        sprintf(key, "%d-th key", i);
        sprintf(str, "%d-th data", i);
        data = strdup(str);
        ht_insert(ht, key, data);
    }
    printf("done\n");

    printf("  stats:\n");
    printf("    %d entries, %d table elements, %d filled elements\n", ht->n, ht->size, ht->nhash);
    printf("    %f entries per hash value in use\n", (double) ht->n / ht->nhash);

    printf("  finding and printing each 10th data:\n");
    for (i = 0; i < size; i += 10) {
        char key[BUFSIZE];
        char* data;

        sprintf(key, "%d-th key", i);
        data = ht_find(ht, key);
        if (data != NULL)
            printf("    i = %d; data = \"%s\"\n", i, data);
        else
            printf("    i = %d; data = <none>\n", i);
    }

    printf("  removing every 3rd element...");
    for (i = 0; i < size; i += 3) {
        char key[BUFSIZE];

        sprintf(key, "%d-th key", i);
        free(ht_delete(ht, key));
    }
    printf("done\n");

    printf("  stats:\n");
    printf("    %d entries, %d table elements, %d filled elements\n", ht->n, ht->size, ht->nhash);
    printf("    %f entries per hash value in use\n", (double) ht->n / ht->nhash);

    printf("  finding and printing each 10th data:\n");
    for (i = 0; i < size; i += 10) {
        char key[BUFSIZE];
        char* data;

        sprintf(key, "%d-th key", i);
        data = ht_find(ht, key);
        if (data != NULL)
            printf("    i = %d; data = \"%s\"\n", i, data);
        else
            printf("    i = %d; data = <none>\n", i);
    }

    printf("  printing all data by calling ht_process():\n ");
    ht_process(ht, print_string);

    printf("\n  freeing the remaining data by calling ht_process()...");
    ht_process(ht, free);
    printf("done\n");

    printf("  destroying the hash table...");
    ht_destroy(ht);
    printf("done\n");

    return 0;
}
コード例 #26
0
ファイル: hashtable.c プロジェクト: AlexanderC/saffire
/**
 * Return value of key, or NULL when nothing found
 */
void *ht_num_find(t_hash_table *ht, long index) {
    char key[32];
    snprintf(key, 31, "%ld", index);
    return ht_find(ht, key);
}