mirror of
https://github.com/apache/nuttx.git
synced 2025-12-10 20:24:51 +08:00
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:
committed by
Alan Carvalho de Assis
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,
|
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
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.
|
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 queue/Make.defs
|
||||||
include regex/Make.defs
|
include regex/Make.defs
|
||||||
include sched/Make.defs
|
include sched/Make.defs
|
||||||
|
include search/Make.defs
|
||||||
include semaphore/Make.defs
|
include semaphore/Make.defs
|
||||||
include signal/Make.defs
|
include signal/Make.defs
|
||||||
include spawn/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;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user