summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn O. Pearce <sop@google.com>2009-06-13 15:15:13 -0700
committerShawn O. Pearce <sop@google.com>2009-06-13 15:15:13 -0700
commit622f47ae5bc43ec96dac8802b17f2ce7ebd9daf7 (patch)
tree9332b3010c43dcaff1ca8caffd45cfeb4298019b
parent2192d56bc3146071a74fd605798abb3350d40e6d (diff)
Use binary search when pulling lines from SparseFileContent
This is more efficient then a linear search, especially during the contains(int) operation where we expect a large number of negative results when looking at the post-image content when whitespace is being ignored. Signed-off-by: Shawn O. Pearce <sop@google.com>
-rw-r--r--src/main/java/com/google/gerrit/client/data/SparseFileContent.java43
1 files changed, 33 insertions, 10 deletions
diff --git a/src/main/java/com/google/gerrit/client/data/SparseFileContent.java b/src/main/java/com/google/gerrit/client/data/SparseFileContent.java
index 947f8572bd..2f0974f455 100644
--- a/src/main/java/com/google/gerrit/client/data/SparseFileContent.java
+++ b/src/main/java/com/google/gerrit/client/data/SparseFileContent.java
@@ -21,7 +21,8 @@ public class SparseFileContent {
protected List<Range> ranges;
protected int size;
protected boolean missingNewlineAtEnd;
- private transient int lastGetRange;
+
+ private transient int currentRangeIdx;
public SparseFileContent() {
ranges = new ArrayList<Range>();
@@ -56,17 +57,39 @@ public class SparseFileContent {
}
private String getLine(final int idx) {
- for (int i = lastGetRange; i < ranges.size(); i++) {
- final Range r = ranges.get(i);
- if (r.contains(idx)) {
- lastGetRange = i;
- return r.get(idx);
+ // Most requests are sequential in nature, fetching the next
+ // line from the current range, or the next range.
+ //
+ int high = ranges.size();
+ if (currentRangeIdx < high) {
+ Range cur = ranges.get(currentRangeIdx);
+ if (cur.contains(idx)) {
+ return cur.get(idx);
+ }
+
+ if (++currentRangeIdx < high) {
+ final Range next = ranges.get(currentRangeIdx);
+ if (next.contains(idx)) {
+ return next.get(idx);
+ }
}
}
- if (lastGetRange != 0) {
- lastGetRange = 0;
- return getLine(idx);
- }
+
+ // Binary search for the range, since we know its a sorted list.
+ //
+ int low = 0;
+ do {
+ final int mid = (low + high) / 2;
+ final Range cur = ranges.get(mid);
+ if (cur.contains(idx)) {
+ currentRangeIdx = mid;
+ return cur.get(idx);
+ }
+ if (cur.base < idx)
+ high = mid;
+ else
+ low = mid + 1;
+ } while (low < high);
return null;
}