1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.xnap.io;
21
22 import java.util.Iterator;
23 import java.util.LinkedList;
24
25 import org.xnap.util.Scheduler;
26
27 /***
28 *
29 */
30 public class BandwidthManager {
31
32
33
34 /***
35 * The default length of a tick.
36 */
37 public static final long TICK_LENGTH = 250;
38
39
40
41 private LinkedList listeners;
42 private long bandwidth;
43 private long totalBandwidth;
44 private int consumers;
45 private int externalConsumers;
46 private LinkedList queue = new LinkedList();
47 private int totalWeight;
48
49
50
51 public BandwidthManager()
52 {
53 Scheduler.run(0, TICK_LENGTH, new TickRunner());
54 }
55
56
57
58 public synchronized void addBandwidthListener()
59 {
60 }
61
62 /***
63 * Returns true, if bandwidth was allocated.
64 */
65 public synchronized boolean allocate(BandwidthManagable transfer)
66 throws InterruptedException
67 {
68 if (bandwidth > 0) {
69 totalWeight += transfer.getPriority() + 1;
70 queue.add(transfer);
71 this.wait();
72 return true;
73 }
74 else {
75 return false;
76 }
77 }
78
79 public synchronized void consume(int weight, boolean external)
80 {
81 if (external) {
82 externalConsumers += weight;
83 }
84 else {
85 consumers += weight;
86 }
87 updateBandwidth();
88 }
89
90 public synchronized void setBandwidth(long newValue)
91 {
92 totalBandwidth = newValue;
93 updateBandwidth();
94 }
95
96 private void updateBandwidth()
97 {
98 int total = externalConsumers + consumers;
99
100 bandwidth = (total > 0)
101 ? (totalBandwidth * consumers) / total
102 : 0;
103 bandwidth = (bandwidth * TICK_LENGTH) / 1000;
104 }
105
106
107
108 public class TickRunner implements Runnable
109 {
110 public void run()
111 {
112 synchronized (BandwidthManager.this) {
113 if (totalWeight > 0) {
114 long bandwidthPerTransfer = bandwidth / totalWeight;
115 for (Iterator i = queue.iterator(); i.hasNext();) {
116 BandwidthManagable transfer
117 = (BandwidthManagable)i.next();
118 transfer.setAllocated(bandwidthPerTransfer
119 * (transfer.getPriority() + 1));
120 }
121
122 totalWeight = 0;
123 queue.clear();
124
125 BandwidthManager.this.notifyAll();
126 }
127 }
128 }
129 }
130
131 }