ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/savestr.c
Revision: 2.15
Committed: Mon Jun 23 19:55:51 2025 UTC (11 days, 18 hours ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 2.14: +5 -1 lines
Log Message:
perf: Added larger hash table when !SMLMEM

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: savestr.c,v 2.14 2023/06/08 17:48:01 greg Exp $";
3 #endif
4 /*
5 * savestr.c - routines for efficient string storage.
6 *
7 * Savestr(s) stores a shared read-only string.
8 * Freestr(s) indicates a client is finished with a string.
9 * All strings must be null-terminated. There is
10 * no imposed length limit.
11 * Strings stored with savestr(s) can be equated
12 * reliably using their pointer values.
13 * Calls to savestr(s) and freestr(s) should be
14 * balanced (obviously). The last call to freestr(s)
15 * frees memory associated with the string; it should
16 * never be referenced again.
17 *
18 * External symbols declared in rtio.h
19 */
20
21 #include "copyright.h"
22
23 #include <stdlib.h>
24
25 #include "rterror.h"
26 #include "rtio.h"
27
28 #ifndef NHASH
29 #ifdef SMLMEM
30 #define NHASH 2039 /* hash table size (prime!) */
31 #else
32 #define NHASH 17117 /* hash table size (prime!) */
33 #endif
34 #endif
35
36 typedef struct s_head {
37 struct s_head *next; /* next in hash list */
38 int nl; /* links count */
39 } S_HEAD; /* followed by the string itself */
40
41 static S_HEAD *stab[NHASH];
42
43 #define hash(s) (shash(s)%NHASH)
44
45 #define string(sp) ((char *)((sp)+1))
46
47 #define salloc(str) (S_HEAD *)malloc(sizeof(S_HEAD)+1+strlen(str))
48
49 #define sfree(sp) free((void *)(sp))
50
51
52 char *
53 savestr(const char *str) /* save a string */
54 {
55 int hval;
56 S_HEAD *sp;
57
58 if (str == NULL)
59 return(NULL);
60 if (!*str)
61 return "";
62 hval = hash(str);
63 for (sp = stab[hval]; sp != NULL; sp = sp->next)
64 if (!strcmp(str, string(sp))) {
65 sp->nl++;
66 return(string(sp));
67 }
68 if ((sp = salloc(str)) == NULL) {
69 eputs("Out of memory in savestr\n");
70 quit(1);
71 }
72 strcpy(string(sp), str);
73 sp->nl = 1;
74 sp->next = stab[hval];
75 stab[hval] = sp;
76 return(string(sp));
77 }
78
79
80 void
81 freestr(char *s) /* free a string */
82 {
83 int hval;
84 S_HEAD *spl, *sp;
85
86 if (s == NULL || !*s)
87 return;
88 hval = hash(s);
89 for (spl = NULL, sp = stab[hval]; sp != NULL; spl = sp, sp = sp->next)
90 if (s == string(sp)) {
91 if (--sp->nl > 0)
92 return;
93 if (spl != NULL)
94 spl->next = sp->next;
95 else
96 stab[hval] = sp->next;
97 sfree(sp);
98 return;
99 }
100 }
101
102
103 int
104 shash(const char *s)
105 {
106 int h = 0;
107
108 while (*s)
109 h = (h<<1 & 0x7fff) ^ (*s++ & 0xff);
110 return(h);
111 }