#include <protocol.h>
static TSTree *tst;
int sscreate(char *key)
{
check(key != NULL || strlen(key) < 1, "key invalid");
// 1. Check if key is already in the tree.
Record *rec = (Record *) TSTree_search(tst, key, strlen(key));
// If it's already there; there's nothing to do.
if (rec != NULL && rec->deleted == 0) {
return 1;
}
// If it's already there and deleted, undelete it.
if (rec != NULL && rec->deleted == 1) {
rec->deleted = 0;
// Allocate fresh Stats.
rec->st = Stats_create();
check(rec->st != NULL, "stats creation failed");
return 2;
}
// 2. Create bstring from 'key'.
bstring k = bfromcstr(key);
check(k != NULL, "key creation failed");
// 3. Allocate fresh Stats.
Stats *st = Stats_create();
check(st != NULL, "stats creation failed");
// 4. Create Record.
rec = (Record *) calloc(1, sizeof(Record));
check_mem(rec);
// 5. Initialize Record.
rec->key = k;
rec->st = st;
rec->deleted = 0;
// 6. Add Record to tree.
tst = TSTree_insert(tst, key, strlen(key), rec);
check(tst != NULL, "tstree insert failed");
return 0;
error:
return -1;
}
int ssdelete(char *key)
{
check(key != NULL || strlen(key) < 1, "key invalid");
check(tst != NULL, "tstree not initialized");
Record *rec = (Record *) TSTree_search(tst, key, strlen(key));
if (rec == NULL) {
// key does not exists.
return 0;
}
// Mark as deleted.
rec->deleted = 1;
// Free Stats.
free(rec->st);
return 0;
error:
return -1;
}
int sssample_parent(char *key, double s)
{
check(key != NULL || strlen(key) < 1, "key invalid");
check(tst != NULL, "tstree not initialized");
// 1. Try to get Record with key prefix.
Record *rec = (Record *) TSTree_search_prefix(tst, key, strlen(key));
if (rec == NULL) {
// No record with key prefix.
return 0;
}
check(rec->st != NULL, "record's st invalid");
if (rec->deleted == 1) {
// Record was deleted; nop.
return 0;
}
// 2. Sample!
Stats_sample(rec->st, s);
return 1;
error:
return -1;
}
double sssample(char *key, double s)
{
check(key != NULL || strlen(key) < 1, "key invalid");
check(tst != NULL, "tstree not initialized");
// 1. Try to get Record for key.
Record *rec = (Record *) TSTree_search(tst, key, strlen(key));
check(rec != NULL, "record not found");
check(rec->st != NULL, "record's st invalid");
check(rec->deleted != 1, "record was deleted");
// 2. Sample!
Stats_sample(rec->st, s);
// 3. Sample parent!
int rc = sssample_parent(key, s);
check(rc >= 0, "sampling parent failed");
// 4. Get mean.
double m = Stats_mean(rec->st);
return m;
error:
return -1;
}
double ssmean(char *key)
{
check(key != NULL || strlen(key) < 1, "key invalid");
check(tst != NULL, "tstree not initialized");
// 1. Try to get Record for key.
Record *rec = (Record *) TSTree_search(tst, key, strlen(key));
check(rec != NULL, "record not found");
check(rec->deleted != 1, "record was deleted");
check(rec->st != NULL, "record's st invalid");
// 2. Get mean.
double m = Stats_mean(rec->st);
return m;
error:
return -1;
}
char *ssdump(char *key)
{
check(key != NULL || strlen(key) < 1, "key invalid");
check(tst != NULL, "tstree not initialized");
// 1. create bstring from 'key'.
Record *rec = (Record *) TSTree_search(tst, key, strlen(key));
check(rec != NULL, "record not found");
check(rec->st != NULL, "stats not found for key");
check(rec->deleted != 1, "record was deleted");
// 2. get dump.
char *dstr = Stats_dump(rec->st);
check(dstr != NULL, "dump failed for key");
return dstr;
error:
return NULL;
}
// meant to be used by sslist.
void traverse_tree(void *value, void *data)
{
Record *rec = (Record *) value;
bstring bstr = (bstring) data;
check(rec != NULL, "Record is NULL");
check(rec->deleted != 1, "Record was deleted");
check(bstr != NULL, "bstr is NULL");
check(rec->key != NULL, "Record's key is NULL");
check(blength(rec->key) > 0, "Record's key is an empty string");
int rc = bconcat(bstr, rec->key);
check(rc == BSTR_OK, "bstr key concat failed");
rc = bconchar(bstr, '\n');
check(rc == BSTR_OK, "bstr newline concat failed");
error:
return;
}
char *sslist()
{
check(tst != NULL, "tstree not initialized");
// 1. Create "accumulator" string.
bstring ks_str = bfromcstr("");
check(ks_str != NULL, "error creating keys_str");
// 2. Accumulate keys into "accumulator" string.
TSTree_traverse(tst, traverse_tree, ks_str);
// 3. Return result.
return bstr2cstr(ks_str, ' ');
error:
return NULL;
}
int ssstore(char *key)
{
check(key != NULL && strlen(key) > 0, "key invalid");
check(tst != NULL, "tstree not initialized");
// 1. create bstring from 'key'.
Record *rec = (Record *) TSTree_search(tst, key, strlen(key));
check(rec != NULL, "record not found");
check(rec->st != NULL, "stats not found for key");
check(rec->deleted != 1, "record was deleted");
// 2. stringify the stats.
char *st_str = Stats_stringify(rec->st);
check(st_str != NULL, "stats stringify failed");
// 3. store stats in db.
int rc = db_store(key, st_str);
check(rc == 0, "db store failed");
return 0;
error:
return -1;
}