160 lines
3.6 KiB
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));
|
|
}
|
|
|
|
}
|