summaryrefslogtreecommitdiff
path: root/p1/Repository.java
blob: dff76e783b4b9312aa9cf8089485fbbe93102723 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
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;
        }
    }
}