summaryrefslogblamecommitdiffstats
path: root/nserver/src/protocol.c
blob: 84e73237eda86dbc5894635c12e9a5b962230000 (plain) (tree)
1
2
3
4
5
6
7
8
9
10

                     
                   
 
                       
 
                                                         
 

                                                                  
 
                                                    
                                           




                                                      
 



                                                        

                 
 
                                    


                                            
                               


                                               











                                                    
 



              
 

                       

                                                        
 
                                                                 



                              
 

                      
 


                 
            
       
             

 
                                        












                                                                         




                                   







                             
                                    
 

                                                         
 

                                                                  
 

                                                  
                                                   
 

                             
 
                        
                                     


                                             
                                   

             



              

                        

                                                         
 

                                                                  
 
                                           
                                                   
                                                  
 

                                   





              

                       

                                                         

                                    
                                                                  
 

                                                      
                                                   
 

                                     





                                               
 

                                           
 

                                    
 
                                         
                                                   


                                                                    
 

                                                   
 

                                                       
 


           
 
 






                                                     
 

                                                    
 
                        




                                  
#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;
}