Changed the fnetnode peer list to a btree.
authorFredrik Tolf <fredrik@dolda2000.com>
Sun, 24 Feb 2008 04:04:18 +0000 (05:04 +0100)
committerFredrik Tolf <fredrik@dolda2000.com>
Sun, 24 Feb 2008 04:04:18 +0000 (05:04 +0100)
daemon/filenet.c
daemon/filenet.h
daemon/fnet-dc.c
daemon/ui.c

index 82ed1d2..a74f454 100644 (file)
@@ -30,6 +30,8 @@
 #include "utils.h"
 #include "net.h"
 
+static void freepeer(struct fnetpeer *peer);
+
 static struct fnet *networks = NULL;
 struct fnetnode *fnetnodes = NULL;
 int numfnetnodes = 0;
@@ -76,6 +78,16 @@ void getfnetnode(struct fnetnode *fn)
 #endif
 }
 
+static void freepeers(struct btree *n)
+{
+    if(n == NULL)
+       return;
+    freepeers(n->l);
+    freepeers(n->r);
+    freepeer(n->d);
+    free(n);
+}
+
 void putfnetnode(struct fnetnode *fn)
 {
     struct fnetnode *cur;
@@ -102,8 +114,7 @@ void putfnetnode(struct fnetnode *fn)
        fn->fnet->destroy(fn);
     while(fn->args != NULL)
        freewcspair(fn->args, &fn->args);
-    while(fn->peers != NULL)
-       fnetdelpeer(fn->peers);
+    freepeers(fn->peers);
     if(fn->mynick != NULL)
        free(fn->mynick);
     if(fn->pubid != NULL)
@@ -317,6 +328,11 @@ void fnetpeerunset(struct fnetpeer *peer, wchar_t *id)
     putdatum(peer, datum);
 }
 
+static int peercmpid(void *a, void *b)
+{
+    return(wcscmp(((struct fnetpeer *)a)->id, ((struct fnetpeer *)b)->id));
+}
+
 struct fnetpeer *fnetaddpeer(struct fnetnode *fn, wchar_t *id, wchar_t *nick)
 {
     struct fnetpeer *new;
@@ -328,30 +344,18 @@ struct fnetpeer *fnetaddpeer(struct fnetnode *fn, wchar_t *id, wchar_t *nick)
     new->flags.w = 0;
     new->dinum = 0;
     new->peerdi = NULL;
-    new->next = fn->peers;
-    new->prev = NULL;
-    if(fn->peers != NULL)
-       fn->peers->prev = new;
-    fn->peers = new;
+    bbtreeput(&fn->peers, new, peercmpid);
     fn->numpeers++;
     CBCHAINDOCB(fn, fnetnode_ac, fn, L"numpeers");
     CBCHAINDOCB(fn, fnetpeer_new, fn, new);
     return(new);
 }
 
-void fnetdelpeer(struct fnetpeer *peer)
+static void freepeer(struct fnetpeer *peer)
 {
     int i;
     
-    if(peer->next != NULL)
-       peer->next->prev = peer->prev;
-    if(peer->prev != NULL)
-       peer->prev->next = peer->next;
-    if(peer->fn->peers == peer)
-       peer->fn->peers = peer->next;
     peer->fn->numpeers--;
-    CBCHAINDOCB(peer->fn, fnetnode_ac, peer->fn, L"numpeers");
-    CBCHAINDOCB(peer->fn, fnetpeer_del, peer->fn, peer);
     free(peer->id);
     free(peer->nick);
     for(i = 0; i < peer->dinum; i++)
@@ -365,12 +369,43 @@ void fnetdelpeer(struct fnetpeer *peer)
     free(peer);
 }
 
+void fnetdelpeer(struct fnetpeer *peer)
+{
+    bbtreedel(&peer->fn->peers, peer, peercmpid);
+    CBCHAINDOCB(peer->fn, fnetnode_ac, peer->fn, L"numpeers");
+    CBCHAINDOCB(peer->fn, fnetpeer_del, peer->fn, peer);
+    freepeer(peer);
+}
+
+void fnetpeerdm(struct fnetnode *fn)
+{
+    struct btree *new;
+    struct fnetpeer *peer;
+    int intact;
+    
+    new = NULL;
+    intact = 1;
+    for(peer = btreeiter(fn->peers); peer != NULL; peer = btreeiter(NULL)) {
+       if(!peer->flags.b.delete) {
+           bbtreeput(&new, peer, peercmpid);
+       } else {
+           intact = 0;
+           CBCHAINDOCB(peer->fn, fnetpeer_del, peer->fn, peer);
+           freepeer(peer);
+       }
+    }
+    btreefree(fn->peers);
+    fn->peers = new;
+    if(!intact)
+       CBCHAINDOCB(peer->fn, fnetnode_ac, peer->fn, L"numpeers");
+}
+
 struct fnetpeer *fnetfindpeer(struct fnetnode *fn, wchar_t *id)
 {
-    struct fnetpeer *cur;
+    struct fnetpeer key;
     
-    for(cur = fn->peers; (cur != NULL) && wcscmp(cur->id, id); cur = cur->next);
-    return(cur);
+    key.id = id;
+    return(btreeget(fn->peers, &key, peercmpid));
 }
 
 int fnetsetnick(struct fnetnode *fn, wchar_t *newnick)
