Author: toad
Date: 2009-03-26 17:10:29 +0000 (Thu, 26 Mar 2009)
New Revision: 26209
Added:
branches/db4o/freenet/src/freenet/support/RemoveRandomParent.java
Modified:
branches/db4o/freenet/src/freenet/client/async/ClientRequestSchedulerBase.java
branches/db4o/freenet/src/freenet/support/RandomGrabArray.java
branches/db4o/freenet/src/freenet/support/RandomGrabArrayWithClient.java
branches/db4o/freenet/src/freenet/support/RemoveRandom.java
branches/db4o/freenet/src/freenet/support/SectoredRandomGrabArray.java
branches/db4o/freenet/src/freenet/support/SectoredRandomGrabArrayWithInt.java
branches/db4o/freenet/src/freenet/support/SectoredRandomGrabArrayWithObject.java
Log:
RGAs know who their parents are, and when they become empty, they will hint to
their parent that they might need to be removed
Modified:
branches/db4o/freenet/src/freenet/client/async/ClientRequestSchedulerBase.java
===================================================================
---
branches/db4o/freenet/src/freenet/client/async/ClientRequestSchedulerBase.java
2009-03-26 15:31:45 UTC (rev 26208)
+++
branches/db4o/freenet/src/freenet/client/async/ClientRequestSchedulerBase.java
2009-03-26 17:10:29 UTC (rev 26209)
@@ -144,7 +144,7 @@
SectoredRandomGrabArrayWithInt clientGrabber =
(SectoredRandomGrabArrayWithInt) prio.get(rc, container);
if(persistent()) container.activate(clientGrabber, 1);
if(clientGrabber == null) {
- clientGrabber = new SectoredRandomGrabArrayWithInt(rc,
persistent(), container);
+ clientGrabber = new SectoredRandomGrabArrayWithInt(rc,
persistent(), container, null);
prio.add(clientGrabber, container);
if(logMINOR) Logger.minor(this, "Registering retry
count "+rc+" with prioclass "+priorityClass+" on "+clientGrabber+" for "+prio);
}
@@ -155,7 +155,7 @@
SectoredRandomGrabArrayWithObject requestGrabber =
(SectoredRandomGrabArrayWithObject) clientGrabber.getGrabber(client);
if(persistent()) container.activate(requestGrabber, 1);
if(requestGrabber == null) {
- requestGrabber = new
SectoredRandomGrabArrayWithObject(client, persistent(), container);
+ requestGrabber = new
SectoredRandomGrabArrayWithObject(client, persistent(), container,
clientGrabber);
if(logMINOR)
Logger.minor(this, "Creating new
grabber: "+requestGrabber+" for "+client+" from "+clientGrabber+" : "+prio+" :
prio="+priorityClass+", rc="+rc);
clientGrabber.addGrabber(client,
requestGrabber, container);
Modified: branches/db4o/freenet/src/freenet/support/RandomGrabArray.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/RandomGrabArray.java
2009-03-26 15:31:45 UTC (rev 26208)
+++ branches/db4o/freenet/src/freenet/support/RandomGrabArray.java
2009-03-26 17:10:29 UTC (rev 26209)
@@ -7,7 +7,7 @@
/**
* An array which supports very fast remove-and-return-a-random-element.
*/
-public class RandomGrabArray {
+public class RandomGrabArray implements RemoveRandom {
private class Block {
RandomGrabArrayItem[] reqs;
@@ -24,13 +24,15 @@
private final static int BLOCK_SIZE = 1024;
private final boolean persistent;
private final int hashCode;
+ private final RemoveRandomParent parent;
- public RandomGrabArray(boolean persistent, ObjectContainer container) {
+ public RandomGrabArray(boolean persistent, ObjectContainer container,
RemoveRandomParent parent) {
this.blocks = new Block[] { new Block() };
blocks[0].reqs = new RandomGrabArrayItem[MIN_SIZE];
this.persistent = persistent;
index = 0;
this.hashCode = super.hashCode();
+ this.parent = parent;
}
public int hashCode() {
@@ -368,6 +370,7 @@
if(Logger.shouldLog(Logger.MINOR, this))
Logger.minor(this, "Removing "+it+" from "+this);
boolean matched = false;
+ boolean empty = false;
synchronized(this) {
if(blocks.length == 1) {
Block block = blocks[0];
@@ -383,6 +386,7 @@
break;
}
}
+ if(index == 0) empty = true;
if(persistent)
container.deactivate(block, 1);
} else {
@@ -421,6 +425,7 @@
if(persistent)
container.deactivate(block, 1);
}
+ if(index == 0) empty = true;
}
}
if(it.getParentGrabArray() == this)
@@ -431,6 +436,13 @@
if(persistent) {
container.store(this);
}
+ if(empty && parent != null) {
+ boolean active = true;
+ if(persistent) active =
container.ext().isActive(parent);
+ if(!active) container.activate(parent, 1);
+ parent.maybeRemove(this, container);
+ if(!active) container.deactivate(parent, 1);
+ }
}
public synchronized boolean isEmpty() {
Modified:
branches/db4o/freenet/src/freenet/support/RandomGrabArrayWithClient.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/RandomGrabArrayWithClient.java
2009-03-26 15:31:45 UTC (rev 26208)
+++ branches/db4o/freenet/src/freenet/support/RandomGrabArrayWithClient.java
2009-03-26 17:10:29 UTC (rev 26209)
@@ -6,8 +6,8 @@
final Object client;
- public RandomGrabArrayWithClient(Object client, boolean persistent,
ObjectContainer container) {
- super(persistent, container);
+ public RandomGrabArrayWithClient(Object client, boolean persistent,
ObjectContainer container, RemoveRandomParent parent) {
+ super(persistent, container, parent);
this.client = client;
}
Modified: branches/db4o/freenet/src/freenet/support/RemoveRandom.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/RemoveRandom.java 2009-03-26
15:31:45 UTC (rev 26208)
+++ branches/db4o/freenet/src/freenet/support/RemoveRandom.java 2009-03-26
17:10:29 UTC (rev 26209)
@@ -11,4 +11,6 @@
/** Just for consistency checking */
public boolean persistent();
+
+ public void removeFrom(ObjectContainer container);
}
Added: branches/db4o/freenet/src/freenet/support/RemoveRandomParent.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/RemoveRandomParent.java
(rev 0)
+++ branches/db4o/freenet/src/freenet/support/RemoveRandomParent.java
2009-03-26 17:10:29 UTC (rev 26209)
@@ -0,0 +1,13 @@
+package freenet.support;
+
+import com.db4o.ObjectContainer;
+
+public interface RemoveRandomParent {
+
+ /** If the specified RemoveRandom is empty, remove it.
+ * LOCKING: Must be called with no locks held, particularly no locks on
the
+ * RemoveRandom, because we take locks in order!
+ */
+ public void maybeRemove(RemoveRandom r, ObjectContainer container);
+
+}
Modified: branches/db4o/freenet/src/freenet/support/SectoredRandomGrabArray.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/SectoredRandomGrabArray.java
2009-03-26 15:31:45 UTC (rev 26208)
+++ branches/db4o/freenet/src/freenet/support/SectoredRandomGrabArray.java
2009-03-26 17:10:29 UTC (rev 26209)
@@ -8,7 +8,7 @@
* Like RandomGrabArray, but there is an equal chance of any given client's
requests being
* returned.
*/
-public class SectoredRandomGrabArray implements RemoveRandom {
+public class SectoredRandomGrabArray implements RemoveRandom,
RemoveRandomParent {
/*
* Yes, this is O(n). No, I don't care.
@@ -32,11 +32,13 @@
private RemoveRandomWithObject[] grabArrays;
private Object[] grabClients;
private final boolean persistent;
+ private final RemoveRandomParent parent;
- public SectoredRandomGrabArray(boolean persistent, ObjectContainer
container) {
+ public SectoredRandomGrabArray(boolean persistent, ObjectContainer
container, RemoveRandomParent parent) {
this.persistent = persistent;
grabClients = new Object[0];
grabArrays = new RemoveRandomWithObject[0];
+ this.parent = parent;
}
/**
@@ -49,7 +51,7 @@
if(clientIndex == -1) {
if(logMINOR)
Logger.minor(this, "Adding new RGAWithClient
for "+client+" on "+this+" for "+item);
- rga = new RandomGrabArrayWithClient(client, persistent,
container);
+ rga = new RandomGrabArrayWithClient(client, persistent,
container, this);
addElement(client, rga);
if(persistent) {
container.store(rga);
@@ -293,4 +295,28 @@
container.delete(this);
}
+ public void maybeRemove(RemoveRandom r, ObjectContainer container) {
+ int count = 0;
+ while(true) {
+ int found = -1;
+ synchronized(this) {
+ for(int i=0;i<grabArrays.length;i++) {
+ if(grabArrays[i] == r) {
+ found = i;
+ break;
+ }
+ }
+ }
+ if(found != -1) {
+ count++;
+ if(count > 1) Logger.error(this, "Found "+r+" many
times in "+this, new Exception("error"));
+ removeElement(found);
+ } else {
+ if(count == 0) Logger.error(this, "Not in parent: "+r+"
for "+this, new Exception("error"));
+ else if(persistent) r.removeFrom(container);
+ return;
+ }
+ }
+ }
+
}
Modified:
branches/db4o/freenet/src/freenet/support/SectoredRandomGrabArrayWithInt.java
===================================================================
---
branches/db4o/freenet/src/freenet/support/SectoredRandomGrabArrayWithInt.java
2009-03-26 15:31:45 UTC (rev 26208)
+++
branches/db4o/freenet/src/freenet/support/SectoredRandomGrabArrayWithInt.java
2009-03-26 17:10:29 UTC (rev 26209)
@@ -6,8 +6,8 @@
private final int number;
- public SectoredRandomGrabArrayWithInt(int number, boolean persistent,
ObjectContainer container) {
- super(persistent, container);
+ public SectoredRandomGrabArrayWithInt(int number, boolean persistent,
ObjectContainer container, RemoveRandomParent parent) {
+ super(persistent, container, parent);
this.number = number;
}
Modified:
branches/db4o/freenet/src/freenet/support/SectoredRandomGrabArrayWithObject.java
===================================================================
---
branches/db4o/freenet/src/freenet/support/SectoredRandomGrabArrayWithObject.java
2009-03-26 15:31:45 UTC (rev 26208)
+++
branches/db4o/freenet/src/freenet/support/SectoredRandomGrabArrayWithObject.java
2009-03-26 17:10:29 UTC (rev 26209)
@@ -6,8 +6,8 @@
private final Object object;
- public SectoredRandomGrabArrayWithObject(Object object, boolean
persistent, ObjectContainer container) {
- super(persistent, container);
+ public SectoredRandomGrabArrayWithObject(Object object, boolean
persistent, ObjectContainer container, RemoveRandomParent parent) {
+ super(persistent, container, parent);
this.object = object;
}
_______________________________________________
cvs mailing list
[email protected]
http://emu.freenetproject.org/cgi-bin/mailman/listinfo/cvs