gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r2708 - in GNUnet: . src/applications/gap


From: grothoff
Subject: [GNUnet-SVN] r2708 - in GNUnet: . src/applications/gap
Date: Mon, 1 May 2006 23:25:08 -0700 (PDT)

Author: grothoff
Date: 2006-05-01 23:24:58 -0700 (Mon, 01 May 2006)
New Revision: 2708

Added:
   GNUnet/src/applications/gap/pid_table.c
   GNUnet/src/applications/gap/pid_table.h
Modified:
   GNUnet/ChangeLog
   GNUnet/src/applications/gap/Makefile.am
   GNUnet/src/applications/gap/gap.c
   GNUnet/src/applications/gap/gap.h
Log:
fixing gap bugs and Mantis #1058

Modified: GNUnet/ChangeLog
===================================================================
--- GNUnet/ChangeLog    2006-05-02 04:33:39 UTC (rev 2707)
+++ GNUnet/ChangeLog    2006-05-02 06:24:58 UTC (rev 2708)
@@ -1,3 +1,11 @@
+Tue May  2 00:01:25 PDT 2006
+       Fixed bug in gap where the tracking of query origins for
+       optimizing routing paths lacked a simple assignment of the
+       query origin (found by code inspection).  As a result,
+       routing performance should improve further.  Also fixed
+       small memory leak in gap and reduced memory consumption by
+       fixing Mantis #1058.
+
 Sat Apr 22 13:50:39 PDT 2006
        Fixed bug in util/cron.c where stopCron() would wait for an 
        unnecessary sleep to complete.

Modified: GNUnet/src/applications/gap/Makefile.am
===================================================================
--- GNUnet/src/applications/gap/Makefile.am     2006-05-02 04:33:39 UTC (rev 
2707)
+++ GNUnet/src/applications/gap/Makefile.am     2006-05-02 06:24:58 UTC (rev 
2708)
@@ -10,7 +10,8 @@
 
 
 libgnunetmodule_gap_la_SOURCES = \
-  gap.c gap.h
+  gap.c gap.h \
+  pid_table.c pid_table.h
 libgnunetmodule_gap_la_LDFLAGS = \
   -export-dynamic -avoid-version -module \
   $(LDADD)

Modified: GNUnet/src/applications/gap/gap.c
===================================================================
--- GNUnet/src/applications/gap/gap.c   2006-05-02 04:33:39 UTC (rev 2707)
+++ GNUnet/src/applications/gap/gap.c   2006-05-02 06:24:58 UTC (rev 2708)
@@ -99,7 +99,9 @@
 
 static int stat_memory_destinations;
 
+static int stat_pending_rewards;
 
+
 /**
  * Topology service.
  */
@@ -156,7 +158,7 @@
 
 /**
  * Linked list tracking reply statistics.  Synchronize access using
- * the queryManagerLock!
+ * the lock!
  */
 static ReplyTrackData * rtdList = NULL;
 
@@ -230,13 +232,8 @@
 /**
  * Map the id to an index into the bitmap array.
  */
