summaryrefslogtreecommitdiff
path: root/p1/Repository.java
diff options
context:
space:
mode:
Diffstat (limited to 'p1/Repository.java')
-rw-r--r--p1/Repository.java241
1 files changed, 241 insertions, 0 deletions
diff --git a/p1/Repository.java b/p1/Repository.java
new file mode 100644
index 0000000..dff76e7
--- /dev/null
+++ b/p1/Repository.java
@@ -0,0 +1,241 @@
+import java.util.*;
+import java.text.SimpleDateFormat;
+
+public class Repository {
+
+ private String name;
+ private Commit head;
+ private int size;
+
+ public Repository(String name) {
+ if (name == null || name.isEmpty()) {
+ throw new IllegalArgumentException("Repository needs a name!");
+ }
+
+ this.name = name;
+ }
+
+ public String getRepoHead() {
+ if (head == null) {
+ return null;
+ }
+ return head.id;
+ }
+
+ public int getRepoSize() {
+ Commit temp = head;
+ int size = 0;
+ while (temp != null) {
+ size++;
+ temp = temp.past;
+ }
+ this.size = size;
+ return size;
+ }
+
+ public String toString() {
+ if (head == null) {
+ return name + " - No commits";
+ }
+ return name + " - Current head: " + head.toString();
+ }
+
+ public boolean contains(String targetId) {
+ Commit temp = head;
+
+ while (temp != null) {
+ if (temp.id.equals(targetId)) {
+ return true;
+ }
+ temp = temp.past;
+ }
+
+ return false;
+ }
+
+ public String getHistory(int n) {
+ if (n <= 0) {
+ throw new IllegalArgumentException("do you want the history or not?");
+ }
+
+ Commit temp = head;
+ String history = "";
+ if (n > size) {
+ while (temp != null) {
+ history += temp.toString() + "\n";
+ temp = temp.past;
+ }
+ }
+
+ for (int i = 0; i < n && temp != null; i++) {
+ history += temp.toString() + "\n";
+ temp = temp.past;
+ }
+
+ return history;
+ }
+
+ public String commit(String message) {
+ if (head == null) {
+ head = new Commit(message);
+ return head.id;
+ }
+ Commit old = head;
+ head = new Commit(message, old);
+ size++;
+ return head.id;
+ }
+
+ public boolean drop(String targetId) {
+ // list is empty
+ if (head == null) {
+ return false;
+ }
+
+ size--;
+ Commit temp = head;
+
+ // front
+ if (temp.id.equals(targetId)) {
+ head = temp.past;
+ return true;
+ }
+
+ // middle
+ while (temp.past != null && temp.past.past != null) {
+ if (temp.past.id == targetId) {
+ temp.past = temp.past.past;
+ return true;
+ }
+ temp = temp.past;
+ }
+
+ // end
+ if (temp.past != null && temp.past.id.equals(targetId)) {
+ temp.past = null;
+ return true;
+ }
+
+ // if we get here, targetId was not found, return size to initial state
+ size++;
+ return false;
+ }
+
+ public void synchronize(Repository other) {
+ if (head == null && other.head == null) {
+ head = null;
+ } else if (head == null) {
+ head = other.head;
+ other.head = null;
+ } else if (other.head == null) {
+ other.head = null;
+ } else {
+ List<Commit> commitList = new ArrayList<>();
+ Comparator commitComparator = new Comparator<Commit>() {
+ public int compare(Commit one, Commit two) {
+ return Long.compare(one.timeStamp, two.timeStamp);
+ }
+ };
+ Commit temp = head;
+ while (temp != null) {
+ commitList.add(temp);
+ temp = temp.past;
+ }
+ temp = other.head;
+ while (temp != null) {
+ commitList.add(temp);
+ temp = temp.past;
+ }
+ commitList.sort(commitComparator);
+ Commit prev = null;
+ for (Commit commit : commitList) {
+ commit.past = prev;
+ prev = commit;
+ }
+ head = commitList.get(commitList.size() - 1);
+ other.head = null;
+ }
+ }
+ /**
+ * DO NOT MODIFY
+ * A class that represents a single commit in the repository.
+ * Commits are characterized by an identifier, a commit message,
+ * and the time that the commit was made. A commit also stores
+ * a reference to the immediately previous commit if it exists.
+ *
+ * Staff Note: You may notice that the comments in this
+ * class openly mention the fields of the class. This is fine
+ * because the fields of the Commit class are public. In general,
+ * be careful about revealing implementation details!
+ */
+ public class Commit {
+
+ private static int currentCommitID;
+
+ /**
+ * The time, in milliseconds, at which this commit was created.
+ */
+ public final long timeStamp;
+
+ /**
+ * A unique identifier for this commit.
+ */
+ public final String id;
+
+ /**
+ * A message describing the changes made in this commit.
+ */
+ public final String message;
+
+ /**
+ * A reference to the previous commit, if it exists. Otherwise, null.
+ */
+ public Commit past;
+
+ /**
+ * Constructs a commit object. The unique identifier and timestamp
+ * are automatically generated.
+ * @param message A message describing the changes made in this commit.
+ * @param past A reference to the commit made immediately before this
+ * commit.
+ */
+ public Commit(String message, Commit past) {
+ this.id = "" + currentCommitID++;
+ this.message = message;
+ this.timeStamp = System.currentTimeMillis();
+ this.past = past;
+ }
+
+ /**
+ * Constructs a commit object with no previous commit. The unique
+ * identifier and timestamp are automatically generated.
+ * @param message A message describing the changes made in this commit.
+ */
+ public Commit(String message) {
+ this(message, null);
+ }
+
+ /**
+ * Returns a string representation of this commit. The string
+ * representation consists of this commit's unique identifier,
+ * timestamp, and message, in the following form:
+ * "[identifier] at [timestamp]: [message]"
+ * @return The string representation of this collection.
+ */
+ @Override
+ public String toString() {
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z");
+ Date date = new Date(timeStamp);
+
+ return id + " at " + formatter.format(date) + ": " + message;
+ }
+
+ /**
+ * Resets the IDs of the commit nodes such that they reset to 0.
+ * Primarily for testing purposes.
+ */
+ public static void resetIds() {
+ Commit.currentCommitID = 0;
+ }
+ }
+}