コード例 #1
0
ファイル: st.c プロジェクト: iriscouch/ruby-inabox
int
st_delete_safe(register st_table *table, register st_data_t *key, st_data_t *value, st_data_t never)
{
    unsigned int hash_val;
    register st_table_entry *ptr;

    if (table->entries_packed) {
	st_index_t i;
	for (i = 0; i < table->num_entries; i++) {
	    if ((st_data_t)table->bins[i*2] == *key) {
		if (value != 0) *value = (st_data_t)table->bins[i*2+1];
		table->bins[i*2] = (void *)never;
		return 1;
	    }
	}
	if (value != 0) *value = 0;
	return 0;
    }

    hash_val = do_hash_bin(*key, table);
    ptr = table->bins[hash_val];

    for (; ptr != 0; ptr = ptr->next) {
	if ((ptr->key != never) && EQUAL(table, ptr->key, *key)) {
	    REMOVE_ENTRY(table, ptr);
	    *key = ptr->key;
	    if (value != 0) *value = ptr->record;
	    ptr->key = ptr->record = never;
	    return 1;
	}
    }

    if (value != 0) *value = 0;
    return 0;
}
コード例 #2
0
ファイル: cocoa_st.c プロジェクト: a-bx/mruby-cocoa
int
cocoa_st_foreach(cocoa_st_table *table, enum cocoa_st_retval (*func)(ANYARGS), cocoa_st_data_t arg)
{
    cocoa_st_table_entry *ptr, **last, *tmp;
    enum cocoa_st_retval retval;
    cocoa_st_index_t i;

    if ((ptr = table->head) != 0) {
        do {
            i = ptr->hash % table->num_bins;
            retval = (*func)(ptr->key, ptr->record, (void*)arg);
            switch (retval) {
              case COCOA_ST_CHECK:    /* check if hash is modified during iteration */
                for (tmp = table->bins[i]; tmp != ptr; tmp = tmp->next) {
                    if (!tmp) {
                        /* call func with error notice */
                        retval = (*func)(0, 0, arg, 1);
                        return 1;
                    }
                }
                /* fall through */
              default:
              case COCOA_ST_CONTINUE:
                ptr = ptr->fore;
                break;
              case COCOA_ST_STOP:
                return 0;
              case COCOA_ST_DELETE:
                last = &table->bins[ptr->hash % table->num_bins];
                for (; (tmp = *last) != 0; last = &tmp->next) {
                    if (ptr == tmp) {
                        tmp = ptr->fore;
                        *last = ptr->next;
                        REMOVE_ENTRY(table, ptr);
                        free(ptr);
                        if (ptr == tmp) return 0;
                        ptr = tmp;
                        break;
                    }
                }
            }
        } while (ptr && table->head);
    }
    return 0;
}
コード例 #3
0
ファイル: cocoa_st.c プロジェクト: a-bx/mruby-cocoa
int
cocoa_st_delete(register cocoa_st_table *table, register cocoa_st_data_t *key, cocoa_st_data_t *value)
{
    cocoa_st_index_t hash_val;
    cocoa_st_table_entry **prev;
    register cocoa_st_table_entry *ptr;

    hash_val = do_hash_bin(*key, table);
    for (prev = &table->bins[hash_val]; (ptr = *prev) != 0; prev = &ptr->next) {
        if (EQUAL(table, *key, ptr->key)) {
            *prev = ptr->next;
            REMOVE_ENTRY(table, ptr);
            if (value != 0) *value = ptr->record;
            *key = ptr->key;
            free(ptr);
            return 1;
        }
    }

    if (value != 0) *value = 0;
    return 0;
}
コード例 #4
0
ファイル: st.c プロジェクト: jixc2008/rhodes
int
st_delete_safe(register st_table *table, register st_data_t *key, st_data_t *value, st_data_t never)
{
    unsigned int hash_val;
    register st_table_entry *ptr;

    hash_val = do_hash_bin(*key, table);
    ptr = table->bins[hash_val];

    for (; ptr != 0; ptr = ptr->next) {
	if ((ptr->key != never) && EQUAL(table, ptr->key, *key)) {
	    REMOVE_ENTRY(table, ptr);
	    *key = ptr->key;
	    if (value != 0) *value = ptr->record;
	    ptr->key = ptr->record = never;
	    return 1;
	}
    }

    if (value != 0) *value = 0;
    return 0;
}
コード例 #5
0
ファイル: st.c プロジェクト: iriscouch/ruby-inabox
int
st_delete(register st_table *table, register st_data_t *key, st_data_t *value)
{
    unsigned int hash_val;
    st_table_entry **prev;
    register st_table_entry *ptr;

    if (table->entries_packed) {
        int i;
        for (i = 0; i < table->num_entries; i++) {
            if ((st_data_t)table->bins[i*2] == *key) {
                if (value != 0) *value = (st_data_t)table->bins[i*2+1];
                table->num_entries--;
                memmove(&table->bins[i*2], &table->bins[(i+1)*2],
                        sizeof(struct st_table_entry*) * 2*(table->num_entries-i));
                return 1;
            }
        }
        if (value != 0) *value = 0;
        return 0;
    }

    hash_val = do_hash_bin(*key, table);

    for (prev = &table->bins[hash_val]; (ptr = *prev) != 0; prev = &ptr->next) {
	if (EQUAL(table, *key, ptr->key)) {
	    *prev = ptr->next;
	    REMOVE_ENTRY(table, ptr);
	    if (value != 0) *value = ptr->record;
	    *key = ptr->key;
	    free(ptr);
	    return 1;
	}
    }

    if (value != 0) *value = 0;
    return 0;
}
コード例 #6
0
ファイル: st.c プロジェクト: iriscouch/ruby-inabox
		/* fall through */
	      case ST_CONTINUE:
		ptr = ptr->fore;
		break;
	      case ST_STOP:
		return 0;
	      case ST_DELETE:
		last = &table->bins[ptr->hash % table->num_bins];
		for (; (tmp = *last) != 0; last = &tmp->next) {
		    if (ptr == tmp) {
			tmp = ptr->fore;
			*last = ptr->next;
			REMOVE_ENTRY(table, ptr);
			free(ptr);
			if (ptr == tmp) return 0;
			ptr = tmp;
			break;
		    }
		}
	    }
	} while (ptr && table->head);
    }
    return 0;
}

