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 } |
