// : vi ts=4 sw=4 noet :
/*
==================================================================================
- Copyright (c) 2019 Nokia
+ Copyright (c) 2019 Nokia
Copyright (c) 2018-2019 AT&T Intellectual Property.
Licensed 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
+ 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,
------------------------------------------------------------------------------
Mnemonic: symtab.c
Abstract: Symbol table -- slightly streamlined from it's original 2000 version
- (a part of the {X}fm opensource code), though we must retain the
+ (a part of the {X}fm opensource code), though we must retain the
original copyright.
Things changed for the Ric Msg implemention (Nov 2018):
- no concept of copy/free of the user data (functions removed)
- add ability to support an integer key (class 0)
+ Numeric key is an unsigned, 64bit key.
- externally visible names given a rmr_ extension as it's being
- incorporated into the RIC msg routing library and will be
+ incorporated into the RIC msg routing library and will be
available to user applications.
Date: 11 Feb 2000
#include <string.h>
#include <stdlib.h>
#include <memory.h>
+#include <netdb.h>
#include "rmr_symtab.h"
struct Sym_ele *next; /* pointer at next element in list */
struct Sym_ele *prev; /* larger table, easier deletes */
const char *name; /* symbol name */
- unsigned int nkey; // the numeric key
+ uint64_t nkey; // the numeric key
void *val; /* user data associated with name */
unsigned long mcount; /* modificaitons to value */
unsigned long rcount; /* references to symbol */
- //unsigned int flags;
+ //unsigned int flags;
unsigned int class; /* helps divide things up and allows for duplicate names */
} Sym_ele;
Sym_ele **symlist; /* pointer to list of element pointerss */
long inhabitants; /* number of active residents */
long deaths; /* number of deletes */
- long size;
+ long size;
} Sym_tab;
// -------------------- internal ------------------------------------------------------------------
eptr->next->prev = eptr->prev;
if( eptr->class && eptr->name ) { // class 0 entries are numeric, so name is NOT a pointer
- free( (void *) eptr->name ); // and if free fails, what? panic?
+ free( (void *) eptr->name ); // and if free fails, what? panic?
}
free( eptr );
return 0;
}
-/*
+/*
Generic routine to put something into the table
called by sym_map or sym_put since the logic for each is pretty
much the same.
*/
static int putin( Sym_tab *table, const char *name, unsigned int class, void *val ) {
- Sym_ele *eptr; /* pointer into hash table */
- Sym_ele **sym_tab; /* pointer into hash table */
- int hv; /* hash value */
- int rc = 0; /* assume it existed */
- unsigned int nkey = 0; // numeric key if class == 0
+ Sym_ele *eptr; /* pointer into hash table */
+ Sym_ele **sym_tab; /* pointer into hash table */
+ int hv; /* hash value */
+ int rc = 0; /* assume it existed */
+ uint64_t nkey = 0; // numeric key if class == 0
sym_tab = table->symlist;
hv = sym_hash( name, table->size ); // hash it
for( eptr=sym_tab[hv]; eptr && ! same( class, eptr->class, eptr->name, name); eptr=eptr->next );
} else {
- nkey = *((int *) name);
+ nkey = *((uint64_t *) name);
hv = nkey % table->size; // just hash the number
for( eptr=sym_tab[hv]; eptr && eptr->nkey != nkey; eptr=eptr->next );
}
if( ! eptr ) { // not found above, so add
rc++;
table->inhabitants++;
-
+
eptr = (Sym_ele *) malloc( sizeof( Sym_ele) );
if( ! eptr ) {
fprintf( stderr, "[FAIL] symtab/putin: out of memory\n" );
return -1;
- }
+ }
eptr->prev = NULL;
eptr->class = class;
{
Sym_tab *table;
Sym_ele **sym_tab;
- int i;
+ int i;
table = (Sym_tab *) vtable;
sym_tab = table->symlist;
for( i = 0; i < table->size; i++ )
- while( sym_tab[i] )
+ while( sym_tab[i] )
del_ele( table, i, sym_tab[i] );
}
extern void rmr_sym_dump( void *vtable )
{
Sym_tab *table;
- int i;
+ int i;
Sym_ele *eptr;
Sym_ele **sym_tab;
for( i = 0; i < table->size; i++ )
{
if( sym_tab[i] )
- for( eptr = sym_tab[i]; eptr; eptr = eptr->next )
+ for( eptr = sym_tab[i]; eptr; eptr = eptr->next )
{
if( eptr->val && eptr->class ) {
fprintf( stderr, "key=%s val@=%p\n", eptr->name, eptr->val );
} else {
- fprintf( stderr, "nkey=%d val@=%p\n", eptr->nkey, eptr->val );
+ fprintf( stderr, "nkey=%lu val@=%p\n", (unsigned long) eptr->nkey, eptr->val );
}
}
}
memset( table, 0, sizeof( *table ) );
- if((table->symlist = (Sym_ele **) malloc( sizeof( Sym_ele *) * size )))
+ if((table->symlist = (Sym_ele **) malloc( sizeof( Sym_ele *) * size )))
{
memset( table->symlist, 0, sizeof( Sym_ele *) * size );
table->size = size;
return (void *) table; /* user might want to know what the size is */
}
-/*
+/*
Delete an element given name/class or numeric key (class 0).
*/
extern void rmr_sym_del( void *vtable, const char *name, unsigned int class )
{
Sym_tab *table;
Sym_ele **sym_tab;
- Sym_ele *eptr; /* pointer into hash table */
- int hv; /* hash value */
- unsigned int nkey; // class 0, name points to integer not string
+ Sym_ele *eptr; /* pointer into hash table */
+ int hv; /* hash value */
+ uint64_t nkey; // class 0, name points to integer not string
table = (Sym_tab *) vtable;
sym_tab = table->symlist;
hv = sym_hash( name, table->size );
for(eptr=sym_tab[hv]; eptr && ! same(class, eptr->class, eptr->name, name); eptr=eptr->next );
} else {
- nkey = *((int *) name);
+ nkey = *((uint64_t *) name);
hv = nkey % table->size; // just hash the number
for( eptr=sym_tab[hv]; eptr && eptr->nkey != nkey; eptr=eptr->next );
}
/*
Delete element by numberic key.
*/
-extern void *rmr_sym_ndel( void *vtable, int key ) {
+extern void *rmr_sym_ndel( void *vtable, uint64_t key ) {
rmr_sym_del( vtable, (const char *) &key, 0 );
}
Sym_ele **sym_tab;
Sym_ele *eptr; // element from table
int hv; // hash value of key
- unsigned int nkey; // numeric key if class 0
+ uint64_t nkey; // numeric key if class 0
table = (Sym_tab *) vtable;
sym_tab = table->symlist;
hv = sym_hash( name, table->size );
for(eptr=sym_tab[hv]; eptr && ! same(class, eptr->class, eptr->name, name); eptr=eptr->next );
} else {
- nkey = *((int *) name);
+ nkey = *((uint64_t *) name);
hv = nkey % table->size; // just hash the number
for( eptr=sym_tab[hv]; eptr && eptr->nkey != nkey; eptr=eptr->next );
}
/*
Retrieve the data referenced by a numerical key.
*/
-extern void *rmr_sym_pull( void *vtable, int key ) {
+extern void *rmr_sym_pull( void *vtable, uint64_t key ) {
return rmr_sym_get( vtable, (const char *) &key, 0 );
}
-/*
+/*
Put an element with a string key into the table. Replaces the element
if it was already there. Class must be >0 and if not 1 will be forced.
(class 0 keys are numeric).
return putin( table, name, class, val );
}
-/*
- Add a new entry assuming that the key is an unsigned integer.
+/*
+ Add a new entry assuming that the key is an unsigned, 64 bit, integer.
- Returns 1 if new, 0 if existed
+ Returns 1 if new, 0 if existed
*/
-extern int rmr_sym_map( void *vtable, unsigned int key, void *val ) {
+extern int rmr_sym_map( void *vtable, uint64_t key, void *val ) {
Sym_tab *table;
table = (Sym_tab *) vtable;
return putin( table, (const char *) &key, 0, val );
}
-/*
- Dump some statistics to stderr dev. Higher level is the more info dumpped
+/*
+ Dump some statistics to stderr dev. Higher level is the more info dumpped
*/
extern void rmr_sym_stats( void *vtable, int level )
{
ch_count = 0;
if( sym_tab[i] )
{
- for( eptr = sym_tab[i]; eptr; eptr = eptr->next )
+ for( eptr = sym_tab[i]; eptr; eptr = eptr->next )
{
ch_count++;
if( level > 3 ) {
if( eptr->class ) { // a string key
fprintf( stderr, "sym: (%d) key=%s val@=%p ref=%ld mod=%lu\n", i, eptr->name, eptr->val, eptr->rcount, eptr->mcount );
} else {
- fprintf( stderr, "sym: (%d) key=%d val@=%p ref=%ld mod=%lu\n", i, eptr->nkey, eptr->val, eptr->rcount, eptr->mcount );
+ fprintf( stderr, "sym: (%d) key=%lu val@=%p ref=%ld mod=%lu\n", i, (unsigned long) eptr->nkey, eptr->val, eptr->rcount, eptr->mcount );
}
}
}
else
empty++;
- if( ch_count > max_chain )
+ if( ch_count > max_chain )
{
max_chain = ch_count;
maxi = i;
if( eptr->class ) {
fprintf( stderr, "\t%s\n", eptr->name );
} else {
- fprintf( stderr, "\t%d (numeric key)\n", eptr->nkey );
+ fprintf( stderr, "\t%lu (numeric key)\n", (unsigned long) eptr->nkey );
}
}
}
- fprintf( stderr, "sym:%ld(size) %ld(inhab) %ld(occupied) %ld(dead) %ld(maxch) %d(>2per)\n",
+ fprintf( stderr, "sym:%ld(size) %ld(inhab) %ld(occupied) %ld(dead) %ld(maxch) %d(>2per)\n",
table->size, table->inhabitants, table->size - empty, table->deaths, max_chain, twoper );
}