parent
							
								
									d1e591b448
								
							
						
					
					
						commit
						5bdc1c881b
					
				| @ -0,0 +1,104 @@ | ||||
| /* | ||||
|  * 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 com.arialyy.aria.core.common; | ||||
| 
 | ||||
| /** | ||||
|  * 速度限制 | ||||
|  */ | ||||
| public class BandwidthLimiter { | ||||
|   public static int maxBandWith = 2 * 1024; //KB
 | ||||
| 
 | ||||
|   /* KB */ | ||||
|   private static Long KB = 1024L; | ||||
|   /* The smallest count chunk length in bytes */ | ||||
|   private static Long CHUNK_LENGTH = 1024L; | ||||
|   /* How many bytes will be sent or receive */ | ||||
|   private int bytesWillBeSentOrReceive = 0; | ||||
|   /* When the last piece was sent or receive */ | ||||
|   private long lastPieceSentOrReceiveTick = System.nanoTime(); | ||||
|   /* Default rate is 1024KB/s */ | ||||
|   private int maxRate = 1024; | ||||
|   /* Time cost for sending CHUNK_LENGTH bytes in nanoseconds */ | ||||
|   private long timeCostPerChunk = (1000000000L * CHUNK_LENGTH) | ||||
|       / (this.maxRate * KB); | ||||
| 
 | ||||
|   /** | ||||
|    * Initialize a BandwidthLimiter object with a certain rate. | ||||
|    * | ||||
|    * @param maxRate the download or upload speed in KBytes | ||||
|    */ | ||||
|   public BandwidthLimiter(int maxRate, int threadNum) { | ||||
|     if (threadNum > 1) { | ||||
|       maxRate = maxRate / threadNum; | ||||
|     } | ||||
|     this.setMaxRate(maxRate); | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * Set the max upload or download rate in KB/s. maxRate must be grater than | ||||
|    * 0. If maxRate is zero, it means there is no bandwidth limit. | ||||
|    * | ||||
|    * @param maxRate If maxRate is zero, it means there is no bandwidth limit. | ||||
|    * @throws IllegalArgumentException | ||||
|    */ | ||||
|   public synchronized void setMaxRate(int maxRate) | ||||
|       throws IllegalArgumentException { | ||||
|     if (maxRate < 0) { | ||||
|       throw new IllegalArgumentException("maxRate can not less than 0"); | ||||
|     } | ||||
|     this.maxRate = maxRate; | ||||
|     if (maxRate == 0) { | ||||
|       this.timeCostPerChunk = 0; | ||||
|     } else { | ||||
|       this.timeCostPerChunk = (1000000000L * CHUNK_LENGTH) | ||||
|           / (this.maxRate * KB); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * Next 1 byte should do bandwidth limit. | ||||
|    */ | ||||
|   public synchronized void limitNextBytes() { | ||||
|     this.limitNextBytes(1); | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * Next len bytes should do bandwidth limit | ||||
|    */ | ||||
|   public synchronized void limitNextBytes(int len) { | ||||
|     this.bytesWillBeSentOrReceive += len; | ||||
| 
 | ||||
|     /* We have sent CHUNK_LENGTH bytes */ | ||||
|     while (this.bytesWillBeSentOrReceive > CHUNK_LENGTH) { | ||||
|       long nowTick = System.nanoTime(); | ||||
|       long missedTime = this.timeCostPerChunk | ||||
|           - (nowTick - this.lastPieceSentOrReceiveTick); | ||||
|       if (missedTime > 0) { | ||||
|         try { | ||||
|           Thread.currentThread().sleep(missedTime / 1000000, | ||||
|               (int) (missedTime % 1000000)); | ||||
|         } catch (InterruptedException e) { | ||||
|           e.printStackTrace(); | ||||
|         } | ||||
|       } | ||||
|       this.bytesWillBeSentOrReceive -= CHUNK_LENGTH; | ||||
|       this.lastPieceSentOrReceiveTick = nowTick | ||||
|           + (missedTime > 0 ? missedTime : 0); | ||||
|     } | ||||
|   } | ||||
| } | ||||
					Loading…
					
					
				
		Reference in new issue