ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/savestr.c
Revision: 2.10
Committed: Thu Mar 4 16:34:34 2004 UTC (20 years ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad4R2P2, rad5R0, rad3R7P2, rad3R7P1, rad4R2, rad4R1, rad4R0, rad3R6, rad3R6P1, rad3R8, rad3R9, rad4R2P1
Changes since 2.9: +2 -2 lines
Log Message:
Increased savestr() hash table size from 509 to 2039

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: savestr.c,v 2.9 2003/11/14 17:22:06 schorsch 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 standard.h
19 */
20
21 #include "copyright.h"
22
23 #include <string.h>
24 #include <stdlib.h>
25
26 #include "rtmisc.h"
27 #include "rterror.h"
28 #include "rtio.h"
29
30 #ifndef NHASH
31 #define NHASH 2039 /* hash table size (prime!) */
32 #endif
33
34 typedef struct s_head {
35 struct s_head *next; /* next in hash list */
36 int nl; /* links count */
37 } S_HEAD; /* followed by the string itself */
38
39 static S_HEAD *stab[NHASH];
40
41 #define hash(s) (shash(s)%NHASH)
42
43 #define string(sp) ((char *)((sp)+1))
44
45 #define salloc(str) (S_HEAD *)malloc(sizeof(S_HEAD)+1+strlen(str))
46
47 #define sfree(sp) free((void *)(sp))
48
49
50 char *
51 savestr(char *str) /* save a string */
52 {
53 register int hval;
54 register S_HEAD *sp;
55
56 if (str == NULL)
57 return(NULL);
58 hval = hash(str);
59 for (sp = stab[hval]; sp != NULL; sp = sp->next)
60 if (!strcmp(str, string(sp))) {
61 sp->nl++;
62 return(string(sp));
63 }
64 if ((sp = salloc(str)) == NULL) {
65 eputs("Out of memory in savestr\n");
66 quit(1);
67 }
68 strcpy(string(sp), str);
69 sp->nl = 1;
70 sp->next = stab[hval];
71 stab[hval] = sp;
72 return(string(sp));
73 }
74
75
76 void
77 freestr(char *s) /* free a string */
78 {
79 int hval;
80 register S_HEAD *spl, *sp;
81
82 if (s == NULL)
83 return;
84 hval = hash(s);
85 for (spl = NULL, sp = stab[hval]; sp != NULL; spl = sp, sp = sp->next)
86 if (s == string(sp)) {
87 if (--sp->nl > 0)
88 return;
89 if (spl != NULL)
90 spl->next = sp->next;
91 else
92 stab[hval] = sp->next;
93 sfree(sp);
94 return;
95 }
96 }
97
98
99 int
100 shash(register char *s)
101 {
102 register int h = 0;
103
104 while (*s)
105 h = (h<<1 & 0x7fff) ^ (*s++ & 0xff);
106 return(h);
107 }