org.jclarion.clarion.primative.ActiveThreadMap Maven / Gradle / Ivy
package org.jclarion.clarion.primative;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.TimerTask;
import org.jclarion.clarion.runtime.ClarionTaskManager;
public class ActiveThreadMap
{
private static final int SIZE=8;
private static final int AND=7;
private static class Entry
{
//private long lastAccessed;
private Entry(Thread key,V value)
{
this._key=key;
this._value=value;
}
private Thread _key;
private V _value;
public boolean isAlive()
{
return _key.isAlive();
}
public V getValue()
{
return _value;
}
public Thread getKey()
{
return _key;
}
public void setValue(V value)
{
this._value=value;
}
public void setValue(Thread key,V value)
{
this._value=value;
this._key=key;
}
}
private Entry[][] hash;
@SuppressWarnings("unchecked")
public ActiveThreadMap()
{
hash=new Entry[SIZE][];
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public void put(Thread thread,V value)
{
List cleanup=null;
synchronized(this) {
int indx = ((int) thread.getId()) & AND;
Entry[] bucket = hash[indx];
if (bucket == null) {
bucket = new Entry[1];
hash[indx] = bucket;
bucket[0] = new Entry(thread, value);
return;
}
int slot = -1;
boolean empty = true;
for (int scan = 0; scan < bucket.length; scan++) {
Entry e = bucket[scan];
if (e != null && e.getKey() == thread) {
e.setValue(value);
return;
}
if (e == null || !e.isAlive()) {
slot = scan;
continue;
}
empty = false;
}
if (empty && slot > 0) {
for (Entry e : bucket) {
cleanup = addToCleanup(cleanup, e);
}
bucket = new Entry[1];
hash[indx] = bucket;
slot = 0;
}
if (slot == -1) {
Entry[] newBucket = new Entry[bucket.length << 1];
System.arraycopy(bucket, 0, newBucket, 0, bucket.length);
slot = bucket.length;
bucket = newBucket;
hash[indx] = bucket;
}
Entry e = bucket[slot];
if (e != null) {
if (e.getKey() != thread) {
cleanup = addToCleanup(cleanup, e);
}
e.setValue(thread,value);
} else {
bucket[slot] = new Entry(thread, value);
}
}
cleanup(cleanup);
}
@SuppressWarnings({"unchecked", "rawtypes"})
public synchronized V get(Thread thread)
{
int indx = ((int)thread.getId())&AND;
Entry[] bucket = hash[indx];
if (bucket==null) return null;
for (int scan=0;scan[] scan : hash ) {
if (scan!=null) {
count+=scan.length;
}
}
return count;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public void clear()
{
Entry[][] old;
synchronized(this) {
old=hash;
hash=new Entry[SIZE][];
}
for (Entry ea[] : old )
{
if (ea==null) continue;
for (Entry e : ea ) {
if (e!=null) {
cleanup(e.getValue());
}
}
}
}
private static class ScheduledPack extends TimerTask
{
final WeakReference> wr_atm;
public ScheduledPack(ActiveThreadMap base)
{
wr_atm = new WeakReference>(base);
}
public void run()
{
ActiveThreadMap atm = wr_atm.get();
if (atm==null) {
cancel();
} else {
atm.pack();
}
}
}
public void schedulePack(int delay)
{
ClarionTaskManager.getInstance().getTimer().schedule(
new ScheduledPack(this),
new java.util.Date(),delay);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public void pack()
{
List cleanup=new ArrayList();
synchronized(this) {
for (int s1 =0;s1 e = ea[s2];
if (e==null) continue;
if (e.isAlive()) {
empty=false;
continue;
}
cleanup.add(e.getValue());
ea[s2]=null;
}
if (empty) {
hash[s1]=null;
}
}
}
cleanup(cleanup);
}
public void cleanup(V object)
{
if (object==null) return;
if (object instanceof Cleanup) {
((Cleanup) object).cleanup();
}
}
private void cleanup(List l)
{
if (l==null) return;
for (V val : l ) {
cleanup(val);
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private List addToCleanup(List l,Entry e)
{
if (e==null) return l;
if (e.isAlive()) return l;
if (l==null) l =new ArrayList();
l.add((V)e.getValue());
return l;
}
public Iterable keys() {
return new KeyIterable(this);
}
public Iterable values() {
return new ValueIterable(this);
}
private static class KeyIterable implements Iterable
{
private ActiveThreadMap map;
public KeyIterable(ActiveThreadMap map) {
this.map=map;
}
@Override
public Iterator iterator() {
return new KeyIterator(map);
}
}
private static class KeyIterator extends EntryIterator
{
public KeyIterator(ActiveThreadMap map) {
super(map);
}
@Override
protected Thread getNext(Entry next) {
return next.getKey();
}
}
private static class ValueIterable implements Iterable
{
private ActiveThreadMap map;
public ValueIterable(ActiveThreadMap map) {
this.map=map;
}
@Override
public Iterator iterator() {
return new ValueIterator(map);
}
}
private static class ValueIterator extends EntryIterator
{
public ValueIterator(ActiveThreadMap map) {
super(map);
}
@Override
protected V getNext(Entry next) {
return next.getValue();
}
}
private static abstract class EntryIterator implements Iterator
{
private int bucketPos=0;
private int hashPos=0;
private Entry next=null;
private Entry remove=null;
private ActiveThreadMap map;
public EntryIterator(ActiveThreadMap map)
{
this.map=map;
}
@Override
public boolean hasNext() {
synchronized(this) {
while (next==null) {
if (hashPos>=map.hash.length) return false;
if (map.hash[hashPos]==null) {
hashPos++;
continue;
}
if (bucketPos>=map.hash[hashPos].length) {
hashPos++;
bucketPos=0;
continue;
}
next=map.hash[hashPos][bucketPos++];
if (next!=null && !next.isAlive()) { next=null; }
}
return true;
}
}
@Override
public final K next() {
if (!hasNext()) throw new RuntimeException("Exhausted");
remove=next;
next=null;
return getNext(remove);
}
protected abstract K getNext(Entry next);
@Override
public void remove() {
map.remove(remove.getKey());
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy