Mercurial > hg4j
comparison src/org/tmatesoft/hg/internal/BatchRangeHelper.java @ 520:1ee452f31187
Experimental support for inverse direction history walking. Refactored/streamlined cancellation in HgLogCommand and down the stack
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Fri, 21 Dec 2012 21:20:26 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
519:934037edbea0 | 520:1ee452f31187 |
---|---|
1 /* | |
2 * Copyright (c) 2012 TMate Software Ltd | |
3 * | |
4 * This program is free software; you can redistribute it and/or modify | |
5 * it under the terms of the GNU General Public License as published by | |
6 * the Free Software Foundation; version 2 of the License. | |
7 * | |
8 * This program is distributed in the hope that it will be useful, | |
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 * GNU General Public License for more details. | |
12 * | |
13 * For information on how to redistribute this software under | |
14 * the terms of a license other than GNU General Public License | |
15 * contact TMate Software at support@hg4j.com | |
16 */ | |
17 package org.tmatesoft.hg.internal; | |
18 | |
19 import java.util.Arrays; | |
20 import java.util.NoSuchElementException; | |
21 | |
22 /** | |
23 * Helper to break given range [start..end] (inclusive bounds) to series of ranges, | |
24 * all but last are of batchSize length, and the last one is at most of batchSize+batchSizeTolerance length. | |
25 * | |
26 * Range is [{@link #start()rangeStart}..{@link #end() rangeEnd}], where rangeStart is less or equal to rangeEnd. | |
27 * | |
28 * When reverse range iteration is requested, original range is iterated from end to start, but the subranges | |
29 * boundaries are in natural order. i.e. for 0..100, 10 first subrange would be [91..100], not [100..91]. This | |
30 * helps clients of this class to get [start()..end()] in natural order regardless of iteration direction. | |
31 * | |
32 * Note, this class (and its treatment of inclusive boundaries) is designed solely for use with methods that navigate | |
33 * revlogs and take (start,end) pair of inclusive range. | |
34 * | |
35 * @author Artem Tikhomirov | |
36 * @author TMate Software Ltd. | |
37 */ | |
38 public class BatchRangeHelper { | |
39 | |
40 private final int rangeCount; | |
41 private final int rangeDelta; | |
42 private final int nextValueDelta; | |
43 private final int firstBoundary, lastBoundary; | |
44 private int rangeIndex, rangeValue, rangeStart, rangeEnd; | |
45 | |
46 public BatchRangeHelper(int start, int end, int batchSize, boolean reverse) { | |
47 this(start, end, batchSize, batchSize/5, reverse); | |
48 } | |
49 | |
50 public BatchRangeHelper(int start, int end, int batchSize, int batchSizeTolerance, boolean reverse) { | |
51 assert end >= start; | |
52 assert start >= 0; | |
53 assert batchSize > 0; | |
54 assert batchSizeTolerance >= 0; | |
55 final int totalElements = end-start+1; | |
56 int batchRangeCount = totalElements / batchSize; | |
57 // batchRangeCount == 0, totalElements > 0 => need at least 1 range | |
58 if (batchRangeCount == 0 || batchRangeCount*batchSize+batchSizeTolerance < totalElements) { | |
59 batchRangeCount++; | |
60 } | |
61 rangeCount = batchRangeCount; | |
62 rangeDelta = batchSize-1; // ranges are inclusive, and always grow naturally. | |
63 nextValueDelta = reverse ? -batchSize : batchSize; | |
64 firstBoundary = reverse ? end-rangeDelta : start; | |
65 lastBoundary = reverse ? start : end; | |
66 reset(); | |
67 } | |
68 | |
69 public boolean hasNext() { | |
70 return rangeIndex < rangeCount; | |
71 } | |
72 | |
73 public void next() { | |
74 if (!hasNext()) { | |
75 throw new NoSuchElementException(); | |
76 } | |
77 rangeStart = rangeValue; | |
78 rangeEnd = rangeValue + rangeDelta; | |
79 rangeValue += nextValueDelta; | |
80 if (++rangeIndex >= rangeCount) { | |
81 if (nextValueDelta < 0) { | |
82 // reverse iteration, lastBoundary represents start | |
83 rangeStart = lastBoundary; | |
84 } else { | |
85 // lastBoundary represents end | |
86 rangeEnd = lastBoundary; | |
87 } | |
88 } | |
89 } | |
90 | |
91 public int start() { | |
92 return rangeStart; | |
93 } | |
94 | |
95 public int end() { | |
96 return rangeEnd; | |
97 } | |
98 | |
99 public BatchRangeHelper reset() { | |
100 rangeValue = firstBoundary; | |
101 rangeIndex = 0; | |
102 return this; | |
103 } | |
104 | |
105 public int[] toArray() { | |
106 int[] rv = new int[rangeCount*2]; | |
107 reset(); | |
108 int i = 0; | |
109 while (hasNext()) { | |
110 next(); | |
111 rv[i++] = start(); | |
112 rv[i++] = end(); | |
113 } | |
114 reset(); | |
115 return rv; | |
116 } | |
117 | |
118 public static void main(String[] args) { | |
119 System.out.println("With remainder within tolerance"); | |
120 System.out.println(Arrays.toString(new BatchRangeHelper(0, 102, 10, 4, false).toArray())); | |
121 System.out.println(Arrays.toString(new BatchRangeHelper(0, 102, 10, 4, true).toArray())); | |
122 System.out.println("With remainder out of tolerance"); | |
123 System.out.println(Arrays.toString(new BatchRangeHelper(0, 102, 10, 2, false).toArray())); | |
124 System.out.println(Arrays.toString(new BatchRangeHelper(0, 102, 10, 2, true).toArray())); | |
125 System.out.println("Range smaller than batch"); | |
126 System.out.println(Arrays.toString(new BatchRangeHelper(1, 9, 10, false).toArray())); | |
127 System.out.println(Arrays.toString(new BatchRangeHelper(1, 9, 10, true).toArray())); | |
128 System.out.println("Range smaller than batch and smaller than tolerance"); | |
129 System.out.println(Arrays.toString(new BatchRangeHelper(1, 9, 10, 20, false).toArray())); | |
130 System.out.println(Arrays.toString(new BatchRangeHelper(1, 9, 10, 20, true).toArray())); | |
131 System.out.println("Zero tolerance"); | |
132 System.out.println(Arrays.toString(new BatchRangeHelper(0, 100, 10, 0, false).toArray())); | |
133 System.out.println(Arrays.toString(new BatchRangeHelper(0, 100, 10, 0, true).toArray())); | |
134 System.out.println("Right to boundary"); | |
135 System.out.println(Arrays.toString(new BatchRangeHelper(1, 100, 10, false).toArray())); | |
136 System.out.println(Arrays.toString(new BatchRangeHelper(1, 100, 10, true).toArray())); | |
137 } | |
138 } |