-static int getIndex(const PeerIdentity * id) {
-  unsigned int index;
-
-  index = coreAPI->computeIndex(id);
-  if (index >= 8*BITMAP_SIZE)
-    index = index & (8*BITMAP_SIZE-1);
-  return index;
+static unsigned int getIndex(PID_INDEX id) {
+  return id % (8*BITMAP_SIZE);
 }
 
 static void setBit(QueryRecord * qr,
@@ -272,6 +269,7 @@
       while (pos->responseList != NULL) {
        rpos = pos->responseList;
        pos->responseList = rpos->next;
+       change_pid_rc(rpos->responder, -1);
        FREE(rpos);
       }
     }
@@ -285,6 +283,7 @@
          pos->responseList = rpos->next;
        else
          rprev->next = rpos->next;
+       change_pid_rc(rpos->responder, -1);     
        FREE(rpos);
        if (rprev == NULL)
          rpos = pos->responseList;
@@ -300,6 +299,7 @@
        rtdList = pos->next;
       else
        prev->next = pos->next;
+      change_pid_rc(pos->queryOrigin, -1);
       FREE(pos);
       if (prev == NULL)
        pos = rtdList;
@@ -320,21 +320,20 @@
  * @param origin
  * @param responder peer that send the reply
  */
-static void updateResponseData(const PeerIdentity * origin,
-                              const PeerIdentity * responder) {
+static void updateResponseData(PID_INDEX origin,
+                              PID_INDEX responder) {
   ReplyTrackData * pos;
   ReplyTrackData * prev;
   ResponseList * rpos;
   ResponseList * rprev;
 
-  if (responder == NULL)
+  if (responder == 0)
     return; /* we don't track local responses */
   MUTEX_LOCK(lock);
   pos = rtdList;
   prev = NULL;
   while (pos != NULL) {
-    if (hostIdentityEquals(origin,
-                          &pos->queryOrigin))
+    if (origin == pos->queryOrigin)
       break; /* found */
     prev = pos;
     pos = pos->next;
@@ -343,6 +342,8 @@
     pos = MALLOC(sizeof(ReplyTrackData));
     pos->next = NULL;
     pos->responseList = NULL;
+    pos->queryOrigin = origin;
+    change_pid_rc(origin, 1);  
     if (prev == NULL)
       rtdList = pos;
     else
@@ -352,9 +353,7 @@
   rpos = pos->responseList;
   rprev = NULL;
   while (rpos != NULL) {
-    if (0 == memcmp(responder,
-                   &rpos->responder,
-                   sizeof(PeerIdentity))) {
+    if (responder == rpos->responder) {
       rpos->responseCount++;
       MUTEX_UNLOCK(lock);
       return;
@@ -364,7 +363,8 @@
   }
   rpos = MALLOC(sizeof(ResponseList));
   rpos->responseCount = 1;
-  rpos->responder = *responder;
+  rpos->responder = responder;
+  change_pid_rc(responder, 1);
   rpos->next = NULL;
   if (rprev == NULL)
     pos->responseList = rpos;
@@ -399,22 +399,23 @@
   unsigned int delta;
   cron_t now;
   QueryRecord * qr;
+  PID_INDEX receiverId;
 
   cronTime(&now);
+  receiverId = intern_pid(receiver);
   MUTEX_LOCK(lock);
   start = pos;
   delta = 0;
   while (padding - delta > sizeof(P2P_gap_query_MESSAGE)) {
     qr = &queries[pos];
     if ( (qr->expires > now) &&
-        (0 == getBit(qr, getIndex(receiver))) &&
+        (0 == getBit(qr, getIndex(receiverId))) &&
+        (receiverId != qr->noTarget) &&
         (! (equalsHashCode512(&receiver->hashPubKey,
-                              &qr->noTarget.hashPubKey)) ) &&
-        (! (equalsHashCode512(&receiver->hashPubKey,
                               &qr->msg->returnTo.hashPubKey)) ) &&
         (padding - delta >= ntohs(qr->msg->header.size) ) ) {
       setBit(&queries[pos],
-            getIndex(receiver));
+            getIndex(receiverId));
       memcpy(&((char*)position)[delta],
             qr->msg,
             ntohs(qr->msg->header.size));
@@ -428,6 +429,7 @@
       break;
   }
   MUTEX_UNLOCK(lock);
+  change_pid_rc(receiverId, -1);
   return delta;
 }
 
@@ -435,28 +437,28 @@
  * Select a subset of the peers for forwarding.  Called
  * on each connected node by the core.
  */
-static void hotpathSelectionCode(const PeerIdentity * id,
+static void hotpathSelectionCode(const PeerIdentity * peer,
                                 void * cls) {
   QueryRecord * qr = cls;
   ReplyTrackData * pos;
   ResponseList * rp;
   int ranking = 0;
   int distance;
+  PID_INDEX id;
 
+  id = intern_pid(peer);
   /* compute some basic ranking based on historical
      queries from the same origin */
   pos = rtdList;
   while (pos != NULL) {
-    if (equalsHashCode512(&pos->queryOrigin.hashPubKey,
-                         &qr->noTarget.hashPubKey))
+    if (pos->queryOrigin == qr->noTarget)
       break;
     pos = pos->next;
   }
   if (pos != NULL) {
     rp = pos->responseList;
     while (rp != NULL) {
-      if (equalsHashCode512(&rp->responder.hashPubKey,
-                           &id->hashPubKey))
+      if (rp->responder == id)
        break;
       rp = rp->next;
     }
@@ -469,34 +471,33 @@
   }
   distance
     = distanceHashCode512(&qr->msg->queries[0],
-                         &id->hashPubKey);
+                         &peer->hashPubKey);
   if (distance <= 0)
     distance = 1;
   ranking += 0xFFFF / (1 + weak_randomi(distance));
   ranking += 1 + weak_randomi(0xFF); /* small random chance for everyone */
-  if (equalsHashCode512(&id->hashPubKey,
-                       &qr->noTarget.hashPubKey))
+  if (id == qr->noTarget)
     ranking = 0; /* no chance for blocked peers */
   qr->rankings[getIndex(id)] = ranking; 
+  change_pid_rc(id, -1);
 }
 
 /**
  * A "PerNodeCallback" method that forwards the query to the selected
  * nodes.
  */
-static void sendToSelected(const PeerIdentity * id,
+static void sendToSelected(const PeerIdentity * peer,
                           void * cls) {
   const QueryRecord * qr = cls;
+  PID_INDEX id;
 #if DEBUG_GAP
   EncName encq;
   EncName encp;
 #endif
 
-  if ( (equalsHashCode512(&id->hashPubKey,
-                         &qr->noTarget.hashPubKey)) ||
-       (equalsHashCode512(&id->hashPubKey,
-                         &qr->msg->returnTo.hashPubKey)) )
-    return; /* never send back to source */
+  if (equalsHashCode512(&peer->hashPubKey,
+                       &qr->msg->returnTo.hashPubKey))
+    return;  /* never send back to source */
 
   /* Load above hard limit? */
   if ( ( (hardCPULimit > 0) && 
@@ -504,11 +505,17 @@
        ( (hardUpLimit > 0) && 
         (getNetworkLoadUp() >= hardUpLimit) ) )
     return;
+  
+  id = intern_pid(peer);
+  if (id == qr->noTarget) {
+    change_pid_rc(id, -1);
+    return; /* never send back to source */
+  }
 
   if (getBit(qr, getIndex(id)) == 1) {
 #if DEBUG_GAP
     IFLOG(LOG_DEBUG,
-         hash2enc(&id->hashPubKey,
+         hash2enc(&peer->hashPubKey,
                   &encp);
          hash2enc(&qr->msg->queries[0],
                   &encq));
@@ -519,11 +526,12 @@
 #endif
     if (stats != NULL)
       stats->change(stat_routing_forwards, 1);
-    coreAPI->unicast(id,
+    coreAPI->unicast(peer,
                     &qr->msg->header,
                     BASE_QUERY_PRIORITY * ntohl(qr->msg->priority) * 2,
                     TTL_DECREMENT);
   }
+  change_pid_rc(id, -1);
 }
 
 /**
@@ -539,7 +547,11 @@
   cron_t expirationTime;
   int oldestIndex;
   int i;
+  int j;
   int noclear = NO;
+  unsigned long long rankingSum;
+  unsigned long long sel;
+  unsigned long long pos;
 
   cronTime(&now);
   MUTEX_LOCK(lock);
@@ -603,15 +615,13 @@
         msg,
         ntohs(msg->header.size));
   if (noclear == NO) {
-    int j;
-    unsigned long long rankingSum;
     memset(&qr->bitmap[0],
           0,
           BITMAP_SIZE);
     if (excludePeer != NULL)
-      qr->noTarget = *excludePeer;
+      qr->noTarget = intern_pid(excludePeer);
     else
-      qr->noTarget = *coreAPI->myIdentity;
+      qr->noTarget = intern_pid(coreAPI->myIdentity);
     qr->totalDistance = 0;
     qr->rankings = MALLOC(sizeof(int)*8*BITMAP_SIZE);
     qr->activeConnections
@@ -626,9 +636,6 @@
     if (qr->activeConnections > 0) {
       /* select 4 peers for forwarding */
       for (i=0;i<4;i++) {
-       unsigned long long sel;
-       unsigned long long pos;
-
        if (rankingSum == 0)
          break;
        sel = weak_randomi64(rankingSum);
@@ -811,6 +818,9 @@
     return;
   MUTEX_LOCK(lock);
   rewards[rewardPos].query = *query;
+  if (stats != NULL)
+    stats->change(stat_pending_rewards,
+                 prio - rewards[rewardPos].prio);
   rewards[rewardPos].prio = prio;
   rewardPos++;
   if (rewardPos == rewardSize)
@@ -818,8 +828,7 @@
   MUTEX_UNLOCK(lock);
 }
 
-static unsigned int claimReward(const HashCode512 * query,
-                               const PeerIdentity * peer) {
+static unsigned int claimReward(const HashCode512 * query) {
   int i;
   unsigned int ret;
 
@@ -829,6 +838,9 @@
     if (equalsHashCode512(query,
                          &rewards[i].query)) {
       ret += rewards[i].prio;
+      if (stats != NULL)
+       stats->change(stat_pending_rewards,
+                     - rewards[rewardPos].prio);
       rewards[i].prio = 0;
     }
   }
@@ -855,9 +867,9 @@
                     const HashCode512 * query,
                     int ttl,
                     unsigned int priority,
-                    const PeerIdentity * sender) {
+                    PID_INDEX sender) {
   unsigned int i;
-  cron_t now;
+  cron_t now;  
 #if DEBUG__GAP
   EncName enc;
 
@@ -869,7 +881,7 @@
       &enc,
       ite);
 #endif
-  GNUNET_ASSERT(sender != NULL); /* do NOT add to RT for local clients! */
+  GNUNET_ASSERT(sender != 0); /* do NOT add to RT for local clients! */
   cronTime(&now);
   if ( (stats != NULL) &&
        (ite->ttl == 0) )
@@ -887,11 +899,16 @@
       ite->ttl = now + ttl;
       ite->priority += priority;
       for (i=0;i<ite->hostsWaiting;i++)
-       if (equalsHashCode512(&ite->destination[i].hashPubKey,
-                             &sender->hashPubKey))
+       if (ite->destination[i] == sender)
          return SYSERR;
-      if (ite->hostsWaiting >= MAX_HOSTS_WAITING)
-       ite->hostsWaiting = 0; /* RESET to avoid unbounded growth (#1014) */
+      if (ite->hostsWaiting >= MAX_HOSTS_WAITING) {
+       decrement_pid_rcs(ite->destination, ite->hostsWaiting);
+       if (stats != NULL)
+         stats->change(stat_memory_destinations, - ite->hostsWaiting);
+       GROW(ite->destination,
+            ite->hostsWaiting,
+            0); /* RESET to avoid unbounded growth (#1014) */
+      }
     } else {
       ite->successful_local_lookup_in_delay_loop = NO;
       /* different request, flush pending queues */
@@ -899,6 +916,7 @@
       ite->primaryKey = *query;
       if (stats != NULL)
        stats->change(stat_memory_destinations, - ite->hostsWaiting);
+      decrement_pid_rcs(ite->destination, ite->hostsWaiting);
       GROW(ite->destination,
           ite->hostsWaiting,
           0);
@@ -909,8 +927,7 @@
     GNUNET_ASSERT(equalsHashCode512(query,
                                    &ite->primaryKey));
     for (i=0;i<ite->hostsWaiting;i++)
-      if (equalsHashCode512(&sender->hashPubKey,
-                           &ite->destination[i].hashPubKey))
+      if (sender == ite->destination[i])
        return SYSERR; /* already there! */
     /* extend lifetime */
     if (ite->ttl < now + ttl)
@@ -922,7 +939,8 @@
   GROW(ite->destination,
        ite->hostsWaiting,
        ite->hostsWaiting+1);
-  ite->destination[ite->hostsWaiting-1] = *sender;
+  ite->destination[ite->hostsWaiting-1] = sender;
+  change_pid_rc(sender, 1);
   /* again: new listener, flush seen list */
   if (stats != NULL)
     stats->change(stat_memory_seen, - ite->seenIndex);
@@ -962,7 +980,7 @@
 static int needsForwarding(const HashCode512 * query,
                           int ttl,
                           unsigned int priority,
-                          const PeerIdentity * sender,
+                          PID_INDEX sender,
                           int * isRouted,
                           int * doForward) {
   IndirectionTableEntry * ite;
@@ -1229,6 +1247,7 @@
   unsigned int j;
   unsigned int maxDelay;
   cron_t now;
+  PeerIdentity recv;
 #if DEBUG_GAP
   EncName enc;
 #endif
@@ -1242,15 +1261,17 @@
     maxDelay = TTL_DECREMENT; /* for expired queries */
   /* send to peers */
   for (j=0;j<ite->hostsWaiting;j++) {
+    resolve_pid(ite->destination[j],
+               &recv);
 #if DEBUG_GAP
     IFLOG(LOG_DEBUG,
-         hash2enc(&ite->destination[j].hashPubKey,
+         hash2enc(&recv,
                   &enc));
     LOG(LOG_DEBUG,
        "GAP sending reply to `%s'\n",
        &enc);
 #endif
-    coreAPI->unicast(&ite->destination[j],
+    coreAPI->unicast(&recv,
                     msg,
                     BASE_REPLY_PRIORITY *
                     (ite->priority+5),
@@ -1260,7 +1281,6 @@
 }
 
 struct qLRC {
-  const PeerIdentity * sender;
   DataContainer ** values;
   unsigned int valueCount;
   HashCode512 * hashes;
@@ -1356,6 +1376,7 @@
   int max;
   int * perm;
   int doForward;
+  PID_INDEX senderID;
 #if DEBUG_GAP
   EncName enc;
 #endif
@@ -1367,6 +1388,8 @@
         (getNetworkLoadUp() >= hardUpLimit) ) ) 
     return SYSERR;  
 
+  senderID = intern_pid(sender);
+  GNUNET_ASSERT( (senderID != 0) || (sender == NULL) );
   ite = &ROUTING_indTable_[computeRoutingIndex(&query->queries[0])];
   MUTEX_LOCK(&lookup_exclusion);
   i = -1;
@@ -1377,7 +1400,7 @@
       i = needsForwarding(&query->queries[0],
                          ttl,
                          prio,
-                         sender,
+                         senderID,
                          &isRouted,
                          &doForward);
     } else {
@@ -1417,7 +1440,6 @@
   cls.valueCount = 0;
   cls.hashes = NULL;
   cls.hashCount = 0;
-  cls.sender = sender;
   if ( (isRouted == YES) && /* if we can't route, lookup useless! */
        ( (policy & QUERY_ANSWER) > 0) ) {
     bs->get(bs->closure,
@@ -1447,8 +1469,8 @@
 
     for (i=0;i<cls.valueCount;i++) {
       if (i < max) {
-       if (cls.sender != NULL)
-         queueReply(cls.sender,
+       if (sender != NULL)
+         queueReply(sender,
                     &query->queries[0],
                     cls.values[perm[i]]);
       }
@@ -1484,6 +1506,7 @@
     forwardQuery(query,
                 sender);
   }
+  change_pid_rc(senderID, -1);
   return doForward;
 }
 
@@ -1501,7 +1524,7 @@
  * @return how good this content was (effective
  *         priority of the original request)
  */
-static int useContent(const PeerIdentity * hostId,
+static int useContent(const PeerIdentity * host,
                      const P2P_gap_reply_MESSAGE * msg) {
   unsigned int i;
   HashCode512 contentHC;
@@ -1511,16 +1534,17 @@
   unsigned int prio;
   DataContainer * value;
   double preference;
+  PID_INDEX hostId;
 #if DEBUG_GAP
   EncName enc;
 
   IFLOG(LOG_DEBUG,
-       if (hostId != NULL)
+       if (host != NULL)
          hash2enc(&hostId->hashPubKey,
                   &enc));
   LOG(LOG_DEBUG,
       "GAP received content from `%s'\n",
-      (hostId != NULL) ? (const char*)&enc : "myself");
+      (host != NULL) ? (const char*)&enc : "myself");
 #endif
   if (ntohs(msg->header.size) < sizeof(P2P_gap_reply_MESSAGE)) {
     BREAK();
@@ -1567,12 +1591,13 @@
   if (ret == SYSERR) {
     EncName enc;
     
-    if (hostId != NULL)
-      hash2enc(&hostId->hashPubKey, &enc);
+    IFLOG(LOG_ERROR,
+         if (host != NULL)
+           hash2enc(&host->hashPubKey, 
+                    &enc));
     LOG(LOG_ERROR,
-      _("GAP received invalid content from `%s'\n"),
-      (hostId != NULL) ? (const char*)&enc : _("myself"));
-    
+       _("GAP received invalid content from `%s'\n"),
+       (host != NULL) ? (const char*)&enc : _("myself"));    
     BREAK();
     uri(value,
        ANY_BLOCK,
@@ -1583,6 +1608,7 @@
 
   /* THIRD: compute content priority/value and
      send remote reply (ITE processing) */
+  hostId = intern_pid(host);
   MUTEX_LOCK(&lookup_exclusion);
   if (equalsHashCode512(&ite->primaryKey,
                        &msg->primaryKey) ) {   
@@ -1590,10 +1616,10 @@
     ite->priority = 0;
     /* remove the sender from the waiting list
        (if the sender was waiting for a response) */
-    if (hostId != NULL) {
+    if (host != NULL) {
       for (i=0;i<ite->hostsWaiting;i++) {
-       if (equalsHashCode512(&hostId->hashPubKey,
-                             &ite->destination[i].hashPubKey)) {
+       if (hostId == ite->destination[i]) {
+         change_pid_rc(ite->destination[i], -1);
          ite->destination[i] = ite->destination[ite->hostsWaiting-1];
          if (stats != NULL)
            stats->change(stat_memory_destinations, - 1);
@@ -1625,6 +1651,7 @@
         to keep track of all of the responses seen (#1014) */
       if (stats != NULL)
        stats->change(stat_memory_destinations, - ite->hostsWaiting);
+      decrement_pid_rcs(ite->destination, ite->hostsWaiting);
       GROW(ite->destination,
           ite->hostsWaiting,
           0);
@@ -1644,7 +1671,7 @@
       stats->change(stat_routing_reply_drops, 1);
   }
   MUTEX_UNLOCK(&lookup_exclusion);
-  prio += claimReward(&msg->primaryKey, hostId);
+  prio += claimReward(&msg->primaryKey);
 
   /* FOURTH: update content priority in local datastore */
   if (prio > 0) {
@@ -1664,18 +1691,19 @@
   FREE(value);
 
   /* SIXTH: adjust traffic preferences */
-  if (hostId != NULL) { /* if we are the sender, hostId will be NULL */
+  if (host != NULL) { /* if we are the sender, hostId will be NULL */
     preference = (double) prio;
-    identity->changeHostTrust(hostId,
+    identity->changeHostTrust(host,
                              prio);
     for (i=0;i<ite->hostsWaiting;i++)
-      updateResponseData(&ite->destination[i],
+      updateResponseData(ite->destination[i],
                         hostId);
     if (preference < CONTENT_BANDWIDTH_VALUE)
       preference = CONTENT_BANDWIDTH_VALUE;
-    coreAPI->preferTrafficFrom(hostId,
+    coreAPI->preferTrafficFrom(host,
                               preference);
   }
+  change_pid_rc(hostId, -1);
   return OK;
 }
 
@@ -1881,16 +1909,15 @@
 #if DEBUG_GAP
     if (sender != NULL) {
       IFLOG(LOG_DEBUG,
-        hash2enc(&sender->hashPubKey,
-             &enc));
+           hash2enc(&sender->hashPubKey,
+                    &enc));
     }
     LOG(LOG_DEBUG,
         "Dropping query from %s, this peer is too busy.\n",
         sender == NULL ? "localhost" : &enc);
 #endif
     return OK;
-  }
-
+  }  
   queries = 1 + (ntohs(msg->size) - sizeof(P2P_gap_query_MESSAGE))
     / sizeof(HashCode512);
   if ( (queries <= 0) ||
@@ -1900,6 +1927,7 @@
     BREAK();
     return SYSERR; /* malformed query */
   }
+  
   qmsg = MALLOC(ntohs(msg->size));
   memcpy(qmsg, msg, ntohs(msg->size));
   if (equalsHashCode512(&qmsg->returnTo.hashPubKey,
@@ -2041,7 +2069,9 @@
     stat_routing_slots_used         = stats->create(gettext_noop("# gap 
routing slots currently in use"));
     stat_memory_seen                = stats->create(gettext_noop("# gap memory 
used for tracking seen content"));
     stat_memory_destinations        = stats->create(gettext_noop("# gap memory 
used for tracking routing destinations"));
+    stat_pending_rewards            = stats->create(gettext_noop("# gap 
rewards pending"));
   }
+  init_pid_table(stats);
   GROW(rewards,
        rewardSize,
        MAX_REWARD_TRACKS);
@@ -2110,6 +2140,7 @@
   unsigned int i;
   ResponseList * rpos;
   ReplyTrackData * pos;
+  IndirectionTableEntry * ite;
 
   coreAPI->unregisterHandler(P2P_PROTO_gap_QUERY,
                             &handleQuery);
@@ -2123,16 +2154,18 @@
             NULL);
 
   for (i=0;i<indirectionTableSize;i++) {
+    ite = &ROUTING_indTable_[i];
     if (stats != NULL)
-      stats->change(stat_memory_seen, - ROUTING_indTable_[i].seenIndex);
-    GROW(ROUTING_indTable_[i].seen,
-        ROUTING_indTable_[i].seenIndex,
+      stats->change(stat_memory_seen, - ite->seenIndex);
+    GROW(ite->seen,
+        ite->seenIndex,
         0);
-    ROUTING_indTable_[i].seenReplyWasUnique = NO;
-      if (stats != NULL)
-       stats->change(stat_memory_destinations, - 
ROUTING_indTable_[i].hostsWaiting);
-    GROW(ROUTING_indTable_[i].destination,
-        ROUTING_indTable_[i].hostsWaiting,
+    ite->seenReplyWasUnique = NO;
+    if (stats != NULL)
+      stats->change(stat_memory_destinations, - ite->hostsWaiting);
+    decrement_pid_rcs(ite->destination, ite->hostsWaiting);    
+    GROW(ite->destination,
+        ite->hostsWaiting,
         0);
   }
 
@@ -2162,7 +2195,9 @@
   GROW(rewards,
        rewardSize,
        0);
+  done_pid_table();
   if (stats != NULL) {
+    stats->set(stat_pending_rewards, 0);
     coreAPI->releaseService(stats);
     stats = NULL;
   }

Modified: GNUnet/src/applications/gap/gap.h
===================================================================
--- GNUnet/src/applications/gap/gap.h   2006-05-02 04:33:39 UTC (rev 2707)
+++ GNUnet/src/applications/gap/gap.h   2006-05-02 06:24:58 UTC (rev 2708)
@@ -35,6 +35,7 @@
 #include "gnunet_stats_service.h"
 #include "gnunet_traffic_service.h"
 #include "gnunet_topology_service.h"
+#include "pid_table.h"
 
 #define DEBUG_GAP NO
 
@@ -284,7 +285,7 @@
   /**
    * To which peer will we never send this message?
    */
-  PeerIdentity noTarget;
+  PID_INDEX noTarget;
 
   /**
    * Bit-map marking the hostIndices (computeIndex) of nodes that have
@@ -351,7 +352,7 @@
   /**
    * Who are these hosts?
    */
-  PeerIdentity * destination;
+  PID_INDEX * destination;
 
   /**
    * How many hosts are waiting for an answer to this query (length of
@@ -380,7 +381,7 @@
  */
 typedef struct RL_ {
   struct RL_ * next;
-  PeerIdentity responder;
+  PID_INDEX responder;
   unsigned int responseCount;
 } ResponseList;
 
@@ -398,7 +399,7 @@
   /**
    * For which client does this entry track replies?
    */
-  PeerIdentity queryOrigin;
+  PID_INDEX queryOrigin;
 
   /**
    * Linked list of peers that responded, with

Added: GNUnet/src/applications/gap/pid_table.c
===================================================================
--- GNUnet/src/applications/gap/pid_table.c     2006-05-02 04:33:39 UTC (rev 
2707)
+++ GNUnet/src/applications/gap/pid_table.c     2006-05-02 06:24:58 UTC (rev 
2708)
@@ -0,0 +1,167 @@
+/*
+      This file is part of GNUnet
+     (C) 2006 Christian Grothoff (and other contributing authors)
+
+      GNUnet is free software; you can redistribute it and/or modify
+      it under the terms of the GNU General Public License as published
+      by the Free Software Foundation; either version 2, or (at your
+      option) any later version.
+
+      GNUnet is distributed in the hope that it will be useful, but
+      WITHOUT ANY WARRANTY; without even the implied warranty of
+      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+      General Public License for more details.
+
+      You should have received a copy of the GNU General Public License
+      along with GNUnet; see the file COPYING.  If not, write to the
+      Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+      Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file gap/pid_table.c
+ * @brief peer-ID table that assigns integer IDs to peer-IDs to save memory
+ * @author Christian Grothoff
+ */
+
+#include "platform.h"
+#include "pid_table.h"
+
+/**
+ * Statistics service.
+ */
+static Stats_ServiceAPI * stats;
+
+static int stat_pid_entries;
+
+static int stat_pid_rc;
+
+typedef struct {
+  /** the identifier itself */
+  HashCode512 id;
+  /** reference counter */
+  unsigned int rc;
+} PID_Entry;
+
+static unsigned int size;
+
+static PID_Entry * table;
+
+static Mutex lock;
+
+
+PID_INDEX intern_pid(const PeerIdentity * pid) {
+  PID_INDEX ret;
+  PID_INDEX zero;
+
+  if (pid == NULL)
+    return 0;
+  zero = size;
+  MUTEX_LOCK(&lock);
+  for (ret=1;ret<size;ret++) {
+    if (equalsHashCode512(&pid->hashPubKey,
+                         &table[ret].id)) {
+      table[ret].rc++;
+      if (stats != NULL) {
+       stats->change(stat_pid_rc, 1);
+       if (table[ret].rc == 1)
+         stats->change(stat_pid_entries, 1);
+      }
+      MUTEX_UNLOCK(&lock);
+      return ret;
+    } else if ( (zero == size) &&
+               (table[ret].rc == 0) ) {
+      zero = ret;      
+    }
+  }
+  ret = zero;
+  if (ret == size) {
+    GROW(table,
+        size,
+        size + 16);
+  }
+  if (ret == 0)
+    ret = 1;
+  GNUNET_ASSERT(ret < size);
+  table[ret].id = pid->hashPubKey;
+  table[ret].rc = 1;
+  if (stats != NULL) {
+    stats->change(stat_pid_rc, 1);
+    stats->change(stat_pid_entries, 1);
+  }  
+  MUTEX_UNLOCK(&lock);
+  return ret;
+}
+
+void decrement_pid_rcs(const PID_INDEX * ids,
+                      unsigned int count) {
+  int i;
+  PID_INDEX id;
+  if (count == 0)
+    return;
+  MUTEX_LOCK(&lock);
+  for (i=count-1;i>=0;i--) {
+    id = ids[i];
+    GNUNET_ASSERT(id < size);
+    GNUNET_ASSERT(table[id].rc > 0);
+    table[id].rc--;
+    if ( (table[id].rc == 0) &&
+        (stats != NULL) )
+      stats->change(stat_pid_entries, -1);   
+  }
+  MUTEX_UNLOCK(&lock);
+  if (stats != NULL) 
+    stats->change(stat_pid_rc, - count);
+}
+
+void change_pid_rc(PID_INDEX id, int delta) {
+  if (id == 0)
+    return;
+  MUTEX_LOCK(&lock);
+  GNUNET_ASSERT(id < size);
+  GNUNET_ASSERT(table[id].rc > 0);
+  table[id].rc += delta;
+  if (stats != NULL) {
+    stats->change(stat_pid_rc, delta);
+    if (table[id].rc == 0)
+      stats->change(stat_pid_entries, -1);
+  }
+  MUTEX_UNLOCK(&lock);
+}
+
+void resolve_pid(PID_INDEX id, 
+                PeerIdentity * pid) {
+  if (id == 0) {
+    memset(pid, 0, sizeof(PeerIdentity));
+    BREAK();
+    return;
+  }
+  MUTEX_LOCK(&lock);
+  GNUNET_ASSERT(id < size);
+  GNUNET_ASSERT(table[id].rc > 0);
+  pid->hashPubKey = table[id].id;
+  MUTEX_UNLOCK(&lock);
+}
+
+
+void init_pid_table(Stats_ServiceAPI * s) {
+  stats = s;
+  if (stats != NULL) {
+    stat_pid_entries 
+      = stats->create(gettext_noop("# distinct interned peer IDs in pid 
table"));
+    stat_pid_rc
+      = stats->create(gettext_noop("# total RC of interned peer IDs in pid 
table"));
+  }
+  MUTEX_CREATE(&lock);
+}
+
+
+void done_pid_table() {
+  GROW(table,
+       size,
+       0);
+  stats = NULL;
+  MUTEX_DESTROY(&lock);
+}
+
+/* end of pid_table.c */

Added: GNUnet/src/applications/gap/pid_table.h
===================================================================
--- GNUnet/src/applications/gap/pid_table.h     2006-05-02 04:33:39 UTC (rev 
2707)
+++ GNUnet/src/applications/gap/pid_table.h     2006-05-02 06:24:58 UTC (rev 
2708)
@@ -0,0 +1,45 @@
+/*
+      This file is part of GNUnet
+     (C) 2006 Christian Grothoff (and other contributing authors)
+
+      GNUnet is free software; you can redistribute it and/or modify
+      it under the terms of the GNU General Public License as published
+      by the Free Software Foundation; either version 2, or (at your
+      option) any later version.
+
+      GNUnet is distributed in the hope that it will be useful, but
+      WITHOUT ANY WARRANTY; without even the implied warranty of
+      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+      General Public License for more details.
+
+      You should have received a copy of the GNU General Public License
+      along with GNUnet; see the file COPYING.  If not, write to the
+      Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+      Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file gap/pid_table.h
+ * @brief peer-ID table that assigns integer IDs to peer-IDs to save memory
+ * @author Christian Grothoff
+ */
+
+#include "gnunet_util.h"
+#include "gnunet_stats_service.h"
+
+void init_pid_table(Stats_ServiceAPI * s);
+
+void done_pid_table();
+
+typedef unsigned int PID_INDEX;
+ 
+PID_INDEX intern_pid(const PeerIdentity * pid);
+
+void change_pid_rc(PID_INDEX id, int delta);
+
+void decrement_pid_rcs(const PID_INDEX * ids,
+                      unsigned int count);
+
+void resolve_pid(PID_INDEX id, 
+                PeerIdentity * pid);
+





reply via email to

[Prev in Thread] Current Thread [Next in Thread]