View Javadoc
1   /*
2    * Copyright (C) 2011, Google Inc. and others
3    *
4    * This program and the accompanying materials are made available under the
5    * terms of the Eclipse Distribution License v. 1.0 which is available at
6    * https://www.eclipse.org/org/documents/edl-v10.php.
7    *
8    * SPDX-License-Identifier: BSD-3-Clause
9    */
10  
11  package org.eclipse.jgit.lib;
12  
13  import static org.junit.Assert.assertEquals;
14  import static org.junit.Assert.assertFalse;
15  import static org.junit.Assert.assertNotNull;
16  import static org.junit.Assert.assertSame;
17  import static org.junit.Assert.assertTrue;
18  import static org.junit.Assert.fail;
19  
20  import java.util.Iterator;
21  import java.util.NoSuchElementException;
22  
23  import org.junit.Before;
24  import org.junit.Test;
25  
26  public class ObjectIdSubclassMapTest {
27  	private MutableObjectId idBuf;
28  
29  	private SubId id_1, id_2, id_3, id_a31, id_b31;
30  
31  	@Before
32  	public void init() {
33  		idBuf = new MutableObjectId();
34  		id_1 = new SubId(id(1));
35  		id_2 = new SubId(id(2));
36  		id_3 = new SubId(id(3));
37  		id_a31 = new SubId(id(31));
38  		id_b31 = new SubId(id((1 << 8) + 31));
39  	}
40  
41  	@Test
42  	public void testEmptyMap() {
43  		ObjectIdSubclassMap<SubId> m = new ObjectIdSubclassMap<>();
44  		assertTrue(m.isEmpty());
45  		assertEquals(0, m.size());
46  
47  		Iterator<SubId> i = m.iterator();
48  		assertNotNull(i);
49  		assertFalse(i.hasNext());
50  
51  		assertFalse(m.contains(id(1)));
52  	}
53  
54  	@Test
55  	public void testAddGetAndContains() {
56  		ObjectIdSubclassMap<SubId> m = new ObjectIdSubclassMap<>();
57  		m.add(id_1);
58  		m.add(id_2);
59  		m.add(id_3);
60  		m.add(id_a31);
61  		m.add(id_b31);
62  		assertFalse(m.isEmpty());
63  		assertEquals(5, m.size());
64  
65  		assertSame(id_1, m.get(id_1));
66  		assertSame(id_1, m.get(id(1)));
67  		assertSame(id_1, m.get(id(1).copy()));
68  		assertSame(id_2, m.get(id(2).copy()));
69  		assertSame(id_3, m.get(id(3).copy()));
70  		assertSame(id_a31, m.get(id(31).copy()));
71  		assertSame(id_b31, m.get(id_b31.copy()));
72  
73  		assertTrue(m.contains(id_1));
74  	}
75  
76  	@Test
77  	public void testClear() {
78  		ObjectIdSubclassMap<SubId> m = new ObjectIdSubclassMap<>();
79  
80  		m.add(id_1);
81  		assertSame(id_1, m.get(id_1));
82  
83  		m.clear();
84  		assertTrue(m.isEmpty());
85  		assertEquals(0, m.size());
86  
87  		Iterator<SubId> i = m.iterator();
88  		assertNotNull(i);
89  		assertFalse(i.hasNext());
90  
91  		assertFalse(m.contains(id(1)));
92  	}
93  
94  	@Test
95  	public void testAddIfAbsent() {
96  		ObjectIdSubclassMap<SubId> m = new ObjectIdSubclassMap<>();
97  		m.add(id_1);
98  
99  		assertSame(id_1, m.addIfAbsent(new SubId(id_1)));
100 		assertEquals(1, m.size());
101 
102 		assertSame(id_2, m.addIfAbsent(id_2));
103 		assertEquals(2, m.size());
104 		assertSame(id_a31, m.addIfAbsent(id_a31));
105 		assertSame(id_b31, m.addIfAbsent(id_b31));
106 
107 		assertSame(id_a31, m.addIfAbsent(new SubId(id_a31)));
108 		assertSame(id_b31, m.addIfAbsent(new SubId(id_b31)));
109 		assertEquals(4, m.size());
110 	}
111 
112 	@Test
113 	public void testAddGrowsWithObjects() {
114 		ObjectIdSubclassMap<SubId> m = new ObjectIdSubclassMap<>();
115 		m.add(id_1);
116 		for (int i = 32; i < 8000; i++)
117 			m.add(new SubId(id(i)));
118 		assertEquals(8000 - 32 + 1, m.size());
119 
120 		assertSame(id_1, m.get(id_1.copy()));
121 		for (int i = 32; i < 8000; i++)
122 			assertTrue(m.contains(id(i)));
123 	}
124 
125 	@Test
126 	public void testAddIfAbsentGrowsWithObjects() {
127 		ObjectIdSubclassMap<SubId> m = new ObjectIdSubclassMap<>();
128 		m.add(id_1);
129 		for (int i = 32; i < 8000; i++)
130 			m.addIfAbsent(new SubId(id(i)));
131 		assertEquals(8000 - 32 + 1, m.size());
132 
133 		assertSame(id_1, m.get(id_1.copy()));
134 		for (int i = 32; i < 8000; i++)
135 			assertTrue(m.contains(id(i)));
136 	}
137 
138 	@Test
139 	public void testIterator() {
140 		ObjectIdSubclassMap<SubId> m = new ObjectIdSubclassMap<>();
141 		m.add(id_1);
142 		m.add(id_2);
143 		m.add(id_3);
144 
145 		Iterator<SubId> i = m.iterator();
146 		assertTrue(i.hasNext());
147 		assertSame(id_1, i.next());
148 		assertTrue(i.hasNext());
149 		assertSame(id_2, i.next());
150 		assertTrue(i.hasNext());
151 		assertSame(id_3, i.next());
152 
153 		assertFalse(i.hasNext());
154 		try {
155 			i.next();
156 			fail("did not fail on next with no next");
157 		} catch (NoSuchElementException expected) {
158 			// OK
159 		}
160 
161 		i = m.iterator();
162 		assertSame(id_1, i.next());
163 		try {
164 			i.remove();
165 			fail("did not fail on remove");
166 		} catch (UnsupportedOperationException expected) {
167 			// OK
168 		}
169 	}
170 
171 	private AnyObjectId id(int val) {
172 		// Using bytes 2 and 3 positions our value at the low end of idBuf.w1,
173 		// which is what ObjectIdSubclassMap uses for hashing. This makes
174 		// collisions likely, making collision testing easier.
175 
176 		val <<= 1;
177 
178 		idBuf.setByte(2, (val >>> 8) & 0xff);
179 		idBuf.setByte(3, val & 0xff);
180 		return idBuf;
181 	}
182 
183 	private static class SubId extends ObjectId {
184 		SubId(AnyObjectId id) {
185 			super(id);
186 		}
187 	}
188 }