[Top][All Lists]
[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);
+
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r2708 - in GNUnet: . src/applications/gap,
grothoff <=