From ccd6ed9ff01c7225c8ccd04989d54c8e94d35a3b Mon Sep 17 00:00:00 2001 From: akwizgran Date: Mon, 20 Feb 2023 11:56:13 +0000 Subject: [PATCH] Add fast path for writing BdfDictionaries. --- .../bramble/data/BdfWriterImpl.java | 30 ++++++++++++------- .../bramble/data/BdfWriterImplTest.java | 21 +++++++++++-- 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/bramble-core/src/main/java/org/briarproject/bramble/data/BdfWriterImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/data/BdfWriterImpl.java index 263f7bdde..ca9204923 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/data/BdfWriterImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/data/BdfWriterImpl.java @@ -2,6 +2,7 @@ package org.briarproject.bramble.data; import org.briarproject.bramble.api.Bytes; import org.briarproject.bramble.api.FormatException; +import org.briarproject.bramble.api.data.BdfDictionary; import org.briarproject.bramble.api.data.BdfWriter; import org.briarproject.nullsafety.NotNullByDefault; @@ -11,6 +12,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import javax.annotation.Nullable; import javax.annotation.concurrent.NotThreadSafe; @@ -171,16 +173,24 @@ final class BdfWriterImpl implements BdfWriter { @Override public void writeDictionary(Map m) throws IOException { out.write(DICTIONARY); - // Write entries in canonical order - List keys = new ArrayList<>(m.size()); - for (Object k : m.keySet()) { - if (!(k instanceof String)) throw new FormatException(); - keys.add((String) k); - } - sort(keys); - for (String key : keys) { - writeString(key); - writeObject(m.get(key)); + if (m instanceof BdfDictionary) { + // Entries are already sorted and keys are known to be strings + for (Entry e : ((BdfDictionary) m).entrySet()) { + writeString(e.getKey()); + writeObject(e.getValue()); + } + } else { + // Check that keys are strings, write entries in canonical order + List keys = new ArrayList<>(m.size()); + for (Object k : m.keySet()) { + if (!(k instanceof String)) throw new FormatException(); + keys.add((String) k); + } + sort(keys); + for (String key : keys) { + writeString(key); + writeObject(m.get(key)); + } } out.write(END); } diff --git a/bramble-core/src/test/java/org/briarproject/bramble/data/BdfWriterImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/data/BdfWriterImplTest.java index 6a4e9cdb6..0d3af445c 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/data/BdfWriterImplTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/data/BdfWriterImplTest.java @@ -1,5 +1,6 @@ package org.briarproject.bramble.data; +import org.briarproject.bramble.api.data.BdfDictionary; import org.briarproject.bramble.test.BrambleTestCase; import org.briarproject.bramble.util.StringUtils; import org.junit.Test; @@ -168,9 +169,11 @@ public class BdfWriterImplTest extends BrambleTestCase { @Test public void testWriteDictionary() throws IOException { - // Use LinkedHashMap to get predictable iteration order + // Add entries to dictionary in descending order - they should be + // output in ascending order. Use LinkedHashMap to get predictable + // iteration order Map m = new LinkedHashMap<>(); - for (int i = 0; i < 4; i++) m.put(String.valueOf(i), i); + for (int i = 3; i >= 0; i--) m.put(String.valueOf(i), i); w.writeDictionary(m); // DICTIONARY tag, keys as strings and values as integers, END tag checkContents("70" + "41" + "01" + "30" + "21" + "00" + @@ -179,6 +182,20 @@ public class BdfWriterImplTest extends BrambleTestCase { "41" + "01" + "33" + "21" + "03" + "80"); } + @Test + public void testWriteBdfDictionary() throws IOException { + // Add entries to dictionary in descending order - they should be + // output in ascending order + BdfDictionary d = new BdfDictionary(); + for (int i = 3; i >= 0; i--) d.put(String.valueOf(i), i); + w.writeDictionary(d); + // DICTIONARY tag, keys as strings and values as integers, END tag + checkContents("70" + "41" + "01" + "30" + "21" + "00" + + "41" + "01" + "31" + "21" + "01" + + "41" + "01" + "32" + "21" + "02" + + "41" + "01" + "33" + "21" + "03" + "80"); + } + @Test public void testWriteNestedDictionariesAndLists() throws IOException { Map inner = new LinkedHashMap<>();