Implemented hash_remove_current() which removes the current iterator position
from the hash - not yet tested. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20368 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
824e907a2c
commit
826e857cf0
@ -1,9 +1,16 @@
|
||||
/*
|
||||
** Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
||||
** Distributed under the terms of the NewOS License.
|
||||
*/
|
||||
#ifndef _KERNEL_KHASH_H
|
||||
#define _KERNEL_KHASH_H
|
||||
/*
|
||||
* Copyright 2002-2007, Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
||||
* Distributed under the terms of the NewOS License.
|
||||
*/
|
||||
#ifndef _KERNEL_UTIL_KHASH_H
|
||||
#define _KERNEL_UTIL_KHASH_H
|
||||
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
// can be allocated on the stack
|
||||
typedef struct hash_iterator {
|
||||
@ -23,6 +30,7 @@ struct hash_table *hash_init(uint32 table_size, int next_ptr_offset,
|
||||
int hash_uninit(struct hash_table *table);
|
||||
status_t hash_insert(struct hash_table *table, void *_element);
|
||||
status_t hash_remove(struct hash_table *table, void *_element);
|
||||
void hash_remove_current(struct hash_table *table, struct hash_iterator *iterator);
|
||||
void *hash_remove_first(struct hash_table *table, uint32 *_cookie);
|
||||
void *hash_find(struct hash_table *table, void *e);
|
||||
void *hash_lookup(struct hash_table *table, const void *key);
|
||||
@ -31,17 +39,15 @@ void hash_close(struct hash_table *table, struct hash_iterator *i, bool free_ite
|
||||
void *hash_next(struct hash_table *table, struct hash_iterator *i);
|
||||
void hash_rewind(struct hash_table *table, struct hash_iterator *i);
|
||||
|
||||
/* function ptrs must look like this:
|
||||
/* function pointers must look like this:
|
||||
*
|
||||
* uint32 hash_func(void *e, const void *key, uint32 range);
|
||||
* hash function should calculate hash on either e or key,
|
||||
* depending on which one is not NULL
|
||||
* depending on which one is not NULL - they also need
|
||||
* to make sure the returned value is within range.
|
||||
* int compare_func(void *e, const void *key);
|
||||
* compare function should compare the element with
|
||||
* the key, returning 0 if equal, other if not
|
||||
* NOTE: compare func can be null, in which case the hash
|
||||
* code will compare the key pointer with the target
|
||||
* ToDo: check this!
|
||||
*/
|
||||
|
||||
uint32 hash_hash_string(const char *str);
|
||||
@ -50,4 +56,4 @@ uint32 hash_hash_string(const char *str);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _KERNEL_KHASH_H */
|
||||
#endif /* _KERNEL_UTIL_KHASH_H */
|
||||
|
@ -1,16 +1,21 @@
|
||||
/* Generic hash table
|
||||
**
|
||||
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
|
||||
** Distributed under the terms of the NewOS License.
|
||||
*/
|
||||
/*
|
||||
* Copyright 2002-2007, Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Copyright 2001, Travis Geiselbrecht. All rights reserved.
|
||||
* Distributed under the terms of the NewOS License.
|
||||
*/
|
||||
|
||||
//! Generic hash table
|
||||
|
||||
|
||||
#include <KernelExport.h>
|
||||
#include <malloc.h>
|
||||
#include <debug.h>
|
||||
#include <Errors.h>
|
||||
#include <string.h>
|
||||
#include <util/khash.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define TRACE_HASH 0
|
||||
#if TRACE_HASH
|
||||
# define TRACE(x) dprintf x
|
||||
@ -18,9 +23,9 @@
|
||||
# define TRACE(x) ;
|
||||
#endif
|
||||
|
||||
// ToDo: the hashtable is not expanded when necessary (no load factor, no nothing)
|
||||
// Could try to use pools instead of malloc() for the elements - might be
|
||||
// faster than the current approach.
|
||||
// TODO: the hashtable is not expanded when necessary (no load factor, nothing)
|
||||
// resizing should be optional, though, in case the hash is used at times
|
||||
// that forbid resizing.
|
||||
|
||||
struct hash_table {
|
||||
struct hash_element **table;
|
||||
@ -123,7 +128,8 @@ hash_remove(struct hash_table *table, void *_element)
|
||||
uint32 hash = table->hash_func(_element, NULL, table->table_size);
|
||||
void *element, *lastElement = NULL;
|
||||
|
||||
for (element = table->table[hash]; element != NULL; lastElement = element, element = NEXT(table, element)) {
|
||||
for (element = table->table[hash]; element != NULL;
|
||||
lastElement = element, element = NEXT(table, element)) {
|
||||
if (element == _element) {
|
||||
if (lastElement != NULL) {
|
||||
// connect the previous entry with the next one
|
||||
@ -140,6 +146,40 @@ hash_remove(struct hash_table *table, void *_element)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
hash_remove_current(struct hash_table *table, struct hash_iterator *iterator)
|
||||
{
|
||||
uint32 index = iterator->bucket;
|
||||
void *element;
|
||||
|
||||
if (iterator->current == NULL)
|
||||
panic("hash_remove_current() called too early.");
|
||||
|
||||
for (element = table->table[index]; index < table->table_size; index++) {
|
||||
void *lastElement = NULL;
|
||||
|
||||
while (element != NULL) {
|
||||
if (element == iterator->current) {
|
||||
iterator->current = lastElement;
|
||||
|
||||
if (lastElement != NULL) {
|
||||
// connect the previous entry with the next one
|
||||
PUT_IN_NEXT(table, lastElement, NEXT(table, element));
|
||||
} else {
|
||||
table->table[index] = (struct hash_element *)NEXT(table,
|
||||
element);
|
||||
}
|
||||
|
||||
table->num_elements--;
|
||||
return;
|
||||
}
|
||||
|
||||
element = NEXT(table, element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
hash_remove_first(struct hash_table *table, uint32 *_cookie)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user