1
0
Fork 0
mirror of https://github.com/ethauvin/JSON-java.git synced 2025-06-17 07:50:52 -07:00

Java 1.8.

This commit is contained in:
Douglas Crockford 2014-05-05 15:09:32 -07:00
parent 48d31b7f5c
commit a9a0762383
26 changed files with 747 additions and 819 deletions

View file

@ -1,5 +1,8 @@
package org.json.zip;
import java.util.HashMap;
import org.json.Kim;
/*
Copyright (c) 2013 JSON.org
@ -30,30 +33,34 @@ package org.json.zip;
* numbers. This allows the sending of small integers instead of strings.
*
* @author JSON.org
* @version 2013-04-18
* @version 2013-05-03
*/
abstract class Keep implements None, PostMortem {
protected int capacity;
class Keep implements None, PostMortem {
private int capacity;
protected int length;
protected int power;
protected long[] uses;
private Object[] list;
private HashMap<Object, Integer> map;
private int power;
private long[] ticks;
public Keep(int bits) {
this.capacity = JSONzip.twos[bits];
this.capacity = 1 << bits;
this.length = 0;
this.power = 0;
this.uses = new long[this.capacity];
}
this.ticks = new long[this.capacity];
this.list = new Object[this.capacity];
this.map = new HashMap<Object, Integer>(this.capacity);
}
/**
* When an item ages, its use count is reduced by at least half.
*
* @param use
* @param ticks
* The current use count of an item.
* @return The new use count for that item.
*/
public static long age(long use) {
return use >= 32 ? 16 : use / 2;
public static long age(long ticks) {
return ticks >= 32 ? 16 : ticks / 2;
}
/**
@ -62,7 +69,7 @@ abstract class Keep implements None, PostMortem {
* required to identify one of its items goes up.
*/
public int bitsize() {
while (JSONzip.twos[this.power] < this.length) {
while (1 << this.power < this.length) {
this.power += 1;
}
return this.power;
@ -72,13 +79,113 @@ abstract class Keep implements None, PostMortem {
* Increase the usage count on an integer value.
*/
public void tick(int integer) {
this.uses[integer] += 1;
this.ticks[integer] += 1;
}
/**
* Get the value associated with an integer.
* 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.ticks[from]);
if (usage > 0) {
this.ticks[to] = usage;
this.list[to] = key;
this.map.put(key, 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) {
Keep that = (Keep) 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 = 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.ticks[i] + "\n "
+ that.ticks[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, this.length);
this.ticks[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.
*/
abstract public Object value(int integer);
public Object value(int integer) {
return this.list[integer];
}
}