diff --git a/zip/MapKeep.java b/zip/MapKeep.java deleted file mode 100644 index 1374e08..0000000 --- a/zip/MapKeep.java +++ /dev/null @@ -1,160 +0,0 @@ -package org.json.zip; - -import java.util.HashMap; - -import org.json.Kim; - -/* - Copyright (c) 2013 JSON.org - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - The Software shall be used for Good, not Evil. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - */ - -/** - * A keep is an associative data structure that maintains usage counts of each - * of the associations in its keeping. When the keep becomes full, it purges - * little used associations, and ages the survivors. Each key is assigned an - * integer value. When the keep is compacted, each key can be given a new - * value. - */ -class MapKeep extends Keep { - private Object[] list; - private HashMap map; - - /** - * Create a new Keep. - * @param bits - * The capacity of the keep expressed in the number of bits - * required to hold an integer. - */ - public MapKeep(int bits) { - super(bits); - this.list = new Object[this.capacity]; - this.map = new HashMap(this.capacity); - } - - /** - * Compact the keep. A keep may contain at most this.capacity elements. - * The keep contents can be reduced by deleting all elements with low use - * counts, and by reducing the use counts of the survivors. - */ - private void compact() { - int from = 0; - int to = 0; - while (from < this.capacity) { - Object key = this.list[from]; - long usage = age(this.uses[from]); - if (usage > 0) { - this.uses[to] = usage; - this.list[to] = key; - this.map.put(key, new Integer(to)); - to += 1; - } else { - this.map.remove(key); - } - from += 1; - } - if (to < this.capacity) { - this.length = to; - } else { - this.map.clear(); - this.length = 0; - } - this.power = 0; - } - - /** - * Find the integer value associated with this key, or nothing if this key - * is not in the keep. - * - * @param key - * An object. - * @return An integer - */ - public int find(Object key) { - Object o = this.map.get(key); - return o instanceof Integer ? ((Integer) o).intValue() : none; - } - - public boolean postMortem(PostMortem pm) { - MapKeep that = (MapKeep) pm; - if (this.length != that.length) { - JSONzip.log(this.length + " <> " + that.length); - return false; - } - for (int i = 0; i < this.length; i += 1) { - boolean b; - if (this.list[i] instanceof Kim) { - b = ((Kim) this.list[i]).equals(that.list[i]); - } else { - Object o = this.list[i]; - Object q = that.list[i]; - if (o instanceof Number) { - o = o.toString(); - } - if (q instanceof Number) { - q = q.toString(); - } - b = o.equals(q); - } - if (!b) { - JSONzip.log("\n[" + i + "]\n " + this.list[i] + "\n " - + that.list[i] + "\n " + this.uses[i] + "\n " - + that.uses[i]); - return false; - } - } - return true; - } - - /** - * Register a value in the keep. Compact the keep if it is full. The next - * time this value is encountered, its integer can be sent instead. - * @param value A value. - */ - public void register(Object value) { - if (JSONzip.probe) { - int integer = find(value); - if (integer >= 0) { - JSONzip.log("\nDuplicate key " + value); - } - } - if (this.length >= this.capacity) { - compact(); - } - this.list[this.length] = value; - this.map.put(value, new Integer(this.length)); - this.uses[this.length] = 1; - if (JSONzip.probe) { - JSONzip.log("<" + this.length + " " + value + "> "); - } - this.length += 1; - } - - /** - * Return the value associated with the integer. - * @param integer The number of an item in the keep. - * @return The value. - */ - public Object value(int integer) { - return this.list[integer]; - } -} diff --git a/zip/TrieKeep.java b/zip/TrieKeep.java deleted file mode 100644 index dcb13c7..0000000 --- a/zip/TrieKeep.java +++ /dev/null @@ -1,396 +0,0 @@ -package org.json.zip; - -import org.json.Kim; - -/* - Copyright (c) 2013 JSON.org - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - The Software shall be used for Good, not Evil. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - */ - -/** - * A TrieKeep is a Keep that implements a Trie. - */ -class TrieKeep extends Keep { - - /** - * The trie is made of nodes. - */ - class Node implements PostMortem { - private int integer; - private Node[] next; - - /** - * Each non-leaf node contains links to up to 256 next nodes. Each node - * has an integer value. - */ - public Node() { - this.integer = none; - this.next = null; - } - - /** - * Get one of a node's 256 links. If it is a leaf node, it returns - * null. - * - * @param cell - * A integer between 0 and 255. - * @return - */ - public Node get(int cell) { - return this.next == null ? null : this.next[cell]; - } - - /** - * Get one of a node's 256 links. If it is a leap node, it returns - * null. The argument is treated as an unsigned integer. - * - * @param cell - * A byte. - * @return - */ - public Node get(byte cell) { - return get(((int) cell) & 0xFF); - } - - /** - * Compare two nodes. Their lengths must be equal. Their links must - * also compare. - */ - public boolean postMortem(PostMortem pm) { - Node that = (Node) pm; - if (that == null) { - JSONzip.log("\nMisalign"); - return false; - } - if (this.integer != that.integer) { - JSONzip.log("\nInteger " + this.integer + " <> " + - that.integer); - return false; - } - if (this.next == null) { - if (that.next == null) { - return true; - } - JSONzip.log("\nNext is null " + this.integer); - return false; - } - for (int i = 0; i < 256; i += 1) { - Node node = this.next[i]; - if (node != null) { - if (!node.postMortem(that.next[i])) { - return false; - } - } else if (that.next[i] != null) { - JSONzip.log("\nMisalign " + i); - return false; - } - } - return true; - } - - /** - * Set a node's link to another node. - * - * @param cell - * An integer between 0 and 255. - * @param node - * The new value for the cell. - */ - public void set(int cell, Node node) { - if (this.next == null) { - this.next = new Node[256]; - } - if (JSONzip.probe) { - if (node == null || this.next[cell] != null) { - JSONzip.log("\nUnexpected set.\n"); - } - } - this.next[cell] = node; - } - - /** - * Set a node's link to another node. - * - * @param cell - * A byte. - * @param node - * The new value for the cell. - */ - public void set(byte cell, Node node) { - set(((int) cell) & 0xFF, node); - } - - /** - * Get one of a node's 256 links. It will not return null. If there is - * no link, then a link is manufactured. - * - * @param cell - * A integer between 0 and 255. - * @return - */ - public Node vet(int cell) { - Node node = get(cell); - if (node == null) { - node = new Node(); - set(cell, node); - } - return node; - } - - /** - * Get one of a node's 256 links. It will not return null. If there is - * no link, then a link is manufactured. - * - * @param cell - * A byte. - * @return - */ - public Node vet(byte cell) { - return vet(((int) cell) & 0xFF); - } - } - - private int[] froms; - private int[] thrus; - private Node root; - private Kim[] kims; - - /** - * Create a new Keep of kims. - * - * @param bits - * The log2 of the capacity of the Keep. For example, if bits is - * 12, then the keep's capacity will be 4096. - */ - public TrieKeep(int bits) { - super(bits); - this.froms = new int[this.capacity]; - this.thrus = new int[this.capacity]; - this.kims = new Kim[this.capacity]; - this.root = new Node(); - } - - /** - * Get the kim associated with an integer. - * - * @param integer - * @return - */ - public Kim kim(int integer) { - Kim kim = this.kims[integer]; - int from = this.froms[integer]; - int thru = this.thrus[integer]; - if (from != 0 || thru != kim.length) { - kim = new Kim(kim, from, thru); - this.froms[integer] = 0; - this.thrus[integer] = kim.length; - this.kims[integer] = kim; - } - return kim; - } - - /** - * Get the length of the Kim associated with an integer. This is sometimes - * much faster than get(integer).length. - * - * @param integer - * @return - */ - public int length(int integer) { - return this.thrus[integer] - this.froms[integer]; - } - - /** - * Find the integer value associated with this key, or nothing if this key - * is not in the keep. - * - * @param key - * An object. - * @return An integer - */ - public int match(Kim kim, int from, int thru) { - Node node = this.root; - int best = none; - for (int at = from; at < thru; at += 1) { - node = node.get(kim.get(at)); - if (node == null) { - break; - } - if (node.integer != none) { - best = node.integer; - } - from += 1; - } - return best; - } - - public boolean postMortem(PostMortem pm) { - boolean result = true; - TrieKeep that = (TrieKeep) pm; - if (this.length != that.length) { - JSONzip.log("\nLength " + this.length + " <> " + that.length); - return false; - } - if (this.capacity != that.capacity) { - JSONzip.log("\nCapacity " + this.capacity + " <> " + - that.capacity); - return false; - } - for (int i = 0; i < this.length; i += 1) { - Kim thiskim = this.kim(i); - Kim thatkim = that.kim(i); - if (!thiskim.equals(thatkim)) { - JSONzip.log("\n[" + i + "] " + thiskim + " <> " + thatkim); - result = false; - } - } - return result && this.root.postMortem(that.root); - } - - public void registerMany(Kim kim) { - int length = kim.length; - int limit = this.capacity - this.length; - if (limit > JSONzip.substringLimit) { - limit = JSONzip.substringLimit; - } - int until = length - (JSONzip.minSubstringLength - 1); - for (int from = 0; from < until; from += 1) { - int len = length - from; - if (len > JSONzip.maxSubstringLength) { - len = JSONzip.maxSubstringLength; - } - len += from; - Node node = this.root; - for (int at = from; at < len; at += 1) { - Node next = node.vet(kim.get(at)); - if (next.integer == none - && at - from >= (JSONzip.minSubstringLength - 1)) { - next.integer = this.length; - this.uses[this.length] = 1; - this.kims[this.length] = kim; - this.froms[this.length] = from; - this.thrus[this.length] = at + 1; - if (JSONzip.probe) { - try { - JSONzip.log("<<" + this.length + " " - + new Kim(kim, from, at + 1) + ">> "); - } catch (Throwable ignore) { - } - } - this.length += 1; - limit -= 1; - if (limit <= 0) { - return; - } - } - node = next; - } - } - } - - public void registerOne(Kim kim) { - int integer = registerOne(kim, 0, kim.length); - if (integer != none) { - this.kims[integer] = kim; - } - } - - public int registerOne(Kim kim, int from, int thru) { - if (this.length < this.capacity) { - Node node = this.root; - for (int at = from; at < thru; at += 1) { - node = node.vet(kim.get(at)); - } - if (node.integer == none) { - int integer = this.length; - node.integer = integer; - this.uses[integer] = 1; - this.kims[integer] = kim; - this.froms[integer] = from; - this.thrus[integer] = thru; - if (JSONzip.probe) { - try { - JSONzip.log("<<" + integer + " " + new Kim(kim, from, thru) + ">> "); - } catch (Throwable ignore) { - } - } - this.length += 1; - return integer; - } - } - return none; - } - - /** - * Reserve space in the keep, compacting if necessary. A keep may contain - * at most -capacity- elements. The keep contents can be reduced by - * deleting all elements with low use counts, rebuilding the trie with the - * survivors. - */ - public void reserve() { - if (this.capacity - this.length < JSONzip.substringLimit) { - int from = 0; - int to = 0; - this.root = new Node(); - while (from < this.capacity) { - if (this.uses[from] > 1) { - Kim kim = this.kims[from]; - int thru = this.thrus[from]; - Node node = this.root; - for (int at = this.froms[from]; at < thru; at += 1) { - Node next = node.vet(kim.get(at)); - node = next; - } - node.integer = to; - this.uses[to] = age(this.uses[from]); - this.froms[to] = this.froms[from]; - this.thrus[to] = thru; - this.kims[to] = kim; - to += 1; - } - from += 1; - } - -// It is possible, but highly unlikely, that too many items survive. -// If that happens, clear the keep. - - if (this.capacity - to < JSONzip.substringLimit) { - this.power = 0; - this.root = new Node(); - to = 0; - } - this.length = to; - while (to < this.capacity) { - this.uses[to] = 0; - this.kims[to] = null; - this.froms[to] = 0; - this.thrus[to] = 0; - to += 1; - - } - } - } - - public Object value(int integer) { - return kim(integer); - } -}