index d6a73dd..8d2c8db 100644 (file)
@@ -75,7 +75,6 @@ struct fnetpeerdi
 
 struct fnetpeer
 {
-    struct fnetpeer *next, *prev;
     struct fnetnode *fn;
     wchar_t *id;
     wchar_t *nick;
@@ -107,7 +106,7 @@ struct fnetnode
     wchar_t *owner;
     struct fnet *fnet;
     struct fnetpeerdatum *peerdata;
-    struct fnetpeer *peers;
+    struct btree *peers;
     struct wcspair *args;
     int numpeers;
     void *data;
@@ -133,6 +132,7 @@ void putfnetnode(struct fnetnode *fn);
 void killfnetnode(struct fnetnode *fn);
 struct fnetpeer *fnetaddpeer(struct fnetnode *fn, wchar_t *id, wchar_t *nick);
 void fnetdelpeer(struct fnetpeer *peer);
+void fnetpeerdm(struct fnetnode *fn);
 struct fnetpeer *fnetfindpeer(struct fnetnode *fn, wchar_t *id);
 void fnetpeersetstr(struct fnetpeer *peer, wchar_t *id, wchar_t *value);
 void fnetpeersetnum(struct fnetpeer *peer, wchar_t *id, int value);
index c4d81c6..f03458f 100644 (file)
@@ -905,10 +905,10 @@ static void cmd_nicklist(struct socket *sk, struct fnetnode *fn, char *cmd, char
     struct dchub *hub;
     char *p;
     wchar_t *buf;
-    struct fnetpeer *peer, *npeer;
+    struct fnetpeer *peer;
     
     hub = fn->data;
-    for(peer = fn->peers; peer != NULL; peer = peer->next)
+    for(peer = btreeiter(fn->peers); peer != NULL; peer = btreeiter(NULL))
        peer->flags.b.delete = 1;
     while((p = strstr(args, "$$")) != NULL)
     {
@@ -924,12 +924,7 @@ static void cmd_nicklist(struct socket *sk, struct fnetnode *fn, char *cmd, char
        }
        args = p + 2;
     }
-    for(peer = fn->peers; peer != NULL; peer = npeer)
-    {
-       npeer = peer->next;
-       if(peer->flags.b.delete)
-           fnetdelpeer(peer);
-    }
+    fnetpeerdm(fn);
     hubhandleaction(sk, fn, cmd, args);
 }
 
@@ -941,7 +936,7 @@ static void cmd_oplist(struct socket *sk, struct fnetnode *fn, char *cmd, char *
     struct fnetpeer *peer;
     
     hub = fn->data;
-    for(peer = fn->peers; peer != NULL; peer = peer->next)
+    for(peer = btreeiter(fn->peers); peer != NULL; peer = btreeiter(NULL))
        peer->flags.b.op = 0;
     while((p = strstr(args, "$$")) != NULL)
     {
index a7717ea..9c63071 100644 (file)
@@ -694,7 +694,7 @@ static void cmd_lspeers(struct socket *sk, struct uidata *data, int argc, wchar_
 {
     int i;
     struct fnetnode *fn;
-    struct fnetpeer *peer;
+    struct fnetpeer *peer, *npeer;
     
     haveargs(2);
     if((fn = findfnetnode(wcstol(argv[1], NULL, 0))) == NULL)
@@ -706,9 +706,10 @@ static void cmd_lspeers(struct socket *sk, struct uidata *data, int argc, wchar_
     {
        sq(sk, 0, L"201", L"No peers avaiable", NULL);
     } else {
-       for(peer = fn->peers; peer != NULL; peer = peer->next)
+       for(peer = btreeiter(fn->peers); peer != NULL; peer = npeer)
        {
-           sq(sk, 2 | ((peer->next != NULL)?1:0), L"200", L"%ls", peer->id, L"%ls", peer->nick, NULL);
+           npeer = btreeiter(NULL);
+           sq(sk, 2 | ((npeer != NULL)?1:0), L"200", L"%ls", peer->id, L"%ls", peer->nick, NULL);
            for(i = 0; i < peer->dinum; i++)
            {
                if(peer->peerdi[i].datum->datatype == FNPD_INT)