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:
parent
48d31b7f5c
commit
a9a0762383
26 changed files with 747 additions and 819 deletions
137
zip/Keep.java
137
zip/Keep.java
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue