PacketMap.java
| Index Score | ||
|---|---|---|
![]() |
![]() |
org.furthurnet.datastructures |
![]() |
![]() |
Furthurnet |
View: Reasons, Metrics, Source Code
These are the metrics that contribute to the Enerjy Score for this file, ranked by impact. So the metrics listed at the top influence the score to a greater extent that the metrics listed at the bottom.
/*
* FURTHUR - A distributed peer-to-peer file sharing system.
* Copyright (C) 2001 Jamie M. Addessi
* jaddessi@pcpnetworks.com
*
* This program 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 of the License, or
* (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.furthurnet.datastructures;
import org.furthurnet.datastructures.supporting.Common;
public class PacketMap implements Cloneable
{
public int numPacketSets = 0;
public long[] startPacket = null;
public long[] endPacket = null;
public long totalNumPackets = -1;
public PacketMap(long _totalNumPackets)
{
startPacket = new long[10];
endPacket = new long[10];
totalNumPackets = _totalNumPackets;
}
public PacketMap(String encodedData)
{
int pos = encodedData.indexOf("|");
numPacketSets = Integer.parseInt(encodedData.substring(0, pos));
startPacket = new long[nextHighestMultipleOfTen(numPacketSets)];
endPacket = new long[nextHighestMultipleOfTen(numPacketSets)];
String[] list = Common.tokenize(encodedData, numPacketSets*2 + 2); // if more elements are added which need to be encoded/decoded, increase the '2'
totalNumPackets = new Long(list[1]).longValue();
pos = 0;
for (int i=pos; i<numPacketSets; i++)
{
startPacket[i] = new Long(list[2*i + 2]).longValue();
endPacket[i] = new Long(list[2*i + 3]).longValue();
}
}
public synchronized void addPacketSet()
{
if (numPacketSets % 10 == 0)
{
long[] newStartPacket = new long[numPacketSets+10];
long[] newEndPacket = new long[numPacketSets+10];
for (int i=0; i<numPacketSets; i++)
{
newStartPacket[i] = startPacket[i];
newEndPacket[i] = endPacket[i];
}
startPacket = newStartPacket;
endPacket = newEndPacket;
}
numPacketSets++;
}
protected synchronized long getCurrentStartPacket()
{
if (numPacketSets == 0)
return -1;
else
return startPacket[numPacketSets-1];
}
protected synchronized long getCurrentEndPacket()
{
if (numPacketSets == 0)
return -1;
else
return endPacket[numPacketSets-1];
}
protected synchronized void setCurrentStartPacket(long pac)
{
if (numPacketSets > 0)
startPacket[numPacketSets-1] = pac;
}
protected void setCurrentEndPacket(long pac)
{
if (numPacketSets > 0)
endPacket[numPacketSets-1] = pac;
}
// returns true if the specified packet is included in any of the packet sets
public synchronized boolean includesPacket(long pNum)
{
return (findPacket(pNum) >= 0);
}
// returns the index of the packet set containing the specified packet
public synchronized int findPacket(long pNum)
{
for (int i=0; i<numPacketSets; i++)
if ((startPacket[i] <= pNum) && (pNum <= endPacket[i]))
return i;
return -1;
}
// returns the number of packets currently in the map
public synchronized long countPacketsRecieved()
{
long total = 0;
for (int i=0; i<numPacketSets; i++)
total += endPacket[i] - startPacket[i] + 1;
return total;
}
public static PacketMap intersection(PacketMap map1, PacketMap map2)
{
synchronized(map1)
{
synchronized(map2)
{
map1 = PacketMap.simplify(map1);
map2 = PacketMap.simplify(map2);
if ((map1 == null) || (map2 == null))
return null;
long totalNumPackets = map1.totalNumPackets;
PacketMap result = new PacketMap(totalNumPackets);
long pos = 0;
while (pos < totalNumPackets)
{
long start = getStartIntersectionPoint(pos, map1, map2);
long end = getEndIntersectionPoint(start, map1, map2);
if (start < totalNumPackets)
{
result.addPacketSet();
result.setCurrentStartPacket(start);
result.setCurrentEndPacket(end);
}
pos = end + 1;
}
if (result.numPacketSets == 0)
return null;
else
return result;
}
}
}
private static long getStartIntersectionPoint(long pos, PacketMap map1, PacketMap map2)
{
long totalNumPackets = map1.totalNumPackets;
while (pos < totalNumPackets)
{
long pos1 = map1.getNextIncludedPacket(pos); // pos 1 is the next packet that map 1 includes
long pos2 = map2.getNextIncludedPacket(pos); // pos 2 is the next packet that map 2 includes
if ((pos1 == totalNumPackets) || (pos2 == totalNumPackets))
return totalNumPackets;
if (pos1 == pos2)
return pos1; // they both include this packet, return it
else
{
if (pos1 < pos2)
{
int set = map1.findPacket(pos1);
if (map1.endPacket[set] >= pos2)
{
// the set in map 1 that starts with pos1 includes pos2, thus pos2 is the next intersection point
return pos2;
}
else
{
// the set in map 1 that starts with pos1 does not include pos2, move forward to the end of the set, and continue looking
pos = map1.endPacket[set] + 1;
}
}
else
{
int set = map2.findPacket(pos2);
if (map2.endPacket[set] >= pos1)
{
// the set in map 2 that starts with pos2 includes pos1, thus pos1 is the next intersection point
return pos1;
}
else
{
// the set in map 1 that starts with pos1 does not include pos2, move forward to the end of the set, and continue looking
pos = map2.endPacket[set] + 1;
}
}
}
}
return totalNumPackets;
}
private static long getEndIntersectionPoint(long pos, PacketMap map1, PacketMap map2)
{
long totalNumPackets = map1.totalNumPackets;
if (pos == totalNumPackets)
return totalNumPackets;
int set1 = map1.findPacket(pos);
int set2 = map2.findPacket(pos);
if (map1.endPacket[set1] <= map2.endPacket[set2])
return map1.endPacket[set1];
else
return map2.endPacket[set2];
}
public synchronized long getNextIncludedPacket(long pos)
{
if (includesPacket(pos))
return pos;
long next = totalNumPackets;
for (int i=0; i<numPacketSets; i++)
if ((startPacket[i] >= pos) && (startPacket[i] < next))
next = startPacket[i];
return next;
}
private synchronized long getNextExcludedPacket(long pos)
{
while (pos < totalNumPackets)
{
int set = findPacket(pos);
if (set == -1)
return pos;
else
pos = endPacket[set] + 1;
}
return pos;
}
public static PacketMap inverse(PacketMap map, long totalNumPackets)
{
synchronized(map)
{
map = PacketMap.simplify(map);
if (map == null)
{
PacketMap result = new PacketMap(totalNumPackets);
result.numPacketSets = 1;
result.startPacket[0] = 0;
result.endPacket[0] = totalNumPackets-1;
return result; // the inverse of the empty set is the full set
}
else
{
PacketMap result = new PacketMap(totalNumPackets);
long pos = 0;
while (pos < totalNumPackets)
{
long start = map.getNextExcludedPacket(pos);
long end = map.getNextIncludedPacket(start) - 1;
if (start < totalNumPackets)
{
result.addPacketSet();
result.setCurrentStartPacket(start);
result.setCurrentEndPacket(end);
}
pos = end + 1;
}
if (result.numPacketSets == 0)
return null;
else
return result;
}
}
}
public static PacketMap simplify(PacketMap map)
{
synchronized (map)
{
if (map == null)
return null;
PacketMap simplifiedMap = new PacketMap(map.totalNumPackets);
long pos = 0;
while (pos < map.totalNumPackets)
{
long start = map.getNextIncludedPacket(pos);
if (start == map.totalNumPackets)
break;
long end = map.getNextExcludedPacket(start);
simplifiedMap.addPacketSet();
simplifiedMap.setCurrentStartPacket(start);
simplifiedMap.setCurrentEndPacket(end - 1);
pos = end;
}
return simplifiedMap;
}
}
public synchronized String encodeData()
{
String temp = "";
temp += numPacketSets + "|";
temp += totalNumPackets + "|";
for (int i=0; i<numPacketSets; i++)
{
temp += startPacket[i] + "|";
temp += endPacket[i] + "|";
}
return temp;
}
private static int nextHighestMultipleOfTen(int n)
{
if (n % 10 == 0)
return n;
else
return 10 * (n/10 + 1);
}
public synchronized boolean allPacketsReceived()
{
return (countPacketsRecieved() >= totalNumPackets);
}
public synchronized void addPacket(long pNum)
{
if ((pNum < 0) || (pNum >= totalNumPackets))
return;
if (includesPacket(pNum))
return;
for (int i=0; i<numPacketSets; i++)
if (endPacket[i] == pNum - 1)
{
endPacket[i] = pNum;
return;
}
addPacketSet();
setCurrentStartPacket(pNum);
setCurrentEndPacket(pNum);
}
public synchronized long initNewSegment(FileTransferInfo fti, long pendingPacket)
{
// this should be revised to be more efficient
try
{
for (int i=0; i<fti.numFiles; i++)
{
long fileStart = fti.getFileStartPacketNum((int)(Math.random() * fti.numFiles));
if ((!includesPacket(fileStart)) && (!(pendingPacket == fileStart)))
return fileStart;
}
}
catch (Exception e)
{}
long pNum = -1;
do
{
pNum = (long)(Math.random() * totalNumPackets);
}
while ((includesPacket(pNum)) && (!allPacketsReceived()));
return pNum;
}
public synchronized PacketMap copy()
{
try
{
return (PacketMap)this.clone();
}
catch (Exception e)
{
return null;
}
}
public synchronized PacketMap removePackets(long startPacket, long endPacket)
{
try
{
PacketMap temp = new PacketMap(totalNumPackets);
temp.addPacketSet();
temp.setCurrentStartPacket(startPacket);
temp.setCurrentEndPacket(endPacket);
return PacketMap.intersection(this, PacketMap.inverse(temp, totalNumPackets));
}
catch (Exception e)
{}
return this;
}
public synchronized long getNextSequentialPacket()
{
long max = 0;
for (int i=0; i<numPacketSets; i++)
if (endPacket[i] >= max)
max = endPacket[i] + 1;
return max;
}
}
The table below shows all metrics for PacketMap.java.




