From 625276067a489b9375ce6a791c94011aae71f9cf Mon Sep 17 00:00:00 2001
From: akwizgran <akwizgran@users.sourceforge.net>
Date: Fri, 26 Aug 2016 10:57:57 +0100
Subject: [PATCH] Define iteration order of BdfDictionary.

---
 .../briarproject/api/data/BdfDictionary.java  |  5 +-
 .../org/briarproject/api/data/BdfEntry.java   | 15 ++--
 .../briarproject/data/BdfDictionaryTest.java  | 68 +++++++++++++++++++
 3 files changed, 79 insertions(+), 9 deletions(-)

diff --git a/briar-api/src/org/briarproject/api/data/BdfDictionary.java b/briar-api/src/org/briarproject/api/data/BdfDictionary.java
index 920387cae1..24f133e82b 100644
--- a/briar-api/src/org/briarproject/api/data/BdfDictionary.java
+++ b/briar-api/src/org/briarproject/api/data/BdfDictionary.java
@@ -3,11 +3,10 @@ package org.briarproject.api.data;
 import org.briarproject.api.Bytes;
 import org.briarproject.api.FormatException;
 
-import java.util.Hashtable;
 import java.util.Map;
-import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentSkipListMap;
 
-public class BdfDictionary extends Hashtable<String, Object> {
+public class BdfDictionary extends ConcurrentSkipListMap<String, Object> {
 
 	public static final Object NULL_VALUE = new Object();
 
diff --git a/briar-api/src/org/briarproject/api/data/BdfEntry.java b/briar-api/src/org/briarproject/api/data/BdfEntry.java
index 0168d2a3c5..6b3176ee71 100644
--- a/briar-api/src/org/briarproject/api/data/BdfEntry.java
+++ b/briar-api/src/org/briarproject/api/data/BdfEntry.java
@@ -2,11 +2,10 @@ package org.briarproject.api.data;
 
 import java.util.Map.Entry;
 
-// This class is not thread-safe
-public class BdfEntry implements Entry<String, Object> {
+public class BdfEntry implements Entry<String, Object>, Comparable<BdfEntry> {
 
 	private final String key;
-	private Object value;
+	private final Object value;
 
 	public BdfEntry(String key, Object value) {
 		this.key = key;
@@ -25,8 +24,12 @@ public class BdfEntry implements Entry<String, Object> {
 
 	@Override
 	public Object setValue(Object value) {
-		Object oldValue = this.value;
-		this.value = value;
-		return oldValue;
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public int compareTo(BdfEntry e) {
+		if (e == this) return 0;
+		return key.compareTo(e.key);
 	}
 }
diff --git a/briar-tests/src/org/briarproject/data/BdfDictionaryTest.java b/briar-tests/src/org/briarproject/data/BdfDictionaryTest.java
index a7d7f07ba7..06ead4cdfc 100644
--- a/briar-tests/src/org/briarproject/data/BdfDictionaryTest.java
+++ b/briar-tests/src/org/briarproject/data/BdfDictionaryTest.java
@@ -7,10 +7,13 @@ import org.briarproject.api.data.BdfEntry;
 import org.junit.Test;
 
 import java.util.Collections;
+import java.util.Iterator;
+import java.util.Map.Entry;
 
 import static org.briarproject.api.data.BdfDictionary.NULL_VALUE;
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 public class BdfDictionaryTest extends BriarTestCase {
 
@@ -62,4 +65,69 @@ public class BdfDictionaryTest extends BriarTestCase {
 		assertEquals(123, bar.length);
 		assertArrayEquals(new byte[123], bar);
 	}
+
+	@Test
+	public void testKeySetIteratorIsOrderedByKeys() throws Exception {
+		BdfDictionary d = new BdfDictionary();
+		d.put("a", 1);
+		d.put("d", 4);
+		d.put("b", 2);
+		d.put("c", 3);
+		// Keys should be returned in their natural order
+		Iterator<String> it = d.keySet().iterator();
+		assertTrue(it.hasNext());
+		assertEquals("a", it.next());
+		assertTrue(it.hasNext());
+		assertEquals("b", it.next());
+		assertTrue(it.hasNext());
+		assertEquals("c", it.next());
+		assertTrue(it.hasNext());
+		assertEquals("d", it.next());
+	}
+
+	@Test
+	public void testValuesIteratorIsOrderedByKeys() throws Exception {
+		BdfDictionary d = new BdfDictionary();
+		d.put("a", 1);
+		d.put("d", 4);
+		d.put("b", 2);
+		d.put("c", 3);
+		// Values should be returned in the natural order of their keys
+		Iterator<Object> it = d.values().iterator();
+		assertTrue(it.hasNext());
+		assertEquals(1, it.next());
+		assertTrue(it.hasNext());
+		assertEquals(2, it.next());
+		assertTrue(it.hasNext());
+		assertEquals(3, it.next());
+		assertTrue(it.hasNext());
+		assertEquals(4, it.next());
+	}
+
+	@Test
+	public void testEntrySetIteratorIsOrderedByKeys() throws Exception {
+		BdfDictionary d = new BdfDictionary();
+		d.put("a", 1);
+		d.put("d", 4);
+		d.put("b", 2);
+		d.put("c", 3);
+		// Entries should be returned in the natural order of their keys
+		Iterator<Entry<String, Object>> it = d.entrySet().iterator();
+		assertTrue(it.hasNext());
+		Entry<String, Object> e = it.next();
+		assertEquals("a", e.getKey());
+		assertEquals(1, e.getValue());
+		assertTrue(it.hasNext());
+		e = it.next();
+		assertEquals("b", e.getKey());
+		assertEquals(2, e.getValue());
+		assertTrue(it.hasNext());
+		e = it.next();
+		assertEquals("c", e.getKey());
+		assertEquals(3, e.getValue());
+		assertTrue(it.hasNext());
+		e = it.next();
+		assertEquals("d", e.getKey());
+		assertEquals(4, e.getValue());
+	}
 }
-- 
GitLab