package php.runtime.invoke.cache; import php.runtime.env.Environment; import php.runtime.reflection.support.Entity; import java.lang.ref.WeakReference; abstract public class CallCache<T extends Entity> { protected Item[][] cache; public T get(Environment env, int index) { if (cache == null) { return null; } Item[] data = env.id < cache.length ? cache[env.id] : null; if (data == null) return null; if (index >= data.length) return null; Item item = data[index]; if (item == null) { return null; } if (item.env.get() != env) { data[index] = null; return null; } return (T) item.data; } abstract public Item[] newArrayData(int length); abstract public Item[][] newArrayArrayData(int length); @SuppressWarnings("unchecked") synchronized public void put(Environment env, int index, T entity) { int id = env.id; if (cache == null) { cache = newArrayArrayData(id + 1); } if (id >= cache.length) { Item[][] newCache = newArrayArrayData(id + 1); System.arraycopy(cache, 0, newCache, 0, cache.length); cache = newCache; } Item[] data = cache[id]; if (data == null) { cache[id] = data = newArrayData(index + 1 + 10); } else { if (index >= data.length) { Item[] newData = newArrayData(index + 1 + 10); System.arraycopy(data, 0, newData, 0, data.length); cache[id] = data = newData; } } data[index] = new Item(entity, env); } protected static class Item { Entity data; WeakReference<Environment> env; public Item(Entity data, Environment env) { this.data = data; this.env = new WeakReference<Environment>(env); } } }