コード例 #1
0
ファイル: state.c プロジェクト: johnoshaughnessy/Openswan
/* unlink a state object from the hash table, but don't free it
 */
void
unhash_state(struct state *st)
{
    /* unlink from forward chain */
    struct state **p;

    if(st->st_hashchain_prev == NULL) {
	p = state_hash(st->st_icookie, st->st_rcookie, NULL);
	if(*p != st) {
	    p = state_hash(st->st_icookie, zero_cookie, NULL);
	}
    } else {
	p = &st->st_hashchain_prev->st_hashchain_next;
    }

    /* unlink from forward chain */
    passert(*p == st);
    *p = st->st_hashchain_next;

    /* unlink from backward chain */
    if (st->st_hashchain_next != NULL)
    {
	passert(st->st_hashchain_next->st_hashchain_prev == st);
	st->st_hashchain_next->st_hashchain_prev = st->st_hashchain_prev;
    }

    st->st_hashchain_next = st->st_hashchain_prev = NULL;
}
コード例 #2
0
ファイル: state.c プロジェクト: ysm001/slim
/**
 * 引数としてあたえられたStateが等しいかどうかを判定する
 */
static int state_equals_with_compress(State *check, State *stored)
{
  LmnBinStr bs1, bs2;
  int t;

#ifdef PROFILE
  if (lmn_env.prof_no_memeq) {
    /* 本フラグが真の場合はグラフ同形成判定を行わず, ハッシュ値の一致不一致で状態の等価性を判定する.
     * ハッシュコンフリクトで完全性が損なわれるが, .
     * ハッシュ値が完全に散らばることが既知の問題に対し, メモリ使用量等のプロファイルを取る際など,
     * プロファイル収集を円滑に行うべく使用する. グラフ同型成判定の時間分だけ高速化できる */
    return (state_hash(check) == state_hash(stored));
  }
#endif

  if (s_is_d(check)) {
    bs1 = state_D_fetch(check);
  } else {
    bs1 = state_binstr(check);
  }

  if (s_is_d(stored)) {
    bs2 = state_binstr_reconstructor(stored);
  } else {
    bs2 = state_binstr(stored);
  }

  if (is_encoded(check) && is_encoded(stored)) {
    /* 膜のIDで比較 */
    t =
      check->state_name == stored->state_name &&
      binstr_compare(bs1, bs2) == 0;
  }
  else if (state_mem(check) && bs2) {
    /* 同型性判定 */
    t =
      check->state_name == stored->state_name &&
      lmn_mem_equals_enc(bs2, state_mem(check));
  }
  else if (bs1 && bs2) {
    /* このブロックは基本的には例外処理なので注意.
     * PORなどでコピー状態を挿入する際に呼ばれることがある. */
    LmnMembrane *mem = lmn_binstr_decode(bs1);
    t =
      check->state_name == stored->state_name &&
      lmn_mem_equals_enc(bs2, mem);
    lmn_mem_free_rec(mem);
  }
  else {
    lmn_fatal("implementation error");
  }

  if (s_is_d(stored)) {
    lmn_binstr_free(bs2);
  }

  return t;
}
コード例 #3
0
ファイル: state.c プロジェクト: johnoshaughnessy/Openswan
/*
 * unlink a state object from the hash table that had a zero
 * rcookie before, and rehash it into the right place
 */
void
rehash_state(struct state *st)
{
    unsigned bucket = 0;
    /* unlink from forward chain */
    struct state **p = st->st_hashchain_prev == NULL
	? state_hash(st->st_icookie, zero_cookie, &bucket)
	: &st->st_hashchain_prev->st_hashchain_next;

    DBG(DBG_CONTROL
	, DBG_log("rehashing state object #%lu from bucket %u"
                  , st->st_serialno, bucket));

    /* unlink from forward chain */
    passert(*p == st);
    *p = st->st_hashchain_next;

    /* unlink from backward chain */
    if (st->st_hashchain_next != NULL)
    {
	passert(st->st_hashchain_next->st_hashchain_prev == st);
	st->st_hashchain_next->st_hashchain_prev = st->st_hashchain_prev;
    }

    st->st_hashchain_next = st->st_hashchain_prev = NULL;

    /* now, re-insert */
    insert_state(st);
}
コード例 #4
0
ファイル: state.c プロジェクト: johnoshaughnessy/Openswan
/* Insert a state object in the hash table. The object is inserted
 * at the begining of list.
 * Needs cookies, connection, and msgid.
 */
void
insert_state(struct state *st)
{
    unsigned int bucket;
    struct state **p = state_hash(st->st_icookie, st->st_rcookie, &bucket);

    passert(st->st_hashchain_prev == NULL && st->st_hashchain_next == NULL);

    DBG(DBG_CONTROL
	, DBG_log("inserting state object #%lu bucket: %u"
		  , st->st_serialno, bucket));

    if (*p != NULL)
    {
	passert((*p)->st_hashchain_prev == NULL);
	(*p)->st_hashchain_prev = st;
    }
    st->st_hashchain_next = *p;
    *p = st;

    /* Ensure that somebody is in charge of killing this state:
     * if no event is scheduled for it, schedule one to discard the state.
     * If nothing goes wrong, this event will be replaced by
     * a more appropriate one.
     */
    if (st->st_event == NULL)
	event_schedule(EVENT_SO_DISCARD, 0, st);

    refresh_state(st);
}
コード例 #5
0
static State *
state_table_force (StateTable *table, const unsigned *positions)
{
  unsigned hash = state_hash (table->n_entries, positions);
  unsigned idx = hash % table->n_entries;
  State *at = table->hash_table[idx];
  while (at != NULL)
    {
      if (memcmp (at->positions, positions, sizeof (unsigned) * table->n_entries) == 0)
        return at;
      at = at->hash_next;
    }

  /* Allocate a state */
  if (table->n_states_free_in_slab == 0)
    {
      StateSlab *slab = dsk_malloc (table->sizeof_slab);
      table->next_free_in_cur_slab = (State *)(slab + 1);
      table->n_states_free_in_slab = table->n_states_in_slab;
      slab->next_slab = table->cur_slab;
      table->cur_slab = slab;
    }
  at = table->next_free_in_cur_slab;
  table->next_free_in_cur_slab = (State *) ((char*)table->next_free_in_cur_slab + table->sizeof_state);
  table->n_states_free_in_slab -= 1;

  table->occupancy++;
  if (table->occupancy * 2 > table->table_size)
    {
      unsigned new_table_size = ...;
      ...
      idx = hash % table->table_size;
    }