api: add simple hashtable api
merge form OpenGroup https://pubs.opengroup.org/onlinepubs/009696899/functions/hcreate.html Signed-off-by: guohao15 <guohao15@xiaomi.com>
This commit is contained in:
parent
d2d93ba58c
commit
4fd175fd5c
69
LICENSE
69
LICENSE
@ -8564,3 +8564,72 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
include/search.h
|
||||
======================
|
||||
$NetBSD: search.h,v 1.12 1999/02/22 10:34:28 christos Exp $
|
||||
$FreeBSD: src/include/search.h,v 1.4 2002/03/23 17:24:53 imp Exp $
|
||||
|
||||
Written by J.T. Conklin <jtc@netbsd.org>
|
||||
Public domain.
|
||||
|
||||
libs/libc/search/hcreate.c
|
||||
libs/libc/search/hcreate_r.c
|
||||
======================
|
||||
$NetBSD: hcreate.c,v 1.2 2001/02/19 21:26:04 ross Exp $
|
||||
|
||||
Copyright (c) 2001 Christopher G. Demetriou
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
libs/libc/search/hash_func.c
|
||||
======================
|
||||
Copyright (c) 1990, 1993
|
||||
The Regents of the University of California. All rights reserved.
|
||||
|
||||
This code is derived from software contributed to Berkeley by
|
||||
Margo Seltzer.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the University nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
162
include/search.h
Normal file
162
include/search.h
Normal file
@ -0,0 +1,162 @@
|
||||
/****************************************************************************
|
||||
* include/search.h
|
||||
*
|
||||
* $NetBSD: search.h,v 1.12 1999/02/22 10:34:28 christos Exp $
|
||||
* $FreeBSD: src/include/search.h,v 1.4 2002/03/23 17:24:53 imp Exp $
|
||||
*
|
||||
* Written by J.T. Conklin <jtc@netbsd.org>
|
||||
* Public domain.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __INCLUDE_SEARCH_H
|
||||
#define __INCLUDE_SEARCH_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Type Definitions
|
||||
****************************************************************************/
|
||||
|
||||
typedef struct entry
|
||||
{
|
||||
FAR char *key;
|
||||
FAR void *data;
|
||||
} ENTRY;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FIND,
|
||||
ENTER
|
||||
} ACTION;
|
||||
|
||||
struct hsearch_data
|
||||
{
|
||||
FAR struct internal_head *htable;
|
||||
size_t htablesize;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: hcreate
|
||||
*
|
||||
* Description:
|
||||
* The hcreate() function creates a new hashing table with nel elements.
|
||||
* The hashing table will be used by subsequent calls to hsearch() with
|
||||
* the same htab argument. The hashing table is initialized with nel
|
||||
* hashing buckets.
|
||||
*
|
||||
* The hcreate_r() function is the reentrant version of hcreate().
|
||||
*
|
||||
* Returned Value:
|
||||
* If successful, hcreate() and hcreate_r() return 1; otherwise, they
|
||||
* return 0.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int hcreate(size_t);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: hdestroy
|
||||
*
|
||||
* Description:
|
||||
* The hdestroy() function destroys the hashing table specified by htab.
|
||||
* The hashing table is destroyed only if there are no entries in the
|
||||
* table. The hashing table cannot be used again until hcreate() or
|
||||
* hcreate_r() is called.
|
||||
*
|
||||
* The hdestroy_r() function is the reentrant version of hdestroy().
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void hdestroy(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: hsearch
|
||||
*
|
||||
* Description:
|
||||
* The hsearch() function searches the hashing table specified by htab
|
||||
* for an entry with a key matching that of item. If such an entry is
|
||||
* found, hsearch() returns a pointer to the entry's data object. If
|
||||
* such an entry is not found, hsearch() creates a new entry using the
|
||||
* key and data objects specified by item and returns a pointer to the
|
||||
* new entry's data object.
|
||||
*
|
||||
* The hsearch_r() function is the reentrant version of hsearch().
|
||||
*
|
||||
* Returned Value:
|
||||
* If successful, hsearch() and hsearch_r() return a pointer to the data
|
||||
* object of the matching or newly created entry. Otherwise, they return
|
||||
* NULL.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR ENTRY *hsearch(ENTRY, ACTION);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: hcreate_r
|
||||
*
|
||||
* Description:
|
||||
* Create a new hash table.
|
||||
*
|
||||
* Input Parameters:
|
||||
* nel - The number of elements in the hash table.
|
||||
* htab - The location to return the hash table reference.
|
||||
*
|
||||
* Returned Value:
|
||||
* 1 on success; 0 on failure with errno set appropriately.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int hcreate_r(size_t, FAR struct hsearch_data *);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: hdestroy_r
|
||||
*
|
||||
* Description:
|
||||
* Destroy a hash table.
|
||||
*
|
||||
* Input Parameters:
|
||||
* htab - The hash table to be destroyed.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void hdestroy_r(FAR struct hsearch_data *);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: hsearch_r
|
||||
*
|
||||
* Description:
|
||||
* Search a hash table.
|
||||
*
|
||||
* Input Parameters:
|
||||
* item - The search key.
|
||||
* action - The action to take.
|
||||
* result - The location to return the search result.
|
||||
* htab - The hash table to be searched.
|
||||
*
|
||||
* Returned Value:
|
||||
* 1 on success; 0 on failure with errno set appropriately.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int hsearch_r(ENTRY, ACTION, FAR ENTRY **, FAR struct hsearch_data *);
|
||||
|
||||
#endif /* __INCLUDE_SEARCH_H */
|
@ -49,6 +49,7 @@ include pwd/Make.defs
|
||||
include queue/Make.defs
|
||||
include regex/Make.defs
|
||||
include sched/Make.defs
|
||||
include search/Make.defs
|
||||
include semaphore/Make.defs
|
||||
include signal/Make.defs
|
||||
include spawn/Make.defs
|
||||
|
23
libs/libc/search/CMakeLists.txt
Normal file
23
libs/libc/search/CMakeLists.txt
Normal file
@ -0,0 +1,23 @@
|
||||
# ##############################################################################
|
||||
# libs/libc/search/CMakeLists.txt
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more contributor
|
||||
# license agreements. See the NOTICE file distributed with this work for
|
||||
# additional information regarding copyright ownership. The ASF licenses this
|
||||
# file to you under the Apache License, Version 2.0 (the "License"); you may not
|
||||
# use this file except in compliance with the License. You may obtain a copy of
|
||||
# the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations under
|
||||
# the License.
|
||||
#
|
||||
# ##############################################################################
|
||||
|
||||
set(SRCS hash_func.c hcreate.c hcreate_r.c)
|
||||
|
||||
target_sources(c PRIVATE ${SRCS})
|
28
libs/libc/search/Make.defs
Normal file
28
libs/libc/search/Make.defs
Normal file
@ -0,0 +1,28 @@
|
||||
############################################################################
|
||||
# libs/libc/search/Make.defs
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership. The
|
||||
# ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance with the
|
||||
# License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
# Add the search C files to the build
|
||||
|
||||
CSRCS += hcreate_r.c hcreate.c hash_func.c
|
||||
|
||||
# Add the search directory to the build
|
||||
|
||||
DEPPATH += --dep-path search
|
||||
VPATH += :search
|
126
libs/libc/search/hash_func.c
Normal file
126
libs/libc/search/hash_func.c
Normal file
@ -0,0 +1,126 @@
|
||||
/****************************************************************************
|
||||
* libs/libc/search/hash_func.c
|
||||
*
|
||||
* Copyright (c) 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Margo Seltzer.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define HASH4 h = (h << 5) + h + *key++;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
static uint32_t hash4(FAR const void *, size_t);
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/* Global default hash function */
|
||||
|
||||
uint32_t (*g_default_hash)(FAR const void *, size_t) = hash4;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/* Hash function from Chris Torek. */
|
||||
|
||||
static uint32_t hash4(FAR const void *keyarg, size_t len)
|
||||
{
|
||||
FAR const u_char *key = keyarg;
|
||||
uint32_t h = 0;
|
||||
size_t loop;
|
||||
|
||||
if (len > 0)
|
||||
{
|
||||
loop = (len + 8 - 1) >> 3;
|
||||
switch (len & (8 - 1))
|
||||
{
|
||||
case 0:
|
||||
do
|
||||
{
|
||||
HASH4;
|
||||
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case 7:
|
||||
HASH4;
|
||||
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case 6:
|
||||
HASH4;
|
||||
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case 5:
|
||||
HASH4;
|
||||
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case 4:
|
||||
HASH4;
|
||||
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case 3:
|
||||
HASH4;
|
||||
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case 2:
|
||||
HASH4;
|
||||
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case 1:
|
||||
HASH4;
|
||||
}
|
||||
while (--loop);
|
||||
}
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
140
libs/libc/search/hcreate.c
Normal file
140
libs/libc/search/hcreate.c
Normal file
@ -0,0 +1,140 @@
|
||||
/****************************************************************************
|
||||
* libs/libc/search/hcreate.c
|
||||
*
|
||||
* $NetBSD: hcreate.c,v 1.2 2001/02/19 21:26:04 ross Exp $
|
||||
*
|
||||
* Copyright (c) 2001 Christopher G. Demetriou
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* <<Id: LICENSE_GC,v 1.1 2001/10/01 23:24:05 cgd Exp>>
|
||||
*
|
||||
*
|
||||
* hcreate() / hsearch() / hdestroy()
|
||||
*
|
||||
* SysV/XPG4 hash table functions.
|
||||
*
|
||||
* Implementation done based on NetBSD manual page and Solaris manual page,
|
||||
* plus my own personal experience about how they're supposed to work.
|
||||
*
|
||||
* I tried to look at Knuth (as cited by the Solaris manual page), but
|
||||
* nobody had a copy in the office, so...
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <search.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static struct hsearch_data g_htab;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: hcreate
|
||||
*
|
||||
* Description:
|
||||
* The hcreate() function creates a new hashing table with nel elements.
|
||||
* The hashing table will be used by subsequent calls to hsearch() with
|
||||
* the same htab argument. The hashing table is initialized with nel
|
||||
* hashing buckets.
|
||||
*
|
||||
* The hcreate_r() function is the reentrant version of hcreate().
|
||||
*
|
||||
* Returned Value:
|
||||
* If successful, hcreate() and hcreate_r() return 1; otherwise, they
|
||||
* return 0.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int hcreate(size_t nel)
|
||||
{
|
||||
return hcreate_r(nel, &g_htab);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: hdestroy
|
||||
*
|
||||
* Description:
|
||||
* The hdestroy() function destroys the hashing table specified by htab.
|
||||
* The hashing table is destroyed only if there are no entries in the
|
||||
* table. The hashing table cannot be used again until hcreate() or
|
||||
* hcreate_r() is called.
|
||||
*
|
||||
* The hdestroy_r() function is the reentrant version of hdestroy().
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void hdestroy(void)
|
||||
{
|
||||
hdestroy_r(&g_htab);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: hsearch
|
||||
*
|
||||
* Description:
|
||||
* The hsearch() function searches the hashing table specified by htab
|
||||
* for an entry with a key matching that of item. If such an entry is
|
||||
* found, hsearch() returns a pointer to the entry's data object. If
|
||||
* such an entry is not found, hsearch() creates a new entry using the
|
||||
* key and data objects specified by item and returns a pointer to the
|
||||
* new entry's data object.
|
||||
*
|
||||
* The hsearch_r() function is the reentrant version of hsearch().
|
||||
*
|
||||
* Returned Value:
|
||||
* If successful, hsearch() and hsearch_r() return a pointer to the data
|
||||
* object of the matching or newly created entry. Otherwise, they return
|
||||
* NULL.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR ENTRY *hsearch(ENTRY item, ACTION action)
|
||||
{
|
||||
FAR ENTRY *retval;
|
||||
|
||||
hsearch_r(item, action, &retval, &g_htab);
|
||||
|
||||
return retval;
|
||||
}
|
266
libs/libc/search/hcreate_r.c
Normal file
266
libs/libc/search/hcreate_r.c
Normal file
@ -0,0 +1,266 @@
|
||||
/****************************************************************************
|
||||
* libs/libc/search/hcreate_r.c
|
||||
*
|
||||
* $NetBSD: hcreate.c,v 1.2 2001/02/19 21:26:04 ross Exp $
|
||||
*
|
||||
* Copyright (c) 2001 Christopher G. Demetriou
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* <<Id: LICENSE_GC,v 1.1 2001/10/01 23:24:05 cgd Exp>>
|
||||
*
|
||||
* hcreate() / hsearch() / hdestroy()
|
||||
*
|
||||
* SysV/XPG4 hash table functions.
|
||||
*
|
||||
* Implementation done based on NetBSD manual page and Solaris manual page,
|
||||
* plus my own personal experience about how they're supposed to work.
|
||||
*
|
||||
* I tried to look at Knuth (as cited by the Solaris manual page), but
|
||||
* nobody had a copy in the office, so...
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <search.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "libc.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define MIN_BUCKETS_LG2 4
|
||||
#define MIN_BUCKETS (1 << MIN_BUCKETS_LG2)
|
||||
#define MAX_BUCKETS_LG2 (sizeof (size_t) * 8 - 1 - 5)
|
||||
#define MAX_BUCKETS ((size_t)1 << MAX_BUCKETS_LG2)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct internal_entry
|
||||
{
|
||||
SLIST_ENTRY(internal_entry) link;
|
||||
ENTRY ent;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
SLIST_HEAD(internal_head, internal_entry);
|
||||
extern uint32_t (*g_default_hash)(FAR const void *, size_t);
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: hcreate_r
|
||||
*
|
||||
* Description:
|
||||
* Create a new hash table.
|
||||
*
|
||||
* Input Parameters:
|
||||
* nel - The number of elements in the hash table.
|
||||
* htab - The location to return the hash table reference.
|
||||
*
|
||||
* Returned Value:
|
||||
* 1 on success; 0 on failure with errno set appropriately.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int hcreate_r(size_t nel, FAR struct hsearch_data *htab)
|
||||
{
|
||||
size_t idx;
|
||||
unsigned int p2;
|
||||
|
||||
/* Make sure this this isn't called when a table already exists. */
|
||||
|
||||
if (htab->htable != NULL)
|
||||
{
|
||||
_NX_SETERRNO(-EINVAL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If nel is too small, make it min sized. */
|
||||
|
||||
if (nel < MIN_BUCKETS)
|
||||
{
|
||||
nel = MIN_BUCKETS;
|
||||
}
|
||||
|
||||
/* If it's too large, cap it. */
|
||||
|
||||
if (nel > MAX_BUCKETS)
|
||||
{
|
||||
nel = MAX_BUCKETS;
|
||||
}
|
||||
|
||||
/* If it's is not a power of two in size, round up. */
|
||||
|
||||
if ((nel & (nel - 1)) != 0)
|
||||
{
|
||||
for (p2 = 0; nel != 0; p2++)
|
||||
{
|
||||
nel >>= 1;
|
||||
}
|
||||
|
||||
nel = 1 << p2;
|
||||
}
|
||||
|
||||
/* Allocate the table. */
|
||||
|
||||
htab->htablesize = nel;
|
||||
htab->htable = lib_malloc(htab->htablesize * sizeof htab->htable[0]);
|
||||
if (htab->htable == NULL)
|
||||
{
|
||||
_NX_SETERRNO(-ENOMEM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Initialize it. */
|
||||
|
||||
for (idx = 0; idx < htab->htablesize; idx++)
|
||||
{
|
||||
SLIST_INIT(&(htab->htable[idx]));
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: hdestroy_r
|
||||
*
|
||||
* Description:
|
||||
* Destroy a hash table.
|
||||
*
|
||||
* Input Parameters:
|
||||
* htab - The hash table to be destroyed.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void hdestroy_r(FAR struct hsearch_data *htab)
|
||||
{
|
||||
FAR struct internal_entry *ie;
|
||||
size_t idx;
|
||||
|
||||
if (htab->htable == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (idx = 0; idx < htab->htablesize; idx++)
|
||||
{
|
||||
while (!SLIST_EMPTY(&(htab->htable[idx])))
|
||||
{
|
||||
ie = SLIST_FIRST(&(htab->htable[idx]));
|
||||
SLIST_REMOVE_HEAD(&(htab->htable[idx]), link);
|
||||
lib_free(ie->ent.key);
|
||||
lib_free(ie);
|
||||
}
|
||||
}
|
||||
|
||||
lib_free(htab->htable);
|
||||
htab->htable = NULL;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: hsearch_r
|
||||
*
|
||||
* Description:
|
||||
* Search for an entry in a hash table.
|
||||
*
|
||||
* Input Parameters:
|
||||
* item - The search key
|
||||
* action - The action to take if the item is not found
|
||||
* retval - The location to return the search result
|
||||
* htab - The hash table to be searched
|
||||
*
|
||||
* Returned Value:
|
||||
* 1 on success; 0 on failure with errno set appropriately.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int hsearch_r(ENTRY item, ACTION action, FAR ENTRY **retval,
|
||||
FAR struct hsearch_data *htab)
|
||||
{
|
||||
FAR struct internal_head *head;
|
||||
FAR struct internal_entry *ie;
|
||||
uint32_t hashval;
|
||||
size_t len;
|
||||
|
||||
len = strlen(item.key);
|
||||
hashval = (*g_default_hash)(item.key, len);
|
||||
|
||||
head = &(htab->htable[hashval & (htab->htablesize - 1)]);
|
||||
ie = SLIST_FIRST(head);
|
||||
while (ie != NULL)
|
||||
{
|
||||
if (strcmp(ie->ent.key, item.key) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
ie = SLIST_NEXT(ie, link);
|
||||
}
|
||||
|
||||
if (ie != NULL)
|
||||
{
|
||||
*retval = &ie->ent;
|
||||
return 1;
|
||||
}
|
||||
else if (action == FIND)
|
||||
{
|
||||
*retval = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ie = lib_malloc(sizeof *ie);
|
||||
if (ie == NULL)
|
||||
{
|
||||
*retval = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ie->ent.key = item.key;
|
||||
ie->ent.data = item.data;
|
||||
|
||||
SLIST_INSERT_HEAD(head, ie, link);
|
||||
*retval = &ie->ent;
|
||||
return 1;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user