Merge "Add new performance logging"
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/logging/PerformanceLogContextTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/logging/PerformanceLogContextTest.java
new file mode 100644
index 0000000..e061833
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/logging/PerformanceLogContextTest.java
@@ -0,0 +1,66 @@
+package org.eclipse.jgit.logging;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import java.util.List;
+
+/**
+ * Tests for performance log context utilities.
+ */
+public class PerformanceLogContextTest {
+
+	@Test
+	public void testAddEvent() {
+		PerformanceLogRecord record = new PerformanceLogRecord("record", 0);
+		PerformanceLogContext.getInstance().addEvent(record);
+
+		List<PerformanceLogRecord> eventRecords = PerformanceLogContext
+				.getInstance().getEventRecords();
+		assertTrue(eventRecords.contains(record));
+		assertEquals(1, eventRecords.size());
+	}
+
+	@Test
+	public void testCleanEvents() {
+		PerformanceLogRecord record1 = new PerformanceLogRecord("record1", 0);
+		PerformanceLogContext.getInstance().addEvent(record1);
+
+		PerformanceLogRecord record2 = new PerformanceLogRecord("record2", 0);
+		PerformanceLogContext.getInstance().addEvent(record2);
+
+		PerformanceLogContext.getInstance().cleanEvents();
+		List<PerformanceLogRecord> eventRecords = PerformanceLogContext
+				.getInstance().getEventRecords();
+		assertEquals(0, eventRecords.size());
+	}
+
+	@Test
+	public void testAddEventsTwoThreads() {
+		TestRunnable thread1 = new TestRunnable("record1", 1);
+		TestRunnable thread2 = new TestRunnable("record2", 2);
+
+		new Thread(thread1).start();
+		new Thread(thread2).start();
+	}
+
+	private static class TestRunnable implements Runnable {
+		private String name;
+		private long durationMs;
+
+		public TestRunnable(String name, long durationMs) {
+			this.name = name;
+			this.durationMs = durationMs;
+		}
+
+		@Override
+		public void run() {
+			PerformanceLogRecord record = new PerformanceLogRecord(name,
+					durationMs);
+			PerformanceLogContext.getInstance().addEvent(record);
+			assertEquals(1, PerformanceLogContext.getInstance()
+					.getEventRecords().size());
+		}
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/logging/PerformanceLogContext.java b/org.eclipse.jgit/src/org/eclipse/jgit/logging/PerformanceLogContext.java
new file mode 100644
index 0000000..4421efd
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/logging/PerformanceLogContext.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2020, Google LLC  and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.logging;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Singleton that collects performance logs.
+ *
+ * @since 5.10
+ */
+public class PerformanceLogContext {
+	/** Singleton instance that stores the statistics. */
+	private static final PerformanceLogContext INSTANCE = new PerformanceLogContext();
+
+	/** List that stores events as performance logs. */
+	private final ThreadLocal<List<PerformanceLogRecord>> eventRecords = new ThreadLocal<>();
+
+	private PerformanceLogContext() {
+		eventRecords.set(new ArrayList<>());
+	}
+
+	/**
+	 * Get the instance of the context.
+	 *
+	 * @return instance of performance log context.
+	 */
+	public static PerformanceLogContext getInstance() {
+		return INSTANCE;
+	}
+
+	/**
+	 * Get the unmodifiable list of events as performance records.
+	 *
+	 * @return unmodifiable list of events as performance logs.
+	 */
+	public List<PerformanceLogRecord> getEventRecords() {
+		return Collections.unmodifiableList(eventRecords.get());
+	}
+
+	/**
+	 * Adds a performance log record to the current list of events.
+	 *
+	 * @param record
+	 *            performance log record that is going to be added.
+	 */
+	public void addEvent(PerformanceLogRecord record) {
+		eventRecords.get().add(record);
+	}
+
+	/**
+	 * Removes all of the existing records from the current list of events.
+	 */
+	public void cleanEvents() {
+		eventRecords.get().clear();
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/logging/PerformanceLogRecord.java b/org.eclipse.jgit/src/org/eclipse/jgit/logging/PerformanceLogRecord.java
new file mode 100644
index 0000000..3dc5f20
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/logging/PerformanceLogRecord.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2020, Google LLC  and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.logging;
+
+/**
+ * Class to register a performance log record.
+ *
+ * @since 5.10
+ */
+public class PerformanceLogRecord {
+	/** Name of the recorded event. */
+	private String name;
+
+	/** Duration of the recorded event in milliseconds. */
+	private long durationMs;
+
+	/**
+	 * Create a new performance log record for an event.
+	 *
+	 * @param name
+	 *            name of the event.
+	 * @param durationMs
+	 *            duration in milliseconds of the event.
+	 */
+	public PerformanceLogRecord(String name, long durationMs) {
+		this.name = name;
+		this.durationMs = durationMs;
+	}
+
+	/**
+	 * Get the name of the recorded event.
+	 *
+	 * @return name of the recorded event.
+	 */
+	public String getName() {
+		return name;
+	}
+
+	/**
+	 * Get the duration in milliseconds of the recorded event.
+	 *
+	 * @return duration in milliseconds of the recorded event.
+	 */
+	public long getDurationMs() {
+		return durationMs;
+	}
+}
\ No newline at end of file