mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
st.c: update st_reverse_foreach
* st.c (st_reverse_foreach): update as st_foreach(). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47788 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
27ce2d1328
commit
6557a6b9ed
1 changed files with 111 additions and 29 deletions
134
st.c
134
st.c
|
@ -1156,33 +1156,123 @@ st_values_check(st_table *table, st_data_t *values, st_index_t size, st_data_t n
|
||||||
|
|
||||||
#if 0 /* unused right now */
|
#if 0 /* unused right now */
|
||||||
int
|
int
|
||||||
st_reverse_foreach(st_table *table, int (*func)(ANYARGS), st_data_t arg)
|
st_reverse_foreach_check(st_table *table, int (*func)(ANYARGS), st_data_t arg, st_data_t never)
|
||||||
{
|
{
|
||||||
st_table_entry *ptr, **last, *tmp;
|
st_table_entry *ptr, **last, *tmp;
|
||||||
enum st_retval retval;
|
enum st_retval retval;
|
||||||
int i;
|
st_index_t i;
|
||||||
|
|
||||||
if (table->entries_packed) {
|
if (table->entries_packed) {
|
||||||
for (i = table->num_entries-1; 0 <= i; i--) {
|
for (i = table->real_entries; 0 < i;) {
|
||||||
int j;
|
|
||||||
st_data_t key, val;
|
st_data_t key, val;
|
||||||
|
st_index_t hash;
|
||||||
|
--i;
|
||||||
key = PKEY(table, i);
|
key = PKEY(table, i);
|
||||||
val = PVAL(table, i);
|
val = PVAL(table, i);
|
||||||
|
hash = PHASH(table, i);
|
||||||
|
if (key == never) continue;
|
||||||
retval = (*func)(key, val, arg, 0);
|
retval = (*func)(key, val, arg, 0);
|
||||||
|
if (!table->entries_packed) {
|
||||||
|
FIND_ENTRY(table, ptr, hash, i);
|
||||||
|
if (retval == ST_CHECK) {
|
||||||
|
if (!ptr) goto deleted;
|
||||||
|
goto unpacked_continue;
|
||||||
|
}
|
||||||
|
goto unpacked;
|
||||||
|
}
|
||||||
switch (retval) {
|
switch (retval) {
|
||||||
case ST_CHECK: /* check if hash is modified during iteration */
|
case ST_CHECK: /* check if hash is modified during iteration */
|
||||||
for (j = 0; j < table->num_entries; j++) {
|
if (PHASH(table, i) == 0 && PKEY(table, i) == never) {
|
||||||
if (PKEY(table, j) == key)
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (j == table->num_entries) {
|
i = find_packed_index_from(table, hash, key, i);
|
||||||
/* call func with error notice */
|
if (i >= table->real_entries) {
|
||||||
retval = (*func)(0, 0, arg, 1);
|
i = find_packed_index(table, hash, key);
|
||||||
return 1;
|
if (i >= table->real_entries) goto deleted;
|
||||||
}
|
}
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case ST_CONTINUE:
|
case ST_CONTINUE:
|
||||||
break;
|
break;
|
||||||
|
case ST_STOP:
|
||||||
|
return 0;
|
||||||
|
case ST_DELETE:
|
||||||
|
remove_safe_packed_entry(table, i, never);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ptr = table->tail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ptr != 0) {
|
||||||
|
do {
|
||||||
|
if (ptr->key == never)
|
||||||
|
goto unpacked_continue;
|
||||||
|
i = hash_pos(ptr->hash, table->num_bins);
|
||||||
|
retval = (*func)(ptr->key, ptr->record, arg, 0);
|
||||||
|
unpacked:
|
||||||
|
switch (retval) {
|
||||||
|
case ST_CHECK: /* check if hash is modified during iteration */
|
||||||
|
for (tmp = table->bins[i]; tmp != ptr; tmp = tmp->next) {
|
||||||
|
if (!tmp) {
|
||||||
|
deleted:
|
||||||
|
/* call func with error notice */
|
||||||
|
retval = (*func)(0, 0, arg, 1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* fall through */
|
||||||
|
case ST_CONTINUE:
|
||||||
|
unpacked_continue:
|
||||||
|
ptr = ptr->back;
|
||||||
|
break;
|
||||||
|
case ST_STOP:
|
||||||
|
return 0;
|
||||||
|
case ST_DELETE:
|
||||||
|
last = &table->bins[hash_pos(ptr->hash, table->num_bins)];
|
||||||
|
for (; (tmp = *last) != 0; last = &tmp->next) {
|
||||||
|
if (ptr == tmp) {
|
||||||
|
tmp = ptr->back;
|
||||||
|
remove_entry(table, ptr);
|
||||||
|
ptr->key = ptr->record = never;
|
||||||
|
ptr->hash = 0;
|
||||||
|
ptr = tmp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (ptr && table->head);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
st_reverse_foreach(st_table *table, int (*func)(ANYARGS), st_data_t arg)
|
||||||
|
{
|
||||||
|
st_table_entry *ptr, **last, *tmp;
|
||||||
|
enum st_retval retval;
|
||||||
|
st_index_t i;
|
||||||
|
|
||||||
|
if (table->entries_packed) {
|
||||||
|
for (i = table->real_entries; 0 < i;) {
|
||||||
|
st_data_t key, val;
|
||||||
|
st_index_t hash;
|
||||||
|
--i;
|
||||||
|
key = PKEY(table, i);
|
||||||
|
val = PVAL(table, i);
|
||||||
|
hash = PHASH(table, i);
|
||||||
|
retval = (*func)(key, val, arg, 0);
|
||||||
|
if (!table->entries_packed) {
|
||||||
|
FIND_ENTRY(table, ptr, hash, i);
|
||||||
|
if (!ptr) return 0;
|
||||||
|
goto unpacked;
|
||||||
|
}
|
||||||
|
switch (retval) {
|
||||||
|
case ST_CONTINUE:
|
||||||
|
break;
|
||||||
|
case ST_CHECK:
|
||||||
case ST_STOP:
|
case ST_STOP:
|
||||||
return 0;
|
return 0;
|
||||||
case ST_DELETE:
|
case ST_DELETE:
|
||||||
|
@ -1192,25 +1282,20 @@ st_reverse_foreach(st_table *table, int (*func)(ANYARGS), st_data_t arg)
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
ptr = table->tail;
|
||||||
|
}
|
||||||
|
|
||||||
if ((ptr = table->head) != 0) {
|
if (ptr != 0) {
|
||||||
ptr = ptr->back;
|
|
||||||
do {
|
do {
|
||||||
retval = (*func)(ptr->key, ptr->record, arg, 0);
|
|
||||||
switch (retval) {
|
|
||||||
case ST_CHECK: /* check if hash is modified during iteration */
|
|
||||||
i = hash_pos(ptr->hash, table->num_bins);
|
i = hash_pos(ptr->hash, table->num_bins);
|
||||||
for (tmp = table->bins[i]; tmp != ptr; tmp = tmp->next) {
|
retval = (*func)(ptr->key, ptr->record, arg, 0);
|
||||||
if (!tmp) {
|
unpacked:
|
||||||
/* call func with error notice */
|
switch (retval) {
|
||||||
retval = (*func)(0, 0, arg, 1);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* fall through */
|
|
||||||
case ST_CONTINUE:
|
case ST_CONTINUE:
|
||||||
ptr = ptr->back;
|
ptr = ptr->back;
|
||||||
break;
|
break;
|
||||||
|
case ST_CHECK:
|
||||||
case ST_STOP:
|
case ST_STOP:
|
||||||
return 0;
|
return 0;
|
||||||
case ST_DELETE:
|
case ST_DELETE:
|
||||||
|
@ -1225,9 +1310,6 @@ st_reverse_foreach(st_table *table, int (*func)(ANYARGS), st_data_t arg)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ptr = ptr->next;
|
|
||||||
free(tmp);
|
|
||||||
table->num_entries--;
|
|
||||||
}
|
}
|
||||||
} while (ptr && table->head);
|
} while (ptr && table->head);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue