Merge "Move ChangeRebuilder#rebuildProject to RebuildNoteDb"
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeNotes.java b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeNotes.java
index edb5b4e..4967b0f 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeNotes.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeNotes.java
@@ -25,12 +25,11 @@
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
-import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSortedMap;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.ListMultimap;
-import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.Ordering;
@@ -349,7 +348,7 @@
// Lazy defensive copies of mutable ReviewDb types, to avoid polluting the
// ChangeNotesCache from handlers.
- private ImmutableMap<PatchSet.Id, PatchSet> patchSets;
+ private ImmutableSortedMap<PatchSet.Id, PatchSet> patchSets;
private ImmutableListMultimap<PatchSet.Id, PatchSetApproval> approvals;
@VisibleForTesting
@@ -368,18 +367,26 @@
return change;
}
- public ImmutableMap<PatchSet.Id, PatchSet> getPatchSets() {
+ public ImmutableSortedMap<PatchSet.Id, PatchSet> getPatchSets() {
if (patchSets == null) {
- patchSets = ImmutableMap.copyOf(
- Maps.transformValues(state.patchSets(), PatchSet::new));
+ ImmutableSortedMap.Builder<PatchSet.Id, PatchSet> b =
+ ImmutableSortedMap.orderedBy(comparing(PatchSet.Id::get));
+ for (Map.Entry<PatchSet.Id, PatchSet> e : state.patchSets()) {
+ b.put(e.getKey(), new PatchSet(e.getValue()));
+ }
+ patchSets = b.build();
}
return patchSets;
}
public ImmutableListMultimap<PatchSet.Id, PatchSetApproval> getApprovals() {
if (approvals == null) {
- approvals = ImmutableListMultimap.copyOf(
- Multimaps.transformValues(state.approvals(), PatchSetApproval::new));
+ ImmutableListMultimap.Builder<PatchSet.Id, PatchSetApproval> b =
+ ImmutableListMultimap.builder();
+ for (Map.Entry<PatchSet.Id, PatchSetApproval> e : state.approvals()) {
+ b.put(e.getKey(), new PatchSetApproval(e.getValue()));
+ }
+ approvals = b.build();
}
return approvals;
}
@@ -526,7 +533,7 @@
public PatchSet getCurrentPatchSet() {
PatchSet.Id psId = change.currentPatchSetId();
- return checkNotNull(state.patchSets().get(psId),
+ return checkNotNull(getPatchSets().get(psId),
"missing current patch set %s", psId.get());
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeNotesCache.java b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeNotesCache.java
index 198eb2f..73b7aec 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeNotesCache.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeNotesCache.java
@@ -101,7 +101,8 @@
+ P // status
+ P + set(state.pastAssignees(), K)
+ P + set(state.hashtags(), str(10))
- + P + map(state.patchSets(), patchSet())
+ + P + list(state.patchSets(), patchSet())
+ + P + list(state.allPastReviewers(), approval())
+ P + list(state.reviewerUpdates(), 4 * O + K + K + P)
+ P + list(state.submitRecords(), P + list(2, str(4) + P + K) + P)
+ P + list(state.allChangeMessages(), changeMessage())
@@ -172,6 +173,15 @@
+ P; // pushCertificate
}
+ private static int approval() {
+ return O
+ + P + patchSetId() + P + K + P + O + str(10)
+ + 2 // value
+ + P + T // granted
+ + P // tag
+ + P; // realAccountId
+ }
+
private static int changeMessage() {
int key = K + str(20);
return O
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeNotesState.java b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeNotesState.java
index 67eb328..e0f7920 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeNotesState.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/ChangeNotesState.java
@@ -15,14 +15,12 @@
package com.google.gerrit.server.notedb;
import static com.google.common.base.Preconditions.checkNotNull;
-import static java.util.Comparator.comparing;
import com.google.auto.value.AutoValue;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSortedMap;
import com.google.common.collect.Multimap;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.data.SubmitRecord;
@@ -59,17 +57,17 @@
return new AutoValue_ChangeNotesState(
change.getId(),
null,
- ImmutableSet.<Account.Id>of(),
- ImmutableSet.<String>of(),
- ImmutableSortedMap.<PatchSet.Id, PatchSet>of(),
- ImmutableListMultimap.<PatchSet.Id, PatchSetApproval>of(),
+ ImmutableSet.of(),
+ ImmutableSet.of(),
+ ImmutableList.of(),
+ ImmutableList.of(),
ReviewerSet.empty(),
- ImmutableList.<Account.Id>of(),
- ImmutableList.<ReviewerStatusUpdate>of(),
- ImmutableList.<SubmitRecord>of(),
- ImmutableList.<ChangeMessage>of(),
- ImmutableListMultimap.<PatchSet.Id, ChangeMessage>of(),
- ImmutableListMultimap.<RevId, Comment>of());
+ ImmutableList.of(),
+ ImmutableList.of(),
+ ImmutableList.of(),
+ ImmutableList.of(),
+ ImmutableListMultimap.of(),
+ ImmutableListMultimap.of());
}
static ChangeNotesState create(
@@ -117,8 +115,8 @@
status),
ImmutableSet.copyOf(pastAssignees),
ImmutableSet.copyOf(hashtags),
- ImmutableSortedMap.copyOf(patchSets, comparing(PatchSet.Id::get)),
- ImmutableListMultimap.copyOf(approvals),
+ ImmutableList.copyOf(patchSets.entrySet()),
+ ImmutableList.copyOf(approvals.entries()),
reviewers,
ImmutableList.copyOf(allPastReviewers),
ImmutableList.copyOf(reviewerUpdates),
@@ -161,8 +159,8 @@
// Other related to this Change.
abstract ImmutableSet<Account.Id> pastAssignees();
abstract ImmutableSet<String> hashtags();
- abstract ImmutableSortedMap<PatchSet.Id, PatchSet> patchSets();
- abstract ImmutableListMultimap<PatchSet.Id, PatchSetApproval> approvals();
+ abstract ImmutableList<Map.Entry<PatchSet.Id, PatchSet>> patchSets();
+ abstract ImmutableList<Map.Entry<PatchSet.Id, PatchSetApproval>> approvals();
abstract ReviewerSet reviewers();
abstract ImmutableList<Account.Id> allPastReviewers();
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/rebuild/EventList.java b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/rebuild/EventList.java
index 4f6e2e8..363cfd7 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/notedb/rebuild/EventList.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/notedb/rebuild/EventList.java
@@ -23,21 +23,27 @@
import java.sql.Timestamp;
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.Objects;
-class EventList<E extends Event> extends ArrayList<E> {
- private static final long serialVersionUID = 1L;
+class EventList<E extends Event> implements Iterable<E> {
+ private final ArrayList<E> list = new ArrayList<>();
- private E getLast() {
- return get(size() - 1);
+ @Override
+ public Iterator<E> iterator() {
+ return list.iterator();
}
- private long getLastTime() {
- return getLast().when.getTime();
+ void add(E e) {
+ list.add(e);
}
- private long getFirstTime() {
- return get(0).when.getTime();
+ void clear() {
+ list.clear();
+ }
+
+ boolean isEmpty() {
+ return list.isEmpty();
}
boolean canAdd(E e) {
@@ -114,4 +120,24 @@
String getTag() {
return getLast().tag;
}
+
+ private E get(int i) {
+ return list.get(i);
+ }
+
+ private int size() {
+ return list.size();
+ }
+
+ private E getLast() {
+ return list.get(list.size() - 1);
+ }
+
+ private long getLastTime() {
+ return getLast().when.getTime();
+ }
+
+ private long getFirstTime() {
+ return list.get(0).when.getTime();
+ }
}
diff --git a/polygerrit-ui/app/behaviors/gr-path-list-behavior/gr-path-list-behavior_test.html b/polygerrit-ui/app/behaviors/gr-path-list-behavior/gr-path-list-behavior_test.html
index 530b7be..adf0bf1 100644
--- a/polygerrit-ui/app/behaviors/gr-path-list-behavior/gr-path-list-behavior_test.html
+++ b/polygerrit-ui/app/behaviors/gr-path-list-behavior/gr-path-list-behavior_test.html
@@ -13,6 +13,8 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
+<!-- Polymer included for the html import polyfill. -->
+<script src="../../../bower_components/webcomponentsjs/webcomponents.min.js"></script>
<script src="../../bower_components/web-component-tester/browser.js"></script>
<title>gr-path-list-behavior</title>
diff --git a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.js b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.js
index 1a6759b..96c6f93 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.js
@@ -375,6 +375,12 @@
},
_handleGetDiffError: function(response) {
+ // Loading the diff may respond with 409 if the file is too large. In this
+ // case, use a toast error..
+ if (response.status === 409) {
+ this.fire('server-error', {response: response});
+ return;
+ }
this.fire('page-error', {response: response});
},
@@ -386,8 +392,8 @@
this.path,
this._handleGetDiffError.bind(this)).then(function(diff) {
this.filesWeblinks = {
- meta_a: diff.meta_a && diff.meta_a.web_links,
- meta_b: diff.meta_b && diff.meta_b.web_links,
+ meta_a: diff && diff.meta_a && diff.meta_a.web_links,
+ meta_b: diff && diff.meta_b && diff.meta_b.web_links,
};
return diff;
}.bind(this));
diff --git a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff_test.html b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff_test.html
index b9b49c0..20ed61f 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff_test.html
@@ -327,6 +327,16 @@
});
content.click();
});
+
+ test('_getDiff handles null diff responses', function(done) {
+ stub('gr-rest-api-interface', {
+ getDiff: function() { return Promise.resolve(null); },
+ });
+ element.changeNum = 123;
+ element.patchRange = {basePatchNum: 1, patchNum: 2};
+ element.path = 'file.txt';
+ element._getDiff().then(done);
+ });
});
suite('logged in', function() {
diff --git a/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete.js b/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete.js
index 31918dd..601a056 100644
--- a/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete.js
+++ b/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete.js
@@ -118,11 +118,11 @@
},
attached: function() {
- this.listen(document.body, 'click', '_handleBodyClick');
+ this.listen(document.body, 'tap', '_handleBodyTap');
},
detached: function() {
- this.unlisten(document.body, 'click', '_handleBodyClick');
+ this.unlisten(document.body, 'tap', '_handleBodyTap');
},
get focusStart() {
@@ -233,7 +233,7 @@
}
},
- _handleBodyClick: function(e) {
+ _handleBodyTap: function(e) {
var eventPath = Polymer.dom(e).path;
for (var i = 0; i < eventPath.length; i++) {
if (eventPath[i] === this) {
@@ -244,6 +244,7 @@
},
_handleSuggestionTap: function(e) {
+ e.stopPropagation();
this.$.cursor.setCursor(e.target);
this._commit();
this.focus();
diff --git a/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete_test.html b/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete_test.html
index 7a26e72..685f568 100644
--- a/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete_test.html
@@ -290,6 +290,7 @@
assert.isTrue(focusSpy.called);
assert.isTrue(commitSpy.called);
assert.isTrue(element.$.suggestions.hasAttribute('hidden'));
+ assert.isTrue(element._focused);
focusSpy.restore();
commitSpy.restore();
});