org.hwo.pulscounter/src/org/hwo/pulscounter/SnapshotManager.java

322 lines
7.5 KiB
Java

package org.hwo.pulscounter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.util.Hashtable;
import org.hwo.servicelink.ServiceLinkException;
import org.hwo.servicelink.ServiceLinkRequestFailedException;
import org.hwo.tasklet.Tasklet;
import org.hwo.tasklet.TaskletManager;
public class SnapshotManager {
public enum Notification { INITIALIZE, SHUTDOWN, SYNC, FULLSYNC };
private RandomAccessFile file;
private Hashtable<Long,Integer> hashList;
private Integer lastNewest,
snapshotSize;
public SnapshotManager() throws FileNotFoundException {
this.file = new RandomAccessFile("snapshots.dat", "rws");
this.initialize();
}
public SnapshotManager(File file) throws FileNotFoundException {
this.file = new RandomAccessFile(file, "rws");
this.initialize();
}
private synchronized void initialize(){
hashList = new Hashtable<Long, Integer>();
}
private PulsCounter2Application application(){
return PulsCounter2Application.getApplication();
}
public synchronized void notify(Notification notification){
switch (notification){
case INITIALIZE:
TaskletManager.instance().enqueue(new Tasklet("SnapShot Manager initialisieren") {
@Override
public void run() {
doInitialize();
}
});
break;
case SHUTDOWN:
doShutdown();
return;
case FULLSYNC:
TaskletManager.instance().enqueue(new Tasklet("Volle Synchronisation") {
@Override
public void run() {
doFullSync();
}
});
break;
case SYNC:
TaskletManager.instance().enqueue(new Tasklet("Schnelle Synchronisation") {
@Override
public void run() {
doSync();
}
});
break;
}
}
public synchronized void doInitialize(){
try {
byte[] buffer = new byte[256];
ByteBuffer bb = ByteBuffer.wrap(buffer);
Integer ind = 0;
application().message("SnapShotManager: Initialisieren");
hashList.clear();
file.seek(0);
while (file.read(buffer)==256){
Integer timestamp,field0;
Long hash;
timestamp = bb.getInt(0);
field0 = bb.getInt(4);
hash = ((long)timestamp << 32) | field0;
hashList.put(hash, ind++);
}
application().message(String.format("SnapShotManager: %d SnapShots lokal", hashList.size()));
} catch (Exception e){
e.printStackTrace();
application().message("SnapShotManager meldet Fehler: " + e.toString());
}
}
public synchronized void doShutdown(){
}
public synchronized void doFullSync(){
Integer ind_oldest,ind_newest,ind;
int n = 0;
application().message("SnapShotManager: Beginne volle synchronisation");
try {
try {
snapshotSize = application().getServiceLink().readInt(13, 0, 0x0582);
} catch (ServiceLinkRequestFailedException e){
snapshotSize = 512;
}
ind_oldest = application().getServiceLink().readInt(13, 0, 0x0580);
ind_newest = application().getServiceLink().readInt(13, 0, 0x0581);
lastNewest = ind_newest;
System.out.println(String.format("ind_oldest: %d", ind_oldest));
System.out.println(String.format("ind_newest: %d", ind_newest));
ind = ind_oldest;
do {
TaskletManager.instance().setProgress(String.format("%d / %d", n++, snapshotSize));
Integer id;
try {
application().getServiceLink().writeInt(13, 0, 0x0500, ind);
id = application().getServiceLink().readInt(13, 0, 0x0500);
if (!id.equals(ind)){
System.out.println(String.format("bus_snapshot_id: %d != %d",ind,id));
} else {
Integer ts,f0;
ts = application().getServiceLink().readInt(13, 0, 0x0501);
f0 = application().getServiceLink().readInt(13, 0, 0x0502);
Long hash = ((long)ts<<32) | f0;
if (!hashList.containsKey(hash)){
SnapShot snap = snapshotFromDevice(ind);
if (snap != null){
Integer find = snapshotToFile(snap);
if (find != -1){
hashList.put(snap.getHashCode(), find);
} else {
application().message("Snapshot konnte nicht gespeichert werden!");
}
};
};
};
if (ind.equals(ind_newest))
break;
} catch (ServiceLinkRequestFailedException failed){
failed.printStackTrace();
};
ind++;
if (ind > snapshotSize){
ind = 0;
}
} while (!ind.equals(ind_oldest));
} catch (Exception e){
e.printStackTrace();
}
application().message(String.format("SnapShotManager: %d bekannte Snapshots nach FullSync", hashList.size()));
}
private synchronized void doSync(){
Integer ind_oldest,ind_newest,ind;
int n,c;
try {
ind_newest = application().getServiceLink().readInt(13, 0, 0x0581);
if (ind_newest == lastNewest)
return;
ind = lastNewest;
c = ind_newest - lastNewest;
if (c < 0)
c+=snapshotSize;
n = 0;
if (c == 0){
return;
}
do {
TaskletManager.instance().setProgress(String.format("%d / %d", n,c));
ind ++;
ind &= 0x1FF;
n++;
SnapShot snap = snapshotFromDevice(ind);
if (snap != null){
Integer ind_file = snapshotToFile(snap);
hashList.put(snap.getHashCode(), ind_file);
}
} while (!ind.equals(ind_newest));
lastNewest = ind_newest;
application().message(String.format("%d neue Snapshots", n));
} catch (ServiceLinkRequestFailedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ServiceLinkException e) {
e.printStackTrace();
}
}
public synchronized SnapShot loadSnapShot(int ind){
byte[] bytes = new byte[256];
try {
file.seek(ind * 256);
file.read(bytes);
return new SnapShot(bytes);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public synchronized Integer size(){
try {
return ((int)(file.length())/256);
} catch (IOException e) {
e.printStackTrace();
}
return 0;
}
private synchronized Integer snapshotToFile(SnapShot snap){
Long find;
try {
find = file.length()/256;
file.seek(find * 256);
file.write(snap.toBytes());
return find.intValue();
} catch (IOException e) {
e.printStackTrace();
return -1;
}
}
private SnapShot snapshotFromDevice(Integer ind){
SnapShot ss = new SnapShot();
Integer id;
try {
application().getServiceLink().writeInt(13, 0, 0x0500, ind);
id = application().getServiceLink().readInt(13, 0, 0x0500);
if (!id.equals(ind)){
System.out.println(String.format("bus_snapshot_id: %d != %d",ind,id));
return null;
};
ss.setTimestamp( application().getServiceLink().readInt(13, 0, 0x0501));
ss.setField0( application().getServiceLink().readInt(13, 0, 0x0502));
ss.setInputmask( application().getServiceLink().readInt(13, 0, 0x0503));
ss.setOutputmask( application().getServiceLink().readInt(13, 0, 0x0504));
ss.setPullupmask( application().getServiceLink().readInt(13, 0, 0x0505));
ss.setInvertmask( application().getServiceLink().readInt(13, 0, 0x0506));
ss.setTriggermask( application().getServiceLink().readInt(13, 0, 0x0507));
for (int i=0;i<32;i++){
ss.setValue(i, application().getServiceLink().readInt(13, 0, 0x0510 + i));
}
for (int i=0;i<8;i++){
ss.setAnalog(i, application().getServiceLink().readInt(13, 0, 0x0508 + i));
}
} catch (Exception e){
e.printStackTrace();
return null;
}
System.out.print(String.format("Snapshot from Device: %s\n", ss.toString()));
return ss;
}
}