presence: user core macro for hash slot index
[sip-router] / src / modules / presence / hash.c
index 43fcf05..f6abcdc 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <time.h>
 #include "../../core/mem/shm_mem.h"
 #include "../../core/hashes.h"
 #include "../../core/dprint.h"
@@ -700,10 +701,19 @@ done:
        return ret;
 }
 
-/* in-memory presentity records */
+/**
+ * ==============================
+ *  in-memory presentity records
+ * ==============================
+ */
 
 static ps_ptable_t *_ps_ptable = NULL;
 
+ps_ptable_t *ps_ptable_get(void)
+{
+       return _ps_ptable;
+}
+
 #define PS_PRESENTITY_FIELD_COPY(field) do { \
                if (pt->field.s) { \
                        ptn->field.s = p; \
@@ -718,7 +728,7 @@ static ps_ptable_t *_ps_ptable = NULL;
  */
 ps_presentity_t *ps_presentity_new(ps_presentity_t *pt, int mtype)
 {
-       int bsize = 0;
+       uint32_t bsize = 0;
        ps_presentity_t *ptn = NULL;
        char *p = NULL;
 
@@ -944,6 +954,7 @@ void ps_ptable_destroy(void)
        }
        for(i=0; i<_ps_ptable->ssize; i++) {
                lock_destroy(&_ps_ptable->slots[i].lock);
+               pt = _ps_ptable->slots[i].plist;
                while(pt!=NULL) {
                        ptn = pt->next;
                        ps_presentity_free(pt, 0);
@@ -962,7 +973,7 @@ int ps_ptable_insert(ps_presentity_t *pt)
 {
        ps_presentity_t ptc;
        ps_presentity_t *ptn = NULL;
-       int idx = 0;
+       uint32_t idx = 0;
 
        /* copy struct to fill in missing fields */
        memcpy(&ptc, pt, sizeof(ps_presentity_t));
@@ -981,7 +992,7 @@ int ps_ptable_insert(ps_presentity_t *pt)
                return -1;
        }
 
-       idx = ptn->hashid % _ps_ptable->ssize;
+       idx = core_hash_idx(ptn->hashid, _ps_ptable->ssize);
 
        lock_get(&_ps_ptable->slots[idx].lock);
        if(_ps_ptable->slots[idx].plist == NULL) {
@@ -999,11 +1010,11 @@ int ps_ptable_insert(ps_presentity_t *pt)
 /**
  *
  */
-int ps_ptable_update(ps_presentity_t *pt)
+int ps_ptable_replace(ps_presentity_t *pt)
 {
        ps_presentity_t ptc;
        ps_presentity_t *ptn = NULL;
-       int idx = 0;
+       uint32_t idx = 0;
 
        /* copy struct to fill in missing fields */
        memcpy(&ptc, pt, sizeof(ps_presentity_t));
@@ -1017,7 +1028,7 @@ int ps_ptable_update(ps_presentity_t *pt)
                ptc.ruid = pres_sruid.uid;
        }
 
-       idx = ptn->hashid % _ps_ptable->ssize;
+       idx = core_hash_idx(ptc.hashid, _ps_ptable->ssize);
 
        lock_get(&_ps_ptable->slots[idx].lock);
        ptn = _ps_ptable->slots[idx].plist;
@@ -1036,6 +1047,10 @@ int ps_ptable_update(ps_presentity_t *pt)
                ptn = ptn->next;
        }
 
+       if(ptn!=NULL) {
+               ps_presentity_free(ptn, 0);
+       }
+
        ptn = ps_presentity_new(&ptc, 0);
        if(ptn==NULL) {
                lock_release(&_ps_ptable->slots[idx].lock);
@@ -1054,6 +1069,70 @@ int ps_ptable_update(ps_presentity_t *pt)
        return 0;
 }
 
+/**
+ *
+ */
+int ps_ptable_update(ps_presentity_t *pt)
+{
+       ps_presentity_t ptc;
+       ps_presentity_t *ptn = NULL;
+       uint32_t idx = 0;
+
+       /* copy struct to fill in missing fields */
+       memcpy(&ptc, pt, sizeof(ps_presentity_t));
+
+       ptc.hashid = core_case_hash(&pt->user, &pt->domain, 0);
+
+       if(ptc.ruid.s == NULL) {
+               if(sruid_next(&pres_sruid) < 0) {
+                       return -1;
+               }
+               ptc.ruid = pres_sruid.uid;
+       }
+
+       idx = core_hash_idx(ptc.hashid, _ps_ptable->ssize);
+
+       lock_get(&_ps_ptable->slots[idx].lock);
+       ptn = _ps_ptable->slots[idx].plist;
+       while(ptn!=NULL) {
+               if(ps_presentity_match(ptn, &ptc, 0)==1) {
+                       if(ptn->next) {
+                               ptn->next->prev = ptn->prev;
+                       }
+                       if(ptn->prev) {
+                               ptn->prev->next = ptn->next;
+                       } else {
+                               _ps_ptable->slots[idx].plist = ptn->next;
+                       }
+                       break;
+               }
+               ptn = ptn->next;
+       }
+
+       if(ptn == NULL) {
+               lock_release(&_ps_ptable->slots[idx].lock);
+               return 0; /* affected items */
+       }
+       ps_presentity_free(ptn, 0);
+
+       ptn = ps_presentity_new(&ptc, 0);
+       if(ptn==NULL) {
+               lock_release(&_ps_ptable->slots[idx].lock);
+               return -1;
+       }
+
+       if(_ps_ptable->slots[idx].plist == NULL) {
+               _ps_ptable->slots[idx].plist = ptn;
+       } else {
+               _ps_ptable->slots[idx].plist->prev = ptn;
+               ptn->next = _ps_ptable->slots[idx].plist;
+               _ps_ptable->slots[idx].plist = ptn;
+       }
+       lock_release(&_ps_ptable->slots[idx].lock);
+
+       return 1; /* affected items */
+}
+
 /**
  *
  */
@@ -1061,13 +1140,13 @@ int ps_ptable_remove(ps_presentity_t *pt)
 {
        ps_presentity_t ptc;
        ps_presentity_t *ptn = NULL;
-       int idx = 0;
+       uint32_t idx = 0;
 
        /* copy struct to fill in missing fields */
        memcpy(&ptc, pt, sizeof(ps_presentity_t));
 
        ptc.hashid = core_case_hash(&pt->user, &pt->domain, 0);
-       idx = ptn->hashid % _ps_ptable->ssize;
+       idx = core_hash_idx(ptc.hashid, _ps_ptable->ssize);
 
        lock_get(&_ps_ptable->slots[idx].lock);
        ptn = _ps_ptable->slots[idx].plist;
@@ -1103,14 +1182,14 @@ ps_presentity_t *ps_ptable_get_list(str *user, str *domain)
        ps_presentity_t *ptl = NULL;
        ps_presentity_t *ptd = NULL;
        ps_presentity_t *pte = NULL;
-       int idx = 0;
+       uint32_t idx = 0;
 
        memset(&ptc, 0, sizeof(ps_presentity_t));
 
        ptc.user = *user;
        ptc.domain = *domain;
        ptc.hashid = core_case_hash(&ptc.user, &ptc.domain, 0);
-       idx = ptc.hashid % _ps_ptable->ssize;
+       idx = core_hash_idx(ptc.hashid, _ps_ptable->ssize);
 
        lock_get(&_ps_ptable->slots[idx].lock);
        ptn = _ps_ptable->slots[idx].plist;
@@ -1148,7 +1227,7 @@ ps_presentity_t *ps_ptable_get_item(str *user, str *domain, str *event, str *eta
        ps_presentity_t ptc;
        ps_presentity_t *ptn = NULL;
        ps_presentity_t *ptd = NULL;
-       int idx = 0;
+       uint32_t idx = 0;
 
        memset(&ptc, 0, sizeof(ps_presentity_t));
 
@@ -1157,7 +1236,7 @@ ps_presentity_t *ps_ptable_get_item(str *user, str *domain, str *event, str *eta
        ptc.event = *event;
        ptc.etag = *etag;
        ptc.hashid = core_case_hash(&ptc.user, &ptc.domain, 0);
-       idx = ptc.hashid % _ps_ptable->ssize;
+       idx = core_hash_idx(ptc.hashid, _ps_ptable->ssize);
 
        lock_get(&_ps_ptable->slots[idx].lock);
        ptn = _ps_ptable->slots[idx].plist;
@@ -1171,4 +1250,45 @@ ps_presentity_t *ps_ptable_get_item(str *user, str *domain, str *event, str *eta
        lock_release(&_ps_ptable->slots[idx].lock);
 
        return ptd;
+}
+
+/**
+ *
+ */
+ps_presentity_t *ps_ptable_get_expired(int eval)
+{
+       ps_presentity_t *ptn = NULL;
+       ps_presentity_t *ptl = NULL;
+       ps_presentity_t *ptd = NULL;
+       ps_presentity_t *pte = NULL;
+       int i = 0;
+
+       for(i=0; i<_ps_ptable->ssize; i++) {
+               lock_get(&_ps_ptable->slots[i].lock);
+               ptn = _ps_ptable->slots[i].plist;
+               while(ptn!=NULL) {
+                       if(ptn->expires > 0 && ptn->expires <= eval) {
+                               ptd = ps_presentity_dup(ptn, 1);
+                               if(ptd == NULL) {
+                                       break;
+                               }
+                               if(pte==NULL) {
+                                       ptl = ptd;
+                               } else {
+                                       pte->next = ptd;
+                                       ptd->prev = pte;
+                               }
+                               pte = ptd;
+                       }
+                       ptn = ptn->next;
+               }
+               lock_release(&_ps_ptable->slots[i].lock);
+       }
+
+       if(ptd==NULL && ptl != NULL) {
+               ps_presentity_list_free(ptl, 1);
+               return NULL;
+       }
+
+       return ptl;
 }
\ No newline at end of file