#if 0  /* unused right now */
int
st_reverse_foreach(st_table *table, int (*func)(ANYARGS), st_data_t arg)
{
    st_table_entry *ptr, **last, *tmp;
    enum st_retval retval;
    int i;

    if (table->entries_packed) {
        for (i = table->num_entries-1; 0 <= i; i--) {
            int j;
            st_data_t key, val;
            key = (st_data_t)table->bins[i*2];
            val = (st_data_t)table->bins[i*2+1];
            retval = (*func)(key, val, arg);
            switch (retval) {
	      case ST_CHECK:	/* check if hash is modified during iteration */
                for (j = 0; j < table->num_entries; j++) {
                    if ((st_data_t)table->bins[j*2] == key)
                        break;
                }
                if (j == table->num_entries) {
                    /* call func with error notice */
                    retval = (*func)(0, 0, arg, 1);
                    return 1;
                }
		/* fall through */
	      case ST_CONTINUE:
		break;
	      case ST_STOP:
		return 0;
	      case ST_DELETE:
                table->num_entries--;
                memmove(&table->bins[i*2], &table->bins[(i+1)*2],
                        sizeof(struct st_table_entry*) * 2*(table->num_entries-i));
                break;
            }
        }
        return 0;
    }

    if ((ptr = table->head) != 0) {
	ptr = ptr->back;
	do {
	    retval = (*func)(ptr->key, ptr->record, arg, 0);
	    switch (retval) {
	      case ST_CHECK:	/* check if hash is modified during iteration */
		i = ptr->hash % table->num_bins;
		for (tmp = table->bins[i]; tmp != ptr; tmp = tmp->next) {
		    if (!tmp) {
			/* call func with error notice */
			retval = (*func)(0, 0, arg, 1);
			return 1;
		    }
		}
		/* fall through */
	      case ST_CONTINUE:
		ptr = ptr->back;
		break;
	      case ST_STOP:
		return 0;
	      case ST_DELETE:
		last = &table->bins[ptr->hash % table->num_bins];
		for (; (tmp = *last) != 0; last = &tmp->next) {
		    if (ptr == tmp) {
			tmp = ptr->back;
			*last = ptr->next;
			REMOVE_ENTRY(table, ptr);
			free(ptr);
			ptr = tmp;
			break;
		    }
		}
		ptr = ptr->next;
		free(tmp);
		table->num_entries--;
	    }
	} while (ptr && table->head);
    }
    return 0;
}