commit e6baea87a494775c0f245e77ca254c395db56d54
parent dbaa680f3819391269a520637d013d145dce3177
Author: quantumish <freifeld.david@gmail.com>
Date: Sun, 19 Nov 2023 15:44:00 -0500
Add README, tweak language
Diffstat:
12 files changed, 82 insertions(+), 178 deletions(-)
diff --git a/http.c b/http.c
@@ -22,7 +22,7 @@
#include "utils/log.h"
#include "utils/time.h"
-#include "utils/shitvec.h"
+#include "utils/vec.h"
#include "utils/sync.h"
#include "utils/html.h"
#include "utils/compress.h"
@@ -48,7 +48,7 @@ response_t serve_error(enum StatusCode c) {
return r;
}
-shitvec_t paths;
+vec_t paths;
hashmap_t path_redirs;
char* get_file_ext(char* filename) {
@@ -79,9 +79,9 @@ response_t serve_file(request_t* req) {
char* hdr;
if ((hdr = hashmap_get(&req->headers, "Accept"))) {
ok = false;
- shitvec_t mtypes = hdr_parse_accept(hdr);
+ vec_t mtypes = hdr_parse_accept(hdr);
for (int j = 0; j < mtypes.vec_sz; j++) {
- struct req_mimetype* a_mtype = shitvec_get(&mtypes, j);
+ struct req_mimetype* a_mtype = vec_get(&mtypes, j);
// TODO doesn't handle stuff like image/* (is that even allowed?)
if (strcmp(a_mtype->item, mtype) == 0 || strcmp(a_mtype->item, "*/*") == 0) {
ok = true;
@@ -95,9 +95,9 @@ response_t serve_file(request_t* req) {
if (ok && (hdr = hashmap_get(&req->headers, "Accept-Encoding"))) {
ok = false;
- shitvec_t mtypes = hdr_parse_accept(hdr); // abuse of this func
+ vec_t mtypes = hdr_parse_accept(hdr); // abuse of this func
for (int j = 0; j < mtypes.vec_sz; j++) {
- struct req_mimetype* a_mtype = shitvec_get(&mtypes, j);
+ struct req_mimetype* a_mtype = vec_get(&mtypes, j);
if (strcmp(a_mtype->item, "gzip") == 0) {
resp_add_hdr(&r, "Content-Encoding", "gzip");
buf = gzip_compress(buf, &bufsize);
@@ -152,7 +152,7 @@ response_t make_response (request_t* req, int pfd) {
strcpy(req->path, mapped_path);
}
- if (shitvec_check(&paths, req->path, (sv_cmp_t)strcmp) == -1) {
+ if (vec_check(&paths, req->path, (sv_cmp_t)strcmp) == -1) {
return serve_error(NotFound);
}
@@ -192,7 +192,7 @@ void* handle_conn(int ns, int pfd) {
}
}
-int list_files_sv(shitvec_t* sv, char* base) {
+int list_files_sv(vec_t* sv, char* base) {
char path[MAX_PATH_LEN] = "/";
struct dirent* dp;
DIR* dir = opendir(base);
@@ -203,7 +203,7 @@ int list_files_sv(shitvec_t* sv, char* base) {
strcpy(path+1, base);
strcat(path, "/");
strcat(path, dp->d_name);
- shitvec_push(sv, strchr(path+1, '/'));
+ vec_push(sv, strchr(path+1, '/'));
list_files_sv(sv, path+1);
}
}
@@ -247,7 +247,7 @@ int main() {
name.sin_port = htons(portnum);
}
- paths = shitvec_new(MAX_PATH_LEN);
+ paths = vec_new(MAX_PATH_LEN);
path_redirs = hashmap_new(MAX_PATH_LEN, MAX_PATH_LEN);
path_redirs.vark = true;
hashmap_set(&path_redirs, "/", "/index.html");
@@ -266,7 +266,7 @@ int main() {
int namelen;
struct sockaddr_in client;
- shitvec_t conns = shitvec_new(sizeof(struct conn_ctxt));
+ vec_t conns = vec_new(sizeof(struct conn_ctxt));
while (true) {
int* ptr = channel_try_recv(&listen_chan);
if (ptr != NULL) {
@@ -281,15 +281,15 @@ int main() {
exit(0);
}
struct conn_ctxt ctxt = {.fd = pfds[0], .pid = pid };
- shitvec_push(&conns, &ctxt);
+ vec_push(&conns, &ctxt);
}
for (int i = 0; i < conns.vec_sz; i++) {
- struct conn_ctxt* ctxt = shitvec_get(&conns, i);
+ struct conn_ctxt* ctxt = vec_get(&conns, i);
char msg[8] = {0};
if (read(ctxt->fd, &msg, 8) != 8 || strcmp(msg, "profile") != 0) continue;
struct profile_node prof_res = profile_res_new();
while(true) {
- shitvec_t stack = profile(ctxt->pid);
+ vec_t stack = profile(ctxt->pid);
profile_proc_stack(&prof_res, &stack);
usleep(3);
if (read(ctxt->fd, &msg, 5) == 5 && strcmp(msg, "stop") == 0) break;
diff --git a/http/request.c b/http/request.c
@@ -26,12 +26,12 @@ enum http_method method_enum(char* p) {
/* struct parse_qvals_res { */
/* enum parse_qval_err err; */
/* union { */
-/* shitvec_t items; */
+/* vec_t items; */
/* } data; */
/* }; */
-/* shitvec_t parse_qvalues(char* str) { */
+/* vec_t parse_qvalues(char* str) { */
/* } */
@@ -57,8 +57,8 @@ int cmp_r_mimetype(const void* a, const void* b) {
}
// TODO handle parse errors
-shitvec_t hdr_parse_accept(char* val) {
- shitvec_t mimetypes = shitvec_new(sizeof(struct req_mimetype));
+vec_t hdr_parse_accept(char* val) {
+ vec_t mimetypes = vec_new(sizeof(struct req_mimetype));
char* start = strtok(val, ",");
char* next;
do {
@@ -76,9 +76,9 @@ shitvec_t hdr_parse_accept(char* val) {
if (qptr != NULL) strncpy(mtype.item, start, qptr-start);
else if (next != NULL) strncpy(mtype.item, start, next-start);
else strcpy(mtype.item, start);
- shitvec_push(&mimetypes, &mtype);
+ vec_push(&mimetypes, &mtype);
} while ((start = next));
- shitvec_sort(&mimetypes, cmp_r_mimetype);
+ vec_sort(&mimetypes, cmp_r_mimetype);
return mimetypes;
}
@@ -142,22 +142,22 @@ void test_method_str_to_enum() {
void test_hdr_parse_accept() {
char hdr[MAX_HEADER_VALUE] = "text/html,application/xml;q=0.9,image/webp,*/*;q=0.8";
- shitvec_t mtypes = hdr_parse_accept(hdr);
+ vec_t mtypes = hdr_parse_accept(hdr);
assert_size_eq(mtypes.vec_sz, 4);
- struct req_mimetype* mtype = shitvec_get(&mtypes, 0);
+ struct req_mimetype* mtype = vec_get(&mtypes, 0);
assert_str_eq("text/html", mtype->item);
assert_float_eq(1.0, mtype->q);
- mtype = shitvec_get(&mtypes, 1);
+ mtype = vec_get(&mtypes, 1);
assert_str_eq("image/webp", mtype->item);
assert_float_eq(1.0, mtype->q);
- mtype = shitvec_get(&mtypes, 2);
+ mtype = vec_get(&mtypes, 2);
assert_str_eq("application/xml", mtype->item);
assert_float_eq(0.9, mtype->q);
- mtype = shitvec_get(&mtypes, 3);
+ mtype = vec_get(&mtypes, 3);
assert_str_eq("*/*", mtype->item);
assert_float_eq(0.8, mtype->q);
}
diff --git a/http/request.h b/http/request.h
@@ -1,7 +1,7 @@
#ifndef REQUEST_H
#define REQUEST_H
-#include "../utils/shitvec.h"
+#include "../utils/vec.h"
#include "../utils/hashmap.h"
enum http_method {
@@ -49,7 +49,7 @@ struct req_mimetype {
/* char value[MAX_HEADER_VALUE]; */
/* } header_line_t; */
-shitvec_t hdr_parse_accept(char* val);
+vec_t hdr_parse_accept(char* val);
typedef struct request {
char* buf;
diff --git a/phf.py b/phf.py
@@ -1,36 +1,42 @@
import random
-inputs = ["GET", "HEAD", "POST", "PUT", "DELETE",
- "CONNECT", "OPTIONS", "TRACE"]
+# inputs = ["GET", "HEAD", "POST", "PUT", "DELETE",
+# "CONNECT", "OPTIONS", "TRACE"]
-int_inputs = [int.from_bytes(bytes(i, 'ascii'), 'little') for i in inputs]
+# int_inputs = [int.from_bytes(bytes(i, 'ascii'), 'little') for i in inputs]
-answers = list(range(8))
+# answers = list(range(8))
+
+inps = [random.randrange(2**32) for i in range(100000)]
def is_phf(h, inputs):
return len({h(x) for x in inputs}) == len(inputs)
-print(next(m for m in range(9, 2**32) if is_phf(lambda x: x % m, int_inputs)))
+def colls(h, inputs):
+ return len({h(x) for x in inputs})
+
+# print(next(m for m in range(9, 2**32) if is_phf(lambda x: x % m, int_inputs)))
def h(x, c):
m = (x * c) % 2**32
- return m >> 28
+ return m
-out = [0]*8
-idxs = list(h(x, 0x1b8b6e6d) for x in int_inputs)
+# out = [0]*8
+# idxs = list(h(x, 0x1b8b6e6d) for x in int_inputs)
-for i, idx in enumerate(idxs):
- out[idx] = answers[i]
+# for i, idx in enumerate(idxs):
+# out[idx] = answers[i]
-print([inputs[i] for i in out])
-print(list(out[h(x, 0x1b8b6e6d)] for x in int_inputs))
+# print([inputs[i] for i in out])
+# print(list(out[h(x, 0x1b8b6e6d)] for x in int_inputs))
-# best = float('inf')
-# while best >= len(int_inputs):
-# c = random.randrange(2**32)
-# max_idx = max(h(x, c) for x in int_inputs)
-# if max_idx < best and is_phf(lambda x: h(x, c), int_inputs):
-# print(max_idx, hex(c))
-# best = max_idx
+best = float('-inf')
+while best < len(inps):
+ c = random.randrange(2**32)
+ # max_idx = max(h(x, c) for x in int_inputs)
+ cls = colls(lambda x: h(x, c), inps)
+ if cls > best:
+ print(cls, hex(c))
+ best = cls
diff --git a/utils/html.c b/utils/html.c
@@ -3,9 +3,9 @@
html_t html_new() {
html_t out;
- out._buf = shitvec_new(sizeof(char));
+ out._buf = vec_new(sizeof(char));
html_body_t body;
- body.content = shitvec_new(sizeof(html_fc_t));
+ body.content = vec_new(sizeof(html_fc_t));
out.body = body;
return out;
}
@@ -25,12 +25,12 @@ html_fc_t html_h1_new(char* content) {
}
void html_body_add(html_body_t* body, html_fc_t fc) {
- shitvec_push(&body->content, &fc);
+ vec_push(&body->content, &fc);
}
-void c_sv_pushs(shitvec_t* sv, char* str) {
+void c_sv_pushs(vec_t* sv, char* str) {
for (int i = 0; str[i] != '\0'; i++) {
- shitvec_push(sv, &str[i]);
+ vec_push(sv, &str[i]);
}
}
@@ -38,7 +38,7 @@ char* html_render(html_t* html) {
c_sv_pushs(&html->_buf, "<!DOCTYPE html><html>");
c_sv_pushs(&html->_buf, "<body>");
for (int i = 0; i < html->body.content.vec_sz; i++) {
- html_fc_t* elem = shitvec_get(&html->body.content, i);
+ html_fc_t* elem = vec_get(&html->body.content, i);
switch (elem->type) {
case HTML_TEXT:
@@ -58,7 +58,7 @@ char* html_render(html_t* html) {
}
c_sv_pushs(&html->_buf, "</body>");
c_sv_pushs(&html->_buf, "</html>");
- shitvec_push(&html->_buf, "\0");
+ vec_push(&html->_buf, "\0");
return html->_buf.arr;
}
diff --git a/utils/html.h b/utils/html.h
@@ -1,7 +1,7 @@
#ifndef HTML_H
#define HTML_H
-#include "shitvec.h"
+#include "vec.h"
enum html_fc_type {
HTML_TEXT,
@@ -29,15 +29,15 @@ typedef struct base {
} html_base_t;
typedef struct head {
- shitvec_t meta;
+ vec_t meta;
} html_head_t;
typedef struct body {
- shitvec_t content;
+ vec_t content;
} html_body_t;
typedef struct html {
- shitvec_t _buf;
+ vec_t _buf;
html_body_t body;
} html_t;
diff --git a/utils/profile.c b/utils/profile.c
@@ -19,8 +19,8 @@
#include "log.h"
#include "profile.h"
-shitvec_t profile(pid_t tid) {
- shitvec_t stack = shitvec_new(MAX_SYMLEN);
+vec_t profile(pid_t tid) {
+ vec_t stack = vec_new(MAX_SYMLEN);
errno = 0;
ptrace(PTRACE_ATTACH, tid);
kill(tid, SIGSTOP);
@@ -33,7 +33,7 @@ shitvec_t profile(pid_t tid) {
unw_word_t offset;
char fname[MAX_SYMLEN] = {0};
int resp = unw_get_proc_name(&c, fname, sizeof(fname), &offset);
- shitvec_push(&stack, fname);
+ vec_push(&stack, fname);
} while(unw_step(&c) > 0);
_UPT_resume(as, &c, ui);
_UPT_destroy(ui);
@@ -45,7 +45,7 @@ shitvec_t profile(pid_t tid) {
struct profile_node profile_node_new(char* name) {
struct profile_node out = {
- .children = shitvec_new(sizeof(struct profile_node)),
+ .children = vec_new(sizeof(struct profile_node)),
.samples = 0,
.symbol = {0}
};
@@ -63,18 +63,18 @@ int cmp_prof_node(void* _a, void* _b) {
return strcmp(a->symbol, b->symbol);
}
-void profile_proc_stack(struct profile_node* prof_res, shitvec_t* stack) {
+void profile_proc_stack(struct profile_node* prof_res, vec_t* stack) {
if (stack->vec_sz == 0) return;
struct profile_node* node = prof_res;
for (int i = stack->vec_sz-1; i > 0; i--) {
- char* sym = shitvec_get(stack, i);
- int index = shitvec_check(&node->children, sym, cmp_prof_node);
+ char* sym = vec_get(stack, i);
+ int index = vec_check(&node->children, sym, cmp_prof_node);
if (index == -1) {
struct profile_node new = profile_node_new(sym);
- shitvec_push(&node->children, &new);
+ vec_push(&node->children, &new);
index = node->children.vec_sz - 1;
}
- node = shitvec_get(&node->children, index);
+ node = vec_get(&node->children, index);
node->samples += 1;
}
}
@@ -86,6 +86,6 @@ void profile_dump(struct profile_node* prof_res, int indent) {
printf("%s (%d) \n", node->symbol, node->samples);
}
for (int i = 0; i < node->children.vec_sz; i++) {
- profile_dump(shitvec_get(&node->children, i), indent+1);
+ profile_dump(vec_get(&node->children, i), indent+1);
}
}
diff --git a/utils/profile.h b/utils/profile.h
@@ -3,19 +3,19 @@
#include <sys/types.h>
-#include "shitvec.h"
+#include "vec.h"
#define MAX_SYMLEN 32
-shitvec_t profile(pid_t pid);
+vec_t profile(pid_t pid);
struct profile_node {
char symbol[MAX_SYMLEN];
unsigned int samples;
- shitvec_t children;
+ vec_t children;
};
struct profile_node profile_res_new();
-void profile_proc_stack(struct profile_node* prof_res, shitvec_t* stack);
+void profile_proc_stack(struct profile_node* prof_res, vec_t* stack);
void profile_dump(struct profile_node* prof_res, int indent);
#endif
diff --git a/utils/shitvec.c b/utils/shitvec.c
@@ -1,73 +0,0 @@
-#include <stdlib.h>
-#include <string.h>
-
-#include "shitvec.h"
-
-shitvec_t shitvec_new(size_t e_sz) {
- shitvec_t sv;
- sv.alloc_sz = SHITVEC_INIT_SZ;
- sv.vec_sz = 0;
- sv.e_sz = e_sz;
- sv.arr = malloc(sv.alloc_sz);
- memset(sv.arr, 0, sv.alloc_sz);
- return sv;
-}
-
-void* shitvec_get(shitvec_t* sv, size_t index) {
- if (index > sv->vec_sz) return 0x0;
- return sv->arr+(sv->e_sz * index);
-}
-
-void* shitvec_last(shitvec_t* sv) {
- return shitvec_get(sv, sv->vec_sz-1);
-}
-
-void shitvec_push(shitvec_t* sv, void* item) {
- // FIXME sketchy af
- if ((sv->arr+(2 * sv->e_sz * sv->vec_sz)) > sv->arr+sv->alloc_sz) {
- sv->arr = realloc(sv->arr, sv->alloc_sz * 2);
- sv->alloc_sz *= 2;
- }
- memcpy(sv->arr+(sv->vec_sz * sv->e_sz), item, sv->e_sz);
- sv->vec_sz += 1;
-}
-
-void shitvec_subpush(shitvec_t* sv, void* item, size_t sz) {
- sv->vec_sz += 1;
- if ((sv->arr+(sv->e_sz * sv->vec_sz)) > sv->arr+sv->alloc_sz) {
- sv->arr = realloc(sv->arr, sv->alloc_sz * 2);
- }
- memcpy(sv->arr+(sv->vec_sz * sv->e_sz), item, sz);
-}
-
-int shitvec_check(shitvec_t* sv, void* item, sv_cmp_t cmp) {
- for (size_t i = 0; i < sv->vec_sz; i++) {
- if (cmp(sv->arr+(i*sv->e_sz), item) == 0) {
- return i;
- }
- }
- return -1;
-}
-
-void shitvec_sort(shitvec_t* sv, int(*cmp)(const void*, const void*)) {
- qsort(sv->arr, sv->vec_sz, sv->e_sz, cmp);
-}
-
-void shitvec_free(shitvec_t* sv) {
- free(sv->arr);
-}
-
-#ifdef TEST
-#include "../test.h"
-
-void test_shitvec_sanity() {
- shitvec_t sv = shitvec_new(8);
- shitvec_push(&sv, "whee");
- shitvec_push(&sv, "whoo");
- assert_str_eq("whee", shitvec_get(&sv, 0));
- assert_str_eq("whoo", shitvec_get(&sv, 1));
- assert_size_eq(2, sv.vec_sz);
- assert_size_eq(8, sv.e_sz);
- assert_bool(shitvec_check(&sv, "whoo", (sv_cmp_t)strcmp));
-};
-#endif
diff --git a/utils/shitvec.h b/utils/shitvec.h
@@ -1,29 +0,0 @@
-#ifndef SHITVEC_H
-#define SHITVEC_H
-
-#include <stddef.h>
-#include <stdbool.h>
-
-#define SHITVEC_INIT_SZ 1024
-
-typedef struct shitvec {
- void* arr;
- size_t e_sz;
- size_t alloc_sz;
- size_t vec_sz;
-} shitvec_t;
-
-typedef int(*sv_cmp_t)(void*, void*);
-
-shitvec_t shitvec_new(size_t e_sz);
-void* shitvec_get(shitvec_t* sv, size_t index);
-void* shitvec_last(shitvec_t* sv);
-void shitvec_push(shitvec_t* sv, void* item);
-void shitvec_subpush(shitvec_t* sv, void* item, size_t sz);
-int shitvec_check(shitvec_t* sv, void* item, sv_cmp_t cmp);
-void shitvec_sort(shitvec_t* sv, int(*cmp)(const void*, const void*));
-void shitvec_free(shitvec_t* sv);
-
-#endif
-
-
diff --git a/utils/sync.c b/utils/sync.c
@@ -5,14 +5,14 @@ channel_t channel_new(size_t msg_sz) {
channel_t out;
out.msg_sz = msg_sz;
pthread_mutex_init(&out.mutex, NULL);
- out.queue = shitvec_new(msg_sz);
+ out.queue = vec_new(msg_sz);
out.sz = 0;
return out;
}
void channel_push(channel_t* chan, void* msg) {
pthread_mutex_lock(&chan->mutex);
- shitvec_push(&chan->queue, msg);
+ vec_push(&chan->queue, msg);
pthread_mutex_unlock(&chan->mutex);
__atomic_fetch_add(&chan->sz, 1, __ATOMIC_RELAXED);
}
@@ -20,7 +20,7 @@ void channel_push(channel_t* chan, void* msg) {
void* channel_pop(channel_t* chan) {
void* out;
pthread_mutex_lock(&chan->mutex);
- out = shitvec_get(&chan->queue, chan->queue.vec_sz-1);
+ out = vec_get(&chan->queue, chan->queue.vec_sz-1);
chan->queue.vec_sz -= 1;
pthread_mutex_unlock(&chan->mutex);
__atomic_fetch_sub(&chan->sz, 1, __ATOMIC_RELAXED);
diff --git a/utils/sync.h b/utils/sync.h
@@ -2,11 +2,11 @@
#define UTIL_SYNC_H
#include <pthread.h>
-#include "shitvec.h"
+#include "vec.h"
typedef struct channel {
pthread_mutex_t mutex;
- shitvec_t queue;
+ vec_t queue;
size_t msg_sz;
size_t sz;
} channel_t;