java-org.hwo.servicelink/src/org/hwo/servicelink/ng/ServiceRegisterCache.java

160 lines
3.6 KiB
Java

package org.hwo.servicelink.ng;
import java.util.Hashtable;
import static org.hwo.logging.Logging.*;
import static org.hwo.logging.LogLevel.*;
public class ServiceRegisterCache {
ServiceLink serviceLink;
Hashtable<Integer, BaseCacheItem>
cache;
public class BaseCacheItem
{
Integer ax,
node,
register;
boolean isFloat;
long lastReadTime;
Object value;
public BaseCacheItem(int hash){
this.ax = axFromHash(hash);
this.node = nodeFromHash(hash);
this.register = regFromHash(hash);
this.isFloat = ((hash & 0x40000000) != 0);
this.value = null;
}
public BaseCacheItem(int ax,int node,int register, boolean isFloat)
{
this.ax = ax;
this.node = node;
this.register = register;
this.isFloat = isFloat;
this.value = null;
}
long age()
{
return System.currentTimeMillis() - lastReadTime;
}
boolean isOld()
{
return age() > 250;
}
private void fetchValue(){
if (isOld() && serviceLink.isConnected())
{
try {
if (isFloat){
Float f = serviceLink.readFloat(ax.byteValue(),node.byteValue(),register);
setValue(f);
} else {
Integer i = serviceLink.readInteger(ax.byteValue(),node.byteValue(),register);
setValue(i);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public Object getValue(){
if (isOld()){
log(DEBUGDETAIL,"OLDCACHE:SLA: [%d:%d:%d:%s] = %s", ax,node,register,isFloat ? "F" : "I",value);
fetchValue();
log(DEBUGDETAIL,"NEWCACHE:SLA: [%d:%d:%d:%s] = %s", ax,node,register,isFloat ? "F" : "I",value);
}
return value;
}
public void setValue(Object value){
this.value = value;
this.lastReadTime = System.currentTimeMillis();
log(DEBUGDETAIL,"CACHE: SLA: [%d:%d:%d:%s] = %s", ax,node,register,isFloat ? "F" : "I",value);
}
public void invalidate(){
this.lastReadTime = 0;
}
}
public static Integer axFromHash(Integer hash){
return (hash >> 20) & 0x0F;
}
public static Integer nodeFromHash(Integer hash){
return (hash >> 16) & 0x0F;
}
public static Integer regFromHash(Integer hash){
return (hash) & 0xFFFF;
}
public int calcHash(int ax,int node,int register,boolean isFloat)
{
return (isFloat ? 0x40000000 : 0) | (ax << 20) | (node << 16) | register;
}
ServiceRegisterCache(ServiceLink serviceLink)
{
this.serviceLink = serviceLink;
this.cache = new Hashtable<>();
}
public ServiceLink getServiceLink() {
return serviceLink;
}
private BaseCacheItem getCacheItem(int hash){
if (!cache.containsKey(hash)){
BaseCacheItem bci = new BaseCacheItem(hash);
cache.put(new Integer(hash), bci);
log( DEBUGDETAIL, "new cache-item: 0x%08x = %s", hash, bci);
}
return cache.get(hash);
}
public void updateValue(int hash){
BaseCacheItem bci = getCacheItem(hash);
bci.invalidate();
bci.getValue();
}
public void updateValue(int hash,Object value){
getCacheItem(hash).setValue(value);
}
public synchronized Object getCachedValue(int hash){
return getCacheItem(hash).getValue();
}
public synchronized Object getCachedValue(int ax,int node,int register,boolean isFloat){
int hash = calcHash(ax, node, register, isFloat);
return getCacheItem(hash).getValue();
}
public synchronized Integer getCachedInteger(int ax,int node,int register)
{
return (Integer)getCachedValue(ax, node, register, false);
}
public synchronized Float getCachedFloat(int ax,int node,int register)
{
return (Float)getCachedValue(ax, node, register, true);
}
public synchronized void invalidate(int ax,int node,int register,boolean isFloat)
{
cache.remove(calcHash(ax, node, register,isFloat));
}
}