Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

debugging cache

  • Loading branch information...
commit da29eafa4f4da8ad613563b06711153712791520 1 parent 20d1f95
Daniel Hjerth authored
143 src/cache.c
... ... @@ -0,0 +1,143 @@
  1 +#include <stdio.h>
  2 +#include <string.h>
  3 +#include <stdlib.h>
  4 +#include <stdint.h>
  5 +#include "main.h"
  6 +#include "cache.h"
  7 +
  8 +uint32_t
  9 +hash_fn (void *data, uint32_t len)
  10 +{
  11 + uint32_t h, x;
  12 + char *dd = (char*)data;
  13 +
  14 + for (h = x = 0; x<len; x++) {
  15 + h += dd[x];
  16 + h += (h << 10);
  17 + h ^= (h >> 6);
  18 + }
  19 +
  20 + h += (h << 3);
  21 + h ^= (h >> 11);
  22 + h += (h << 15);
  23 +
  24 + return h;
  25 +}
  26 +
  27 +int
  28 +cache_load(char *dump_path)
  29 +{
  30 + FILE *fp = fopen(dump_path, "rb");
  31 + if(!fp) {
  32 + /* There's no dump file */
  33 + return 0;
  34 + }
  35 +
  36 + /*fseek(fp, 0, SEEK_END);*/
  37 + /*int filesize = ftell(fp);*/
  38 + /*rewind(fp);*/
  39 +
  40 + st.cache_num = 0;
  41 + struct cache_entry *c = &st.cache[0];
  42 + while(
  43 + fread(&c->key_len, sizeof(int), 1, fp) &&
  44 + fread(&c->value_len, sizeof(int), 1, fp) &&
  45 + fread(&c->timestamp, sizeof(int), 1, fp)
  46 + ) {
  47 + c->key = malloc(c->key_len);
  48 + c->value = malloc(c->value_len);
  49 +
  50 + fread(c->key, c->key_len, sizeof(void*), fp);
  51 + fread(c->value, c->value_len, sizeof(void*), fp);
  52 +
  53 +
  54 + uint32_t hash_offset = hash_fn(c->key, c->key_len) & 2047;
  55 + struct hash *he = st.cachetable[hash_offset];
  56 +
  57 + do {
  58 + if (!he || !strcmp(he->key, c->key)) {
  59 + he = malloc(sizeof(struct hash));
  60 + he->key = strdup(c->key);
  61 + he->value = c;
  62 + break;
  63 + }
  64 + } while ((he = he->next));
  65 +
  66 + c = &st.cache[st.cache_num++];
  67 + }
  68 +
  69 + /* Cache was loaded */
  70 + return 1;
  71 +}
  72 +
  73 +int
  74 +cache_dump(char *dump_path)
  75 +{
  76 + FILE *fp = fopen(dump_path, "w");
  77 +
  78 + if(!fp) {
  79 + /* Could not dump! */
  80 + return 0;
  81 + }
  82 +
  83 + for(int i = 0; i<st.cache_num; i++ ) {
  84 + fwrite(&st.cache[i], sizeof(int) * 3, 1, fp);
  85 + fwrite(st.cache[i].key, st.cache[i].key_len, 1, fp);
  86 + fwrite(st.cache[i].value, st.cache[i].value_len, 1, fp);
  87 + }
  88 +
  89 + fclose(fp);
  90 +
  91 + return 1;
  92 +}
  93 +
  94 +
  95 +void *
  96 +cache_get(char *id, int ts) {
  97 + uint32_t hash_offset = hash_fn(id, strlen(id)) & 2047;
  98 +
  99 + struct hash *e = st.cachetable[hash_offset];
  100 +
  101 + if(e) {
  102 + /* There's at least 1 value on this offset */
  103 + do {
  104 + if(!strcmp(e->key, id)) {
  105 + if(ts <= e->value->timestamp) {
  106 + /* The timestamp is fresh */
  107 + return e->value;
  108 + }
  109 + }
  110 + } while((e = e->next));
  111 + }
  112 +
  113 + return 0;
  114 +}
  115 +
  116 +int
  117 +cache_set(char *id, int ts, void *data, int data_len) {
  118 + uint32_t hash_offset = hash_fn(id, strlen(id)) & 2047;
  119 + struct hash *e = st.cachetable[hash_offset];
  120 +
  121 + do {
  122 + if (!e || !strcmp(e->key, id)) {
  123 + struct cache_entry ce;
  124 + ce.key_len = strlen(id);
  125 + ce.value_len = data_len;
  126 + ce.key = strdup(id);
  127 +
  128 + ce.value = malloc(ce.value_len);
  129 + memcpy(ce.value, data, data_len);
  130 +
  131 + st.cache[st.cache_num++] = ce;
  132 +
  133 + e = malloc(sizeof(struct hash));
  134 + e->key = strdup(id);
  135 + e->value = &ce;
  136 + return 1;
  137 + }
  138 + } while ((e = e->next));
  139 +
  140 + fprintf(stderr, "could not set cache entry %s", id);
  141 + exit(1);
  142 + return 0;
  143 +}
25 src/cache.h
... ... @@ -0,0 +1,25 @@
  1 +#ifndef _ST_CACHE__H_
  2 +#define _ST_CACHE__H_
  3 +#include <stdint.h>
  4 +
  5 +struct cache_entry {
  6 + int key_len;
  7 + int value_len;
  8 + int timestamp;
  9 + char *key;
  10 + void *value;
  11 +};
  12 +
  13 +struct hash {
  14 + char *key;
  15 +
  16 + struct cache_entry *value;
  17 + struct hash *next;
  18 +};
  19 +
  20 +uint32_t hash_fn (void *data, uint32_t len);
  21 +int cache_load(char *dump_path);
  22 +int cache_dump(char *dump_path);
  23 +void * cache_get(char *id, int ts);
  24 +int cache_set(char *id, int ts, void *data, int data_len);
  25 +#endif
