View Javadoc

1   /*
2    *  Copyright 2006 Simon Raess
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   */
16  package net.sf.beep4j.internal.tcp;
17  
18  final class SlidingWindow {
19  	
20  	static final long MAX = 4294967295L;
21  	
22  	private long start;
23  	
24  	private long position;
25  	
26  	private long modulo = MAX + 1;
27  	
28  	private int windowSize;
29  	
30  	SlidingWindow(int size) {
31  		this(0, size);
32  	}
33  	
34  	SlidingWindow(long start, int size) {
35  		this.start = start;
36  		this.position = start;
37  		this.windowSize = size;
38  	}
39  	
40  	int getWindowSize() {
41  		return windowSize;
42  	}
43  	
44  	long getStart() {
45  		return start;
46  	}
47  	
48  	long getPosition() {
49  		return position;
50  	}
51  	
52  	long getEnd() {
53  		return (start + windowSize) % modulo;
54  	}
55  	
56  	void slide(long start, int size) {
57  		start = start % modulo;
58  		validateSlide(this.start, start, position, windowSize, size);		
59  		this.start = start;
60  		this.windowSize = size;
61  	}
62  	
63  	private void validateSlide(long oldStart, long newStart, long position, 
64  			int oldWindowSize, int newWindowSize) {
65  		if (newStart + newWindowSize < oldStart + oldWindowSize) {
66  			throw new IllegalArgumentException(
67  					"moving the right window edge to the left is not possible");
68  		}
69  		
70  		if (position >= oldStart) {
71  			if (newStart < oldStart || position < newStart) {
72  				throw new IllegalArgumentException("new start ("
73  						+ newStart + ") must be between old start ("
74  						+ oldStart + ") and position ("
75  						+ position + ")");
76  			}
77  		} else {
78  			if (newStart > position && newStart < oldStart) {
79  				throw new IllegalArgumentException("new start ("
80  						+ newStart + ") must be between old start ("
81  						+ oldStart + ") and position ("
82  						+ position + ")");
83  			}
84  		}
85  	}
86  	
87  	void moveBy(int offset) {
88  		validateMoveBy(offset);
89  		this.position = (position + offset) % modulo;
90  	}
91  
92  	private void validateMoveBy(int offset) {
93  		if (position < start) {
94  			if (position + offset > (start + windowSize) % modulo) {
95  				throw new IllegalArgumentException("cannot move position ("
96  						+ (position + offset) + ") beyond the end of the window ("
97  						+ (start + windowSize) + ")");
98  			}
99  		} else {
100 			if (position + offset > start + windowSize) {
101 				throw new IllegalArgumentException("cannot move position ("
102 						+ (position + offset) + ") beyond the end of the window ("
103 						+ (start + windowSize) + ")");
104 			}
105 		}
106 	}
107 	
108 	int remaining() {
109 		return (int) (getEnd() - position);
110 	}
111 	
112 	/* (non-Javadoc)
113 	 * @see java.lang.Object#toString()
114 	 */
115 	@Override
116 	public String toString() {
117 		return "[start=" + start + ",position=" + position + ",window=" + windowSize + "]";
118 	}
119 	
120 }