Add subscription marking to keep track of things you've read
[blerg.git] / database / database.c
index 585f508..e6e8707 100644 (file)
@@ -1,3 +1,6 @@
+/* Blerg is (C) 2011 The Dominion of Awesome, and is distributed under a
+ * BSD-style license.  Please see the COPYING file for details.
+ */
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
@@ -10,6 +13,7 @@
 #include <sys/file.h>
 #include <fcntl.h>
 #include "database.h"
+#include "subscription.h"
 #include "util.h"
 #include "config.h"
 
@@ -160,10 +164,17 @@ struct blerg *blerg_open(const char *name) {
                goto open_failed_meta_open;
        }
        fstat(blerg->meta_fd, &st);
-       if (st.st_size == 0) {
-               char *buf = (char *) malloc(sizeof(struct meta));
-               memset(buf, 0, sizeof(struct meta));
-               write(blerg->meta_fd, buf, sizeof(struct meta));
+       if (st.st_size < sizeof(struct meta)) {
+               // Fill the difference in size between sizeof(struct meta) and
+               // the file size with nulls.  This allows seamless upgrades as
+               // long as struct meta only adds members.
+               int len = sizeof(struct meta) - st.st_size;
+               char *buf = (char *) malloc(len);
+               memset(buf, 0, len);
+               int tmpfd = dup(blerg->meta_fd);
+               FILE* tmp = fdopen(tmpfd, "a");
+               fwrite(buf, len, 1, tmp);
+               fclose(tmp);
                free(buf);
        }
        blerg->meta = (struct meta *) mmap(NULL, sizeof(struct meta), PROT_READ | PROT_WRITE, MAP_SHARED, blerg->meta_fd, 0);
@@ -243,11 +254,12 @@ int blerg_store(struct blerg *blerg, const char *data, int len) {
        blerg->index[seg_rec].length = len;
        blerg->index[seg_rec].timestamp = time(NULL);
 
-       tag_scan(blerg->name, data, len, record);
-
        flock(blerg->data_fd, LOCK_UN);
        flock(blerg->index_fd, LOCK_UN);
 
+       tag_scan(blerg->name, data, len, record);
+       subscription_notify(blerg->name, record);
+
        return record;
 }
 
@@ -319,3 +331,11 @@ time_t blerg_get_timestamp(struct blerg *blerg, int record) {
 
        return blerg->index[seg_rec].timestamp;
 }
+
+int blerg_set_subscription_mark(struct blerg *blerg) {
+       blerg->meta->subscription_mark = subscription_count_items(blerg->name);
+}
+
+uint64_t blerg_get_subscription_mark(struct blerg *blerg) {
+       return blerg->meta->subscription_mark;
+}