Actually remove packages from pkghash on removal
Fully removes a package from the hash. Also unify prototype with removal from an alpm_list_t, fixing issues when removing a package from the pkgcache. Signed-off-by: Allan McRae <allan@archlinux.org>
This commit is contained in:
parent
11e5e86151
commit
01c3c7e4f2
|
@ -617,7 +617,7 @@ int _alpm_db_remove_pkgfromcache(pmdb_t *db, pmpkg_t *pkg)
|
|||
_alpm_log(PM_LOG_DEBUG, "removing entry '%s' from '%s' cache\n",
|
||||
alpm_pkg_get_name(pkg), db->treename);
|
||||
|
||||
db->pkgcache = _alpm_pkghash_remove(db->pkgcache, pkg, data);
|
||||
db->pkgcache = _alpm_pkghash_remove(db->pkgcache, pkg, &data);
|
||||
if(data == NULL) {
|
||||
/* package not found */
|
||||
_alpm_log(PM_LOG_DEBUG, "cannot remove entry '%s' from '%s' cache: not found\n",
|
||||
|
|
|
@ -219,11 +219,15 @@ pmpkghash_t *_alpm_pkghash_add_sorted(pmpkghash_t *hash, pmpkg_t *pkg)
|
|||
*
|
||||
* @return the resultant hash
|
||||
*/
|
||||
pmpkghash_t *_alpm_pkghash_remove(pmpkghash_t *hash, pmpkg_t *pkg, pmpkg_t *data)
|
||||
pmpkghash_t *_alpm_pkghash_remove(pmpkghash_t *hash, pmpkg_t *pkg, pmpkg_t **data)
|
||||
{
|
||||
alpm_list_t *i;
|
||||
size_t position;
|
||||
|
||||
if(data) {
|
||||
*data = NULL;
|
||||
}
|
||||
|
||||
if(pkg == NULL || hash == NULL) {
|
||||
return(hash);
|
||||
}
|
||||
|
@ -235,7 +239,6 @@ pmpkghash_t *_alpm_pkghash_remove(pmpkghash_t *hash, pmpkg_t *pkg, pmpkg_t *data
|
|||
if(info->name_hash == pkg->name_hash &&
|
||||
strcmp(info->name, pkg->name) == 0) {
|
||||
|
||||
#if 0 /* Actually removing items is not a good idea with linear probing... */
|
||||
/* remove from list */
|
||||
/* TODO - refactor with alpm_list_remove */
|
||||
if(i == hash->list) {
|
||||
|
@ -266,16 +269,34 @@ pmpkghash_t *_alpm_pkghash_remove(pmpkghash_t *hash, pmpkg_t *pkg, pmpkg_t *data
|
|||
}
|
||||
|
||||
/* remove from hash */
|
||||
data = info;
|
||||
info = NULL;
|
||||
if(data) {
|
||||
*data = info;
|
||||
}
|
||||
hash->hash_table[position] = NULL;
|
||||
free(i);
|
||||
i = NULL;
|
||||
|
||||
hash->entries -= 1;
|
||||
#endif
|
||||
|
||||
/* fake removal - pkgname can not be blank so 0 hash is impossible */
|
||||
info->name_hash = 0;
|
||||
/* potentially move entries following removed entry to keep
|
||||
* open addressing collision resolution working */
|
||||
size_t next_null = (position + 1) % hash->buckets;
|
||||
while(hash->hash_table[next_null] != NULL) {
|
||||
next_null = (next_null + 1) % hash->buckets;
|
||||
}
|
||||
|
||||
position = (position + 1) % hash->buckets;
|
||||
|
||||
while((i = hash->hash_table[position]) != NULL) {
|
||||
info = i->data;
|
||||
size_t new_position = get_hash_position(info->name_hash, hash);
|
||||
|
||||
if(new_position != next_null) {
|
||||
hash->hash_table[new_position] = i;
|
||||
hash->hash_table[position] = NULL;
|
||||
}
|
||||
|
||||
position = (position + 1) % hash->buckets;
|
||||
}
|
||||
|
||||
return(hash);
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ pmpkghash_t *_alpm_pkghash_create(size_t size);
|
|||
|
||||
pmpkghash_t *_alpm_pkghash_add(pmpkghash_t *hash, pmpkg_t *pkg);
|
||||
pmpkghash_t *_alpm_pkghash_add_sorted(pmpkghash_t *hash, pmpkg_t *pkg);
|
||||
pmpkghash_t *_alpm_pkghash_remove(pmpkghash_t *hash, pmpkg_t *pkg, pmpkg_t *data);
|
||||
pmpkghash_t *_alpm_pkghash_remove(pmpkghash_t *hash, pmpkg_t *pkg, pmpkg_t **data);
|
||||
|
||||
void _alpm_pkghash_free(pmpkghash_t *hash);
|
||||
|
||||
|
|
Loading…
Reference in New Issue