summaryrefslogtreecommitdiff
path: root/sys/src/cmd/replica/util.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/replica/util.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/replica/util.c')
-rwxr-xr-xsys/src/cmd/replica/util.c137
1 files changed, 137 insertions, 0 deletions
diff --git a/sys/src/cmd/replica/util.c b/sys/src/cmd/replica/util.c
new file mode 100755
index 000000000..f05b85ec7
--- /dev/null
+++ b/sys/src/cmd/replica/util.c
@@ -0,0 +1,137 @@
+#include "all.h"
+
+void*
+erealloc(void *a, int n)
+{
+ a = realloc(a, n);
+ if(a==nil)
+ sysfatal("realloc: %r");
+ return a;
+}
+
+char*
+estrdup(char *s)
+{
+ s = strdup(s);
+ if(s == nil)
+ sysfatal("strdup: %r");
+ return s;
+}
+
+void*
+emalloc(int n)
+{
+ void *a;
+
+ a = mallocz(n, 1);
+ if(a == nil)
+ sysfatal("malloc: %r");
+ return a;
+}
+
+/*
+ * Custom allocators to avoid malloc overheads on small objects.
+ * We never free these. (See below.)
+ */
+typedef struct Stringtab Stringtab;
+struct Stringtab {
+ Stringtab *link;
+ char *str;
+};
+static Stringtab*
+taballoc(void)
+{
+ static Stringtab *t;
+ static uint nt;
+
+ if(nt == 0){
+ t = malloc(64*sizeof(Stringtab));
+ if(t == 0)
+ sysfatal("out of memory");
+ nt = 64;
+ }
+ nt--;
+ return t++;
+}
+
+static char*
+xstrdup(char *s)
+{
+ char *r;
+ int len;
+ static char *t;
+ static int nt;
+
+ len = strlen(s)+1;
+ if(len >= 8192)
+ sysfatal("strdup big string");
+
+ if(nt < len){
+ t = malloc(8192);
+ if(t == 0)
+ sysfatal("out of memory");
+ nt = 8192;
+ }
+ r = t;
+ t += len;
+ nt -= len;
+ strcpy(r, s);
+ return r;
+}
+
+/*
+ * Return a uniquely allocated copy of a string.
+ * Don't free these -- they stay in the table for the
+ * next caller who wants that particular string.
+ * String comparison can be done with pointer comparison
+ * if you know both strings are atoms.
+ */
+static Stringtab *stab[1024];
+
+static uint
+hash(char *s)
+{
+ uint h;
+ uchar *p;
+
+ h = 0;
+ for(p=(uchar*)s; *p; p++)
+ h = h*37 + *p;
+ return h;
+}
+
+char*
+atom(char *str)
+{
+ uint h;
+ Stringtab *tab;
+
+ h = hash(str) % nelem(stab);
+ for(tab=stab[h]; tab; tab=tab->link)
+ if(strcmp(str, tab->str) == 0)
+ return tab->str;
+
+ tab = taballoc();
+ tab->str = xstrdup(str);
+ tab->link = stab[h];
+ stab[h] = tab;
+ return tab->str;
+}
+
+char*
+unroot(char *path, char *root)
+{
+ int len;
+ char *s;
+
+ len = strlen(root);
+ while(len >= 1 && root[len-1]=='/')
+ len--;
+ if(strncmp(path, root, len)==0 && (path[len]=='/' || path[len]=='\0')){
+ s = path+len;
+ while(*s == '/')
+ s++;
+ return s;
+ }
+ return path;
+}