9 src/main.c
@@ -5,6 +5,7 @@
5 5 #include "ui.h"
6 6 #include "song.h"
7 7 #include "album.h"
  8 +#include "cache.h"
8 9
9 10 struct st_singleton _st;
10 11
@@ -17,6 +18,10 @@ static int load_data() {
17 18 exit(1);
18 19 }
19 20
  21 + st.p.cache = "/tmp/saphtune-cache.dat";
  22 +
  23 + cache_load(st.p.cache);
  24 +
20 25 st.songs = malloc(sizeof(struct song_list));
21 26 st.albums = malloc(sizeof(struct song_list));
22 27
@@ -92,7 +97,9 @@ int main(int argc, char** argv) {
92 97 exit(1);
93 98 }
94 99
95   - return ui_main(&argc, &argv);
  100 + int r = ui_main(&argc, &argv);
  101 + cache_dump(st.p.cache);
  102 + return r;
96 103 } else {
97 104 return main_from_args(argc, argv);
98 105 }
7 src/main.h
... ... @@ -1,10 +1,15 @@
1 1 #ifndef _MAIN__H_
2 2 #define _MAIN__H_
3 3 #define st _st
  4 +#include "cache.h"
4 5
5 6 extern struct st_singleton {
6 7 struct song_list *songs;
7 8 struct album_list *albums;
  9 + struct cache_entry cache[8192];
  10 +
  11 + int cache_num;
  12 + struct hash *cachetable[2048];
8 13
9 14 struct {
10 15 char *song_dir;
@@ -12,6 +17,8 @@ extern struct st_singleton {
12 17
13 18 char *song_git_dir;
14 19 char *album_git_dir;
  20 +
  21 + char *cache;
15 22 } p;
16 23 } _st;
17 24
26 src/song.c
@@ -2,6 +2,7 @@
2 2 #include <stdio.h>
3 3 #include "song.h"
4 4 #include "util.h"
  5 +#include "cache.h"
5 6 #include <string.h>
6 7
7 8 int
@@ -41,14 +42,29 @@ struct song_render_stat
41 42 song_render_analyze(char *render_path)
42 43 {
43 44 struct song_render_stat stat;
44   - FILE *fp = fopen(render_path, "rb");
45   - if (!fp) {
46   - printf("Could not detect analyze of %s\n", render_path);
  45 + char *cache_id = malloc(256);
  46 + sprintf(cache_id, "render_%s", render_path);
  47 +
  48 + int render_mtime = get_mtime(render_path);
  49 + if (!render_mtime) {
  50 + printf("Render nonexistent: %s\n", render_path);
47 51 stat.nullspace = -1;
48 52 stat.clipping = -1;
49 53 return stat;
50 54 }
51 55
  56 + struct cache_entry *e = cache_get(cache_id, render_mtime);
  57 + if (e) {
  58 + printf("Found goodies in cache!\n");
  59 + return *((struct song_render_stat*) e->value);
  60 + }
  61 +
  62 + FILE *fp = fopen(render_path, "rb");
  63 + if(!fp) {
  64 + fprintf(stderr, "Unknown error reading render of %s\n", render_path);
  65 + exit(1);
  66 + };
  67 +
52 68 /* Assume 16 bit depth, 48khz */
53 69
54 70 short nullspace_num_sec_multiplier = 10;
@@ -85,6 +101,8 @@ song_render_analyze(char *render_path)
85 101
86 102 stat.clipping = loudness > 0;
87 103
  104 + cache_set(cache_id, render_mtime, &stat, sizeof(stat));
  105 +
88 106 return stat;
89 107 }
90 108
@@ -99,7 +117,7 @@ songs_load_dir(char* dir, struct song_list *song_list) {
99 117
100 118 for(int i=0; i<files.len; i++) {
101 119 song_list->e[i] = song_create(
102   - dir,
  120 + dir,
103 121 files.e[i].d_name);
104 122 }
105 123
20 src/util.c
@@ -2,6 +2,8 @@
2 2 #include <string.h>
3 3 #include <stdio.h>
4 4 #include "util.h"
  5 +#include <sys/types.h>
  6 +#include <sys/stat.h>
5 7
6 8 struct dirent_list
7 9 dir_read_all(char *dir)
@@ -25,19 +27,23 @@ dir_read_all(char *dir)
25 27 continue;
26 28 }
27 29
28   - /*printf("%s is valid, %p, %p\n", */
29   - /*dp->d_name,*/
30   - /*strchr(dp->d_name, '\r'),*/
31   - /*strchr(dp->d_name, '\n'));*/
32   -
33 30 r.e[r.len++] = *dp;
34   -
35 31 } else {
36 32 closedir(dirp);
37 33 break;
38 34 }
39 35 }
40   -
41 36 r.e = realloc(r.e, r.len * sizeof(struct dirent));
42 37 return r;
43 38 }
  39 +
  40 +time_t get_mtime(const char *path)
  41 +{
  42 + struct stat statbuf;
  43 + if (stat(path, &statbuf) == -1) {
  44 + return 0;
  45 + }
  46 +
  47 + return statbuf.st_mtime;
  48 +}
  49 +
1  src/util.h
@@ -13,4 +13,5 @@ struct dirent_list {
13 13 };
14 14
15 15 struct dirent_list dir_read_all(char *dir);
  16 +time_t get_mtime(const char *path);
16 17 #endif

0 comments on commit da29eaf

Please sign in to comment.
Something went wrong with that request. Please try again.