]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.utils.thread/src/org/simantics/utils/threads/Throttler.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.utils.thread / src / org / simantics / utils / threads / Throttler.java
1 /*******************************************************************************
2  * Copyright (c) 2012 Association for Decentralized Information Management in
3  * Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.utils.threads;
13
14 import java.util.concurrent.TimeUnit;
15
16 /**
17  * @author Antti Villberg
18  */
19 public class Throttler implements Runnable {
20
21         final private IThreadWorkQueue thread;
22         final private int interval;
23
24         private boolean isScheduling = false;
25
26         private long[] dispatchTimes;
27         private long lastQueueTime;
28
29         private int dispatchTimePointer = 0;
30
31         private Runnable todo;
32
33         public Throttler(IThreadWorkQueue thread, int interval, int queueLength) {
34
35                 this.thread = thread;
36                 this.interval = interval;
37
38                 long currentTime = System.currentTimeMillis();
39
40                 dispatchTimes = new long[queueLength];
41                 for(int i=0;i<dispatchTimes.length;i++)
42                         dispatchTimes[i] = currentTime - interval;
43
44                 lastQueueTime = Long.MAX_VALUE;
45
46         }
47
48         public synchronized void run() {
49
50                 if(todo != null) {
51                         thread.asyncExec(todo);
52                         todo = null;
53                         ThreadUtils.getTimer().schedule(this, interval, TimeUnit.MILLISECONDS);
54                 } else {
55                         isScheduling = false;
56                 }
57
58         }
59         
60         public synchronized void schedule(Runnable r) {
61
62                 assert(thread.currentThreadAccess());
63                 
64                 dispatch(r);
65
66                 if(getQueueTime() < interval) {
67
68                         isScheduling = true;
69                         ThreadUtils.getTimer().schedule(this, interval, TimeUnit.MILLISECONDS);
70
71                 }
72
73         }
74
75         private long getQueueTime() {
76                 return lastQueueTime;
77         }
78
79         private void dispatch(Runnable runnable) {
80
81                 long time = System.currentTimeMillis();
82                 lastQueueTime = time - dispatchTimes[dispatchTimePointer];
83                 dispatchTimes[dispatchTimePointer] = time;
84                 dispatchTimePointer = ((dispatchTimePointer+1) % dispatchTimes.length);
85
86                 if(!isScheduling) {
87                         todo = null;
88                         runnable.run();
89                 } else {
90                         todo = runnable;
91                 }
92
93         }
94
95 }