aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DateRevPriorityQueue.java
diff options
context:
space:
mode:
Diffstat (limited to 'org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DateRevPriorityQueue.java')
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DateRevPriorityQueue.java150
1 files changed, 150 insertions, 0 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DateRevPriorityQueue.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DateRevPriorityQueue.java
new file mode 100644
index 0000000000..233dd64a3c
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DateRevPriorityQueue.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2023, GerritForge Ltd
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.revwalk;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.eclipse.jgit.annotations.Nullable;
+import org.eclipse.jgit.errors.IncorrectObjectTypeException;
+import org.eclipse.jgit.errors.MissingObjectException;
+import org.eclipse.jgit.internal.JGitText;
+
+import java.io.IOException;
+import java.util.Comparator;
+import java.util.PriorityQueue;
+
+/**
+ * A queue of commits sorted by commit time order using a Java PriorityQueue.
+ * For the commits with the same commit time insertion order will be preserved.
+ */
+class DateRevPriorityQueue extends DateRevQueue {
+ private PriorityQueue<RevCommitEntry> queue;
+
+ private final AtomicInteger sequence = new AtomicInteger(1);
+
+ /**
+ * Create an empty queue of commits sorted by commit time order.
+ */
+ public DateRevPriorityQueue() {
+ this(false);
+ }
+
+ /**
+ * Create an empty queue of commits sorted by commit time order.
+ *
+ * @param firstParent
+ * treat first element as a parent
+ */
+ DateRevPriorityQueue(boolean firstParent) {
+ super(firstParent);
+ initPriorityQueue();
+ }
+
+ private void initPriorityQueue() {
+ sequence.set(1);
+ queue = new PriorityQueue<>(Comparator.comparingInt(
+ (RevCommitEntry ent) -> ent.getEntry().getCommitTime())
+ .reversed()
+ .thenComparingInt(RevCommitEntry::getInsertSequenceNumber));
+ }
+
+ DateRevPriorityQueue(Generator s) throws MissingObjectException,
+ IncorrectObjectTypeException, IOException {
+ this(s.firstParent);
+ for (;;) {
+ final RevCommit c = s.next();
+ if (c == null) {
+ break;
+ }
+ add(c);
+ }
+ }
+
+ @Override
+ public void add(RevCommit c) {
+ // PriorityQueue does not accept null values. To keep the same behaviour
+ // do the same check and throw the same exception before creating entry
+ if (c == null) {
+ throw new NullPointerException(JGitText.get().nullRevCommit);
+ }
+ queue.add(new RevCommitEntry(sequence.getAndIncrement(), c));
+ }
+
+ @Override
+ public RevCommit next() {
+ RevCommitEntry entry = queue.poll();
+ return entry == null ? null : entry.getEntry();
+ }
+
+ /**
+ * Peek at the next commit, without removing it.
+ *
+ * @return the next available commit; null if there are no commits left.
+ */
+ @Override
+ public @Nullable RevCommit peek() {
+ RevCommitEntry entry = queue.peek();
+ return entry == null ? null : entry.getEntry();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void clear() {
+ sequence.set(1);
+ queue.clear();
+ }
+
+ @Override
+ boolean everbodyHasFlag(int f) {
+ return queue.stream().map(RevCommitEntry::getEntry)
+ .noneMatch(c -> (c.flags & f) == 0);
+ }
+
+ @Override
+ boolean anybodyHasFlag(int f) {
+ return queue.stream().map(RevCommitEntry::getEntry)
+ .anyMatch(c -> (c.flags & f) != 0);
+ }
+
+ @Override
+ int outputType() {
+ return outputType | SORT_COMMIT_TIME_DESC;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder s = new StringBuilder();
+ for (RevCommitEntry e : queue) {
+ describe(s, e.getEntry());
+ }
+ return s.toString();
+ }
+
+ private static class RevCommitEntry {
+ private final int insertSequenceNumber;
+
+ private final RevCommit entry;
+
+ public RevCommitEntry(int insertSequenceNumber, RevCommit entry) {
+ this.insertSequenceNumber = insertSequenceNumber;
+ this.entry = entry;
+ }
+
+ public int getInsertSequenceNumber() {
+ return insertSequenceNumber;
+ }
+
+ public RevCommit getEntry() {
+ return entry;
+ }
+ }
+}