1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
113
114
115 @Override
116 public String toString() {
117 return "[start=" + start + ",position=" + position + ",window=" + windowSize + "]";
118 }
119
120 }