Index: src/java/org/apache/nutch/util/ThreadPool.java =================================================================== --- src/java/org/apache/nutch/util/ThreadPool.java (revision 561794) +++ src/java/org/apache/nutch/util/ThreadPool.java (working copy) @@ -1,140 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.nutch.util; - -import java.util.*; - -// Commons Logging imports -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - - -/************************************************ - * ThreadPool.java - * - * ThreadPool maintains a large set of threads, which - * can be dedicated to a certain task, and then recycled. - ***********************************************/ -public class ThreadPool { - /** - * A TaskThread sits in a loop, asking the pool - * for a job, and servicing it. That's all it does. - */ - class TaskThread extends Thread { - /** - * Get a job from the pool, run it, repeat. - * If the job is null, we exit the loop. - */ - public void run() { - while (true) { - Runnable r = obtainJob(); - if (r == null) { - break; - } - try { - r.run(); - } catch (Exception e) { - System.err.println("E: " + e); - e.printStackTrace(); - } - } - } - } - - int numThreads; - boolean running = false; - Vector jobs; - - /** - * Creates a pool of numThreads size. - * These threads sit around waiting for jobs to - * be posted to the list. - */ - public ThreadPool(int numThreads) { - this.numThreads = numThreads; - jobs = new Vector(37); - running = true; - - for (int i = 0; i < numThreads; i++) { - TaskThread t = new TaskThread(); - t.start(); - } - Log l = LogFactory.getLog("org.apache.nutch.util"); - if (l.isDebugEnabled()) { - l.debug("ThreadPool created with " + numThreads + " threads."); - } - } - - /** - * Gets a job from the queue, returns to worker thread. - * When the pool is closed down, return null for all - * obtainJob() requests. That tells the thread to - * shut down. - */ - Runnable obtainJob() { - Runnable job = null; - - synchronized (jobs) { - while (job == null && running) { - try { - if (jobs.size() == 0) { - jobs.wait(); - } - } catch (InterruptedException ie) { - } - - if (jobs.size() > 0) { - job = (Runnable) jobs.firstElement(); - jobs.removeElementAt(0); - } - } - } - - if (running) { - // Got a job from the queue - return job; - } else { - // Shut down the pool - return null; - } - } - - /** - * Post a Runnable to the queue. This will be - * picked up by an active thread. - */ - public void addJob(Runnable runnable) { - synchronized (jobs) { - jobs.add(runnable); - jobs.notifyAll(); - } - } - - /** - * Turn off the pool. Every thread, when finished with - * its current work, will realize that the pool is no - * longer running, and will exit. - */ - public void shutdown() { - running = false; - Log l = LogFactory.getLog("org.apache.nutch.util"); - if (l.isDebugEnabled()) { - l.debug("ThreadPool shutting down."); - } - } -} Index: src/java/org/apache/nutch/util/FibonacciHeap.java =================================================================== --- src/java/org/apache/nutch/util/FibonacciHeap.java (revision 561794) +++ src/java/org/apache/nutch/util/FibonacciHeap.java (working copy) @@ -1,279 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.nutch.util; - -import java.util.HashMap; - -/** - * A Fibonacci Heap, as described in Introduction to Algorithms by - * Charles E. Leiserson, Thomas H. Cormen, Ronald L. Rivest. - * - *
- *
- * A Fibonacci heap is a very efficient data structure for priority
- * queuing.
- *
- */
-public class FibonacciHeap {
- private FibonacciHeapNode min;
- private HashMap itemsToNodes;
-
- // private node class
- private static class FibonacciHeapNode {
- private Object userObject;
- private int priority;
-
- private FibonacciHeapNode parent;
- private FibonacciHeapNode prevSibling;
- private FibonacciHeapNode nextSibling;
- private FibonacciHeapNode child;
- private int degree;
- private boolean mark;
-
- FibonacciHeapNode(Object userObject, int priority) {
- this.userObject= userObject;
- this.priority= priority;
-
- this.parent= null;
- this.prevSibling= this;
- this.nextSibling= this;
- this.child= null;
- this.degree= 0;
- this.mark= false;
- }
-
- public String toString() {
- return "["+userObject+", "+degree+"]";
- }
- }
-
- /**
- * Creates a new FibonacciHeap
.
- */
- public FibonacciHeap() {
- this.min= null;
- this.itemsToNodes= new HashMap();
- }
-
- /**
- * Adds the Object item
, with the supplied
- * priority
.
- */
- public void add(Object item, int priority) {
- if (itemsToNodes.containsKey(item))
- throw new IllegalStateException("heap already contains item! (item= "
- + item + ")");
- FibonacciHeapNode newNode= new FibonacciHeapNode(item, priority);
- itemsToNodes.put(item, newNode);
-
- if (min == null) {
- min= newNode;
- } else {
- concatenateSiblings(newNode, min);
- if (newNode.priority < min.priority)
- min= newNode;
- }
- }
-
- /**
- * Returns true
if item
exists in this
- * FibonacciHeap
, false otherwise.
- */
- public boolean contains(Object item) {
- return itemsToNodes.containsKey(item);
- }
-
- // makes x's nextSibling and prevSibling point to itself
- private void removeFromSiblings(FibonacciHeapNode x) {
- if (x.nextSibling == x)
- return;
- x.nextSibling.prevSibling= x.prevSibling;
- x.prevSibling.nextSibling= x.nextSibling;
- x.nextSibling= x;
- x.prevSibling= x;
- }
-
- // joins siblings lists of a and b
- private void concatenateSiblings(FibonacciHeapNode a, FibonacciHeapNode b) {
- a.nextSibling.prevSibling= b;
- b.nextSibling.prevSibling= a;
- FibonacciHeapNode origAnext= a.nextSibling;
- a.nextSibling= b.nextSibling;
- b.nextSibling= origAnext;
- }
-
- /**
- * Returns the same Object that {@link #popMin()} would, without
- * removing it.
- */
- public Object peekMin() {
- if (min == null)
- return null;
- return min.userObject;
- }
-
- /**
- * Returns the number of objects in the heap.
- */
- public int size() {
- return itemsToNodes.size();
- }
-
- /**
- * Returns the object which has the lowest priority in the
- * heap. If the heap is empty, null
is returned.
- */
- public Object popMin() {
- if (min == null)
- return null;
- if (min.child != null) {
- FibonacciHeapNode tmp= min.child;
- // rempve parent pointers to min
- while (tmp.parent != null) {
- tmp.parent= null;
- tmp= tmp.nextSibling;
- }
- // add children of min to root list
- concatenateSiblings(tmp, min);
- }
- // remove min from root list
- FibonacciHeapNode oldMin= min;
- if (min.nextSibling == min) {
- min= null;
- } else {
- min= min.nextSibling;
- removeFromSiblings(oldMin);
- consolidate();
- }
- itemsToNodes.remove(oldMin.userObject);
- return oldMin.userObject;
- }
-
- // consolidates heaps of same degree
- private void consolidate() {
- int size= size();
- FibonacciHeapNode[] newRoots= new FibonacciHeapNode[size];
-
- FibonacciHeapNode node= min;
- FibonacciHeapNode start= min;
- do {
- FibonacciHeapNode x= node;
- int currDegree= node.degree;
- while (newRoots[currDegree] != null) {
- FibonacciHeapNode y= newRoots[currDegree];
- if (x.priority > y.priority) {
- FibonacciHeapNode tmp= x;
- x= y;
- y= tmp;
- }
- if (y == start) {
- start= start.nextSibling;
- }
- if (y == node) {
- node= node.prevSibling;
- }
- link(y, x);
- newRoots[currDegree++]= null;
- }
- newRoots[currDegree]= x;
- node= node.nextSibling;
- } while (node != start);
-
- min= null;
- for (int i= 0; i < newRoots.length; i++)
- if (newRoots[i] != null) {
- if ( (min == null)
- || (newRoots[i].priority < min.priority) )
- min= newRoots[i];
- }
- }
-
- // links y under x
- private void link(FibonacciHeapNode y, FibonacciHeapNode x) {
- removeFromSiblings(y);
- y.parent= x;
- if (x.child == null)
- x.child= y;
- else
- concatenateSiblings(x.child, y);
- x.degree++;
- y.mark= false;
- }
-
- /**
- * Decreases the priority
value associated with
- * item
.
- *
- *
- *
- * item
must exist in the heap, and it's current
- * priority must be greater than
priority
.
- *
- * @throws IllegalStateException if item
does not exist
- * in the heap, or if item
already has an equal or
- * lower priority than the suppliedpriority
.
- */
- public void decreaseKey(Object item, int priority) {
- FibonacciHeapNode node=
- (FibonacciHeapNode) itemsToNodes.get(item);
- if (node == null)
- throw new IllegalStateException("No such element: " + item);
- if (node.priority < priority)
- throw new IllegalStateException("decreaseKey(" + item + ", "
- + priority + ") called, but priority="
- + node.priority);
- node.priority= priority;
- FibonacciHeapNode parent= node.parent;
- if ( (parent != null) && (node.priority < parent.priority) ) {
- cut(node, parent);
- cascadingCut(parent);
- }
- if (node.priority < min.priority)
- min= node;
-
- }
-
- // cut node x from below y
- private void cut(FibonacciHeapNode x, FibonacciHeapNode y) {
- // remove x from y's children
- if (y.child == x)
- y.child= x.nextSibling;
- if (y.child == x)
- y.child= null;
-
- y.degree--;
- removeFromSiblings(x);
- concatenateSiblings(x, min);
- x.parent= null;
- x.mark= false;
-
- }
-
- private void cascadingCut(FibonacciHeapNode y) {
- FibonacciHeapNode z= y.parent;
- if (z != null) {
- if (!y.mark) {
- y.mark= true;
- } else {
- cut(y, z);
- cascadingCut(z);
- }
- }
- }
-
-}