diff options
author | Cowtowncoder <tatu.saloranta@iki.fi> | 2015-05-18 16:25:36 -0700 |
---|---|---|
committer | Cowtowncoder <tatu.saloranta@iki.fi> | 2015-05-18 16:25:36 -0700 |
commit | 3c5989b769236f7f23cdac050e0970b065479cb5 (patch) | |
tree | 68d62923287c0d739b67cbdddc89c0de209139d4 /attic | |
parent | ee1c51a66a76a5d60790e429e343284a3ea9293d (diff) | |
download | jackson-databind-3c5989b769236f7f23cdac050e0970b065479cb5.tar.gz |
Minor cleanup: remove unused helper class
Diffstat (limited to 'attic')
-rw-r--r-- | attic/ContainerBuilder.java | 247 | ||||
-rw-r--r-- | attic/README.md | 3 |
2 files changed, 250 insertions, 0 deletions
diff --git a/attic/ContainerBuilder.java b/attic/ContainerBuilder.java new file mode 100644 index 000000000..47cd40943 --- /dev/null +++ b/attic/ContainerBuilder.java @@ -0,0 +1,247 @@ +package com.fasterxml.jackson.databind.util; + +import java.lang.reflect.Array; +import java.util.*; + +/** + * Helper class used for constructing "untyped" {@link java.util.List}, + * {@link java.util.Map} and <code>Object[]</code> values. + * Could help performance if a single instance can be used for building + * nested Maps, Lists/Object[] of relatively small size. + * Whether use makes sense depends; currently this class is not used. + */ +public final class ContainerBuilder +{ + private final static int MAX_BUF = 1000; + + /** + * Buffer in which contents are being buffered (except for cases where + * size has grown too big to bother with separate buffer) + */ + private Object[] b; + + /** + * Pointer to the next available slot in temporary buffer. + */ + private int tail; + + /** + * When building potentially multiple containers, we need to keep track of + * the starting pointer for the current container. + */ + private int start; + + /** + * In cases where size of buffered contents has grown big enough that buffering + * does not make sense, an actual {@link java.util.List} will be constructed + * earlier and used instead of buffering. + */ + private List<Object> list; + + /** + * Similar to <code>list</code>, we may sometimes eagerly construct result + * {@link java.util.Map} and skip actual buffering. + */ + private Map<String,Object> map; + + public ContainerBuilder(int bufSize) { + b = new Object[bufSize & ~1]; + } + + public boolean canReuse() { + return (list == null) && (map == null); + } + + public int bufferLength() { + return b.length; + } + + /* + /********************************************************** + /* Public API + /********************************************************** + */ + + public int start() { + if (list != null || map != null) { + throw new IllegalStateException(); + } + final int prevStart = start; + start = tail; + return prevStart; + } + + public int startList(Object value) { + if (list != null || map != null) { + throw new IllegalStateException(); + } + final int prevStart = start; + start = tail; + add(value); + return prevStart; + } + + public int startMap(String key, Object value) { + if (list != null || map != null) { + throw new IllegalStateException(); + } + final int prevStart = start; + start = tail; + put(key, value); + return prevStart; + } + + public void add(Object value) { + if (list != null) { + list.add(value); + } else if (tail >= b.length) { + _expandList(value); + } else { + b[tail++] = value; + } + } + + public void put(String key, Object value) { + if (map != null) { + map.put(key, value); + } else if ((tail + 2) > b.length) { + _expandMap(key, value); + } else { + b[tail++] = key; + b[tail++] = value; + } + } + + public List<Object> finishList(int prevStart) + { + List<Object> l = list; + if (l == null) { + l = _buildList(true); + } else { + list = null; + } + start = prevStart; + return l; + } + + public Object[] finishArray(int prevStart) + { + Object[] result; + if (list == null) { + result = Arrays.copyOfRange(b, start, tail); + } else { + result = list.toArray(new Object[tail - start]); + list = null; + } + start = prevStart; + return result; + } + + public <T> Object[] finishArray(int prevStart, Class<T> elemType) + { + final int size = tail-start; + @SuppressWarnings("unchecked") + T[] result = (T[]) Array.newInstance(elemType, size); + + if (list == null) { + System.arraycopy(b, start, result, 0, size); + } else { + result = list.toArray(result); + list = null; + } + start = prevStart; + return result; + } + + public Map<String,Object> finishMap(int prevStart) + { + Map<String,Object> m = map; + + if (m == null) { + m = _buildMap(true); + } else { + map = null; + } + start = prevStart; + return m; + } + + /* + /********************************************************** + /* Internal methods + /********************************************************** + */ + + private void _expandList(Object value) { + if (b.length < MAX_BUF) { // can still expand + b = Arrays.copyOf(b, b.length << 1); + b[tail++] = value; + } else { + list = _buildList(false); + list.add(value); + } + } + + private List<Object> _buildList(boolean isComplete) + { + int currLen = tail - start; + if (isComplete) { + if (currLen < 2) { + currLen = 2; + } + } else { + if (currLen < 20) { + currLen = 20; + } else if (currLen < MAX_BUF) { + currLen += (currLen>>1); + } else { + currLen += (currLen>>2); + } + } + List<Object> l = new ArrayList<Object>(currLen); + for (int i = start; i < tail; ++i) { + l.add(b[i]); + } + tail = start; // reset buffered entries + return l; + } + + private void _expandMap(String key, Object value) { + if (b.length < MAX_BUF) { // can still expand + b = Arrays.copyOf(b, b.length << 1); + b[tail++] = key; + b[tail++] = value; + } else { + map = _buildMap(false); + map.put(key, value); + } + } + + private Map<String,Object> _buildMap(boolean isComplete) + { + int size = (tail - start) >> 1; + if (isComplete) { // when complete, optimize to smallest size + if (size <= 3) { // 3 or fewer entries, hash table of 4 + size = 4; + } else if (size <= 40) { + size += (size>>1); + } else { + size += (size>>2) + (size>>4); // * 1.3125 + } + } else { + if (size < 10) { + size = 16; + } else if (size < MAX_BUF) { + size += (size>>1); + } else { + size += (size/3); + } + } + Map<String,Object> m = new LinkedHashMap<String,Object>(size, 0.8f); + for (int i = start; i < tail; i += 2) { + m.put((String) b[i], b[i+1]); + } + tail = start; // reset buffered entries + return m; + } +} diff --git a/attic/README.md b/attic/README.md new file mode 100644 index 000000000..0ea12d288 --- /dev/null +++ b/attic/README.md @@ -0,0 +1,3 @@ +Place where formerly used code is moved if it seems possible (or perhaps even likely) it might +be reused at some point. Or, for some experimental code that isn't yet used. + |