(zzz) i2psnark: Put bit counting in Bitfield.java for efficiency
This commit is contained in:
@ -32,6 +32,7 @@ public class BitField
|
|||||||
|
|
||||||
private final byte[] bitfield;
|
private final byte[] bitfield;
|
||||||
private final int size;
|
private final int size;
|
||||||
|
private int count;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new BitField that represents <code>size</code> unset bits.
|
* Creates a new BitField that represents <code>size</code> unset bits.
|
||||||
@ -41,6 +42,7 @@ public class BitField
|
|||||||
this.size = size;
|
this.size = size;
|
||||||
int arraysize = ((size-1)/8)+1;
|
int arraysize = ((size-1)/8)+1;
|
||||||
bitfield = new byte[arraysize];
|
bitfield = new byte[arraysize];
|
||||||
|
this.count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -60,6 +62,11 @@ public class BitField
|
|||||||
// XXX - More correct would be to check that unused bits are
|
// XXX - More correct would be to check that unused bits are
|
||||||
// cleared or clear them explicitly ourselves.
|
// cleared or clear them explicitly ourselves.
|
||||||
System.arraycopy(bitfield, 0, this.bitfield, 0, arraysize);
|
System.arraycopy(bitfield, 0, this.bitfield, 0, arraysize);
|
||||||
|
|
||||||
|
this.count = 0;
|
||||||
|
for (int i = 0; i < size; i++)
|
||||||
|
if (get(i))
|
||||||
|
this.count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -95,7 +102,10 @@ public class BitField
|
|||||||
throw new IndexOutOfBoundsException(Integer.toString(bit));
|
throw new IndexOutOfBoundsException(Integer.toString(bit));
|
||||||
int index = bit/8;
|
int index = bit/8;
|
||||||
int mask = 128 >> (bit % 8);
|
int mask = 128 >> (bit % 8);
|
||||||
bitfield[index] |= mask;
|
if ((bitfield[index] & mask) == 0) {
|
||||||
|
count++;
|
||||||
|
bitfield[index] |= mask;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -114,6 +124,22 @@ public class BitField
|
|||||||
return (bitfield[index] & mask) != 0;
|
return (bitfield[index] & mask) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the number of set bits.
|
||||||
|
*/
|
||||||
|
public int count()
|
||||||
|
{
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if all bits are set.
|
||||||
|
*/
|
||||||
|
public boolean complete()
|
||||||
|
{
|
||||||
|
return count >= size;
|
||||||
|
}
|
||||||
|
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
// Not very efficient
|
// Not very efficient
|
||||||
@ -129,4 +155,5 @@ public class BitField
|
|||||||
|
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -54,8 +54,8 @@ public class Peer implements Comparable
|
|||||||
private boolean deregister = true;
|
private boolean deregister = true;
|
||||||
private static long __id;
|
private static long __id;
|
||||||
private long _id;
|
private long _id;
|
||||||
final static long CHECK_PERIOD = 40*1000; // 40 seconds
|
final static long CHECK_PERIOD = PeerCoordinator.CHECK_PERIOD; // 40 seconds
|
||||||
final static int RATE_DEPTH = 6; // make following arrays RATE_DEPTH long
|
final static int RATE_DEPTH = PeerCoordinator.RATE_DEPTH; // make following arrays RATE_DEPTH long
|
||||||
private long uploaded_old[] = {-1,-1,-1,-1,-1,-1};
|
private long uploaded_old[] = {-1,-1,-1,-1,-1,-1};
|
||||||
private long downloaded_old[] = {-1,-1,-1,-1,-1,-1};
|
private long downloaded_old[] = {-1,-1,-1,-1,-1,-1};
|
||||||
|
|
||||||
@ -493,33 +493,24 @@ public class Peer implements Comparable
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Return how much the peer has
|
* Return how much the peer has
|
||||||
* Quite inefficient - a byte lookup table or counter in Bitfield would be much better
|
|
||||||
*/
|
*/
|
||||||
public int completed()
|
public int completed()
|
||||||
{
|
{
|
||||||
PeerState s = state;
|
PeerState s = state;
|
||||||
if (s == null || s.bitfield == null)
|
if (s == null || s.bitfield == null)
|
||||||
return 0;
|
return 0;
|
||||||
int count = 0;
|
return s.bitfield.count();
|
||||||
for (int i = 0; i < s.bitfield.size(); i++)
|
|
||||||
if (s.bitfield.get(i))
|
|
||||||
count++;
|
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return if a peer is a seeder
|
* Return if a peer is a seeder
|
||||||
* Quite inefficient - a byte lookup table or counter in Bitfield would be much better
|
|
||||||
*/
|
*/
|
||||||
public boolean isCompleted()
|
public boolean isCompleted()
|
||||||
{
|
{
|
||||||
PeerState s = state;
|
PeerState s = state;
|
||||||
if (s == null || s.bitfield == null)
|
if (s == null || s.bitfield == null)
|
||||||
return false;
|
return false;
|
||||||
for (int i = 0; i < s.bitfield.size(); i++)
|
return s.bitfield.complete();
|
||||||
if (!s.bitfield.get(i))
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user