From cf4a9ffc27eea756074e6038e50b350133a68bac Mon Sep 17 00:00:00 2001
From: zzz <zzz>
Date: Sun, 18 Mar 2007 21:28:28 +0000
Subject: [PATCH] (zzz) i2psnark: Put bit counting in Bitfield.java for
 efficiency

---
 .../java/src/org/klomp/snark/BitField.java    | 29 ++++++++++++++++++-
 .../java/src/org/klomp/snark/Peer.java        | 17 +++--------
 2 files changed, 32 insertions(+), 14 deletions(-)

diff --git a/apps/i2psnark/java/src/org/klomp/snark/BitField.java b/apps/i2psnark/java/src/org/klomp/snark/BitField.java
index c87973c345..d0b347b5ef 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/BitField.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/BitField.java
@@ -32,6 +32,7 @@ public class BitField
 
   private final byte[] bitfield;
   private final int size;
+  private int count;
 
   /**
    * Creates a new BitField that represents <code>size</code> unset bits.
@@ -41,6 +42,7 @@ public class BitField
     this.size = size;
     int arraysize = ((size-1)/8)+1;
     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
     // cleared or clear them explicitly ourselves.
     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));
     int index = 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 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()
   {
     // Not very efficient
@@ -129,4 +155,5 @@ public class BitField
 
     return sb.toString();
   }
+
 }
diff --git a/apps/i2psnark/java/src/org/klomp/snark/Peer.java b/apps/i2psnark/java/src/org/klomp/snark/Peer.java
index 6ad6971ae4..dda4733cfb 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/Peer.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/Peer.java
@@ -54,8 +54,8 @@ public class Peer implements Comparable
   private boolean deregister = true;
   private static long __id;
   private long _id;
-  final static long CHECK_PERIOD = 40*1000; // 40 seconds
-  final static int RATE_DEPTH = 6; // make following arrays RATE_DEPTH long
+  final static long CHECK_PERIOD = PeerCoordinator.CHECK_PERIOD; // 40 seconds
+  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 downloaded_old[] = {-1,-1,-1,-1,-1,-1};
 
@@ -493,33 +493,24 @@ public class Peer implements Comparable
 
   /**
    * Return how much the peer has
-   * Quite inefficient - a byte lookup table or counter in Bitfield would be much better
    */
   public int completed()
   {
     PeerState s = state;
     if (s == null || s.bitfield == null)
         return 0;
-    int count = 0;
-    for (int i = 0; i < s.bitfield.size(); i++)
-         if (s.bitfield.get(i))
-             count++;
-    return count;
+    return s.bitfield.count();
   }
 
   /**
    * Return if a peer is a seeder
-   * Quite inefficient - a byte lookup table or counter in Bitfield would be much better
    */
   public boolean isCompleted()
   {
     PeerState s = state;
     if (s == null || s.bitfield == null)
         return false;
-    for (int i = 0; i < s.bitfield.size(); i++)
-         if (!s.bitfield.get(i))
-             return false;
-    return true;
+    return s.bitfield.complete();
   }
 
   /**
-- 
GitLab