Package org.jscsi.whiskas.views

Source Code of org.jscsi.whiskas.views.PatternData

/*
* Copyright 2007 University of Konstanz
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Id: Control.java 32 2007-05-24 10:45:00Z ross_roy $
*
*/

package org.jscsi.whiskas.views;

//import org.jscsi.whiskas.preferences.*;

import java.io.File;
import java.io.FileReader;
import java.io.LineNumberReader;
import java.io.ObjectInputStream;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;

import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Scale;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.RowData;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;

import org.jscsi.whiskas.Activator;
import org.jscsi.whiskas.preferences.PreferenceConstants;

import org.apache.log4j.spi.LoggingEvent;

/**
* The main class of Whiskas. It controls every visualizing
* view of Whiskas and is responsible for the network
* connection to jSCSI. Therefore it supplies the values
* to display.
* @author Halld�r Janetzko
*/
public class Control extends ViewPart implements SelectionListener,
Runnable, DisposeListener {
    /**Display of Control.*/
    private Display disp;
    /**Parent shell of Control view.*/
    private Shell topshell;
    /**How many lines are evaluated per painting.*/
    private int timeResolution = 10000;
    /**Representation of the data to visualize.*/
    private Values data;
    /**Number of bins for histogram.*/
    public static int numberOfBins = 17;
    /**Buttons for GUI.*/
    private Button btNewHistogram, btNewPattern, btResetAccumulation,
        btApply, btStop;
    /**Text fields for input of server an type file.*/
    private Text serverName, typeFileName;
    /**Boolean value to remember state of Whiskas.*/
    private boolean running = false;
    //public int zeilen = 1;
    //public int spalten = 1;
    /**Scales to adjust visualizing of Whiskas.*/
    private Scale sc, sc2;
    /**Values to adjust appearing and disappearing time.*/
    private int addValue = 1, loseValue = 1;
    /**Counter for giving IDs to new views.*/
    private int idCounter = 0;
    /**
     * Returns Values object of the Control object.
     * @return values object
     */
    public final Values getDaten() {
        return data;
    }
    /**
     * Returns parent shell of Control view.
     * @return parent shell
     */
    public final Shell getTopshell() {
        return topshell;
    }
    /**
     * Returns number of lines to visualize
     * per painting.
     * @return number of lines
     */
    public final int getTimeResolution() {
        return timeResolution;
    }
    /**
     * Returns Display of Control view.
     * @return Display of view
     */
    public final Display getDisplay() {
        return disp;
    }
    /**
     * Returns wether Animation is running or not.
     * @return running - value
     */
    public final boolean getRunning() {
        return running;
    }
    /**
     * Methods sets the running value of the animation.
     * @param b - new running value
     */
    public final void setRunning(final boolean b) {
        running = b;
    }
    /**
     * Returns value to add whenever block is touched.
     * @return int that is added on visualizing value whenever
     * block is touched
     */
    public final int getAddValue() {
        return addValue;
    }
    /**
     * Returns value that is subtracted whenever a time interval is over.
     * @return int that is subtracted of visualizing value (for fade-out)
     */
    public final int getLoseValue() {
        return loseValue;
    }
    /**
     * Method which is used to read data and to supply it to
     * visualizing views.
     */
    public final void run() {
        try {
            while (disp != null && !disp.isDisposed()) {
                if (running) {
                    if (data != null && data.getNetworkReader() != null && !disp.isDisposed()) {
                        data.getData();
                        disp.syncExec(new Runnable() {
                            public void run() {
                                ListIterator < VisualListener > iter =
                                    Activator.getDefault().list_of_visualizer.
                                         listIterator();
                                while (iter.hasNext()) {
                                    VisualListener ids = iter.next();
                                    if (!ids.getComposite().isDisposed()) {
                                        ids.getNewValues();
                                    } else {
                                        iter.remove();
                                    }
                                }
                            }
                        });
                    }
                }
                try {
                    Thread.sleep(200);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } catch (Exception e) { }
    }
    /**
     * Implementation of SelectionListener (method not used).
     * @param e - SelectionEvent
     */
    public void widgetDefaultSelected(final SelectionEvent e) { }
    /**
     * Implementation of SelectionListener (used for buttons
     * of Control view).
     * @param e - SelectionEvent
     */
    public final void widgetSelected(final SelectionEvent e) {
        timeResolution = Integer.parseInt(Activator.getDefault().
                getPluginPreferences().getString(
                        PreferenceConstants.P_INT_HITS_PER_PAINT));
        if (e.widget.toString().contains("Histogram")) {
            try {
                PlatformUI.getWorkbench().getActiveWorkbenchWindow().
                   getActivePage().showView(
                           "org.jscsi.whiskas.views.Histogram",
                           Integer.toString(idCounter++),
                           IWorkbenchPage.VIEW_ACTIVATE);
            } catch (PartInitException ex) {
                MessageDialog.openError(topshell, "Error",
                        "Error opening view:" + ex.getMessage());
            }
        }
        if (e.widget.toString().contains("Reset")) {
            data.resetAccumulation();
        }
        if (e.widget.toString().contains("Stop")) {
            running = false;
            try {
                Thread.sleep(2000);
                if (data != null && data.getSocket() != null) {
                    data.getNetworkReader().stopNetworkReader();
                    data.getSocket().close();
                }
                data = null;
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        if (e.widget.toString().contains("Pattern")) {
            try {
                PlatformUI.getWorkbench().getActiveWorkbenchWindow().
                  getActivePage().showView(
                          "org.jscsi.whiskas.views.Pattern",
                          Integer.toString(idCounter++),
                          IWorkbenchPage.VIEW_ACTIVATE);
            } catch (PartInitException ex) {
                MessageDialog.openError(topshell, "Error",
                        "Error opening view:" + ex.getMessage());
            }
        }
        if (e.widget.toString().contains("Apply")) {
            running = false;
            try {
                Thread.sleep(2000);
                if (data != null && data.getSocket() != null) {
                    data.getNetworkReader().stopNetworkReader();
                    data.getSocket().close();
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            String log = serverName.getText();
            String types = typeFileName.getText();
            if (!log.equals("")) {
                data = new Values(log, types, this);
                if (data.startConnection()) {
                    running = true;
                }
            }
        }
    }
    /**
     * This is a callback that will allow us
     * to create the viewer and initialize it.
     * @param parent - Composite to create GUI on
     */
    public final void createPartControl(final Composite parent) {
        Activator.getDefault().ctr = this;
        disp = parent.getDisplay();
        Composite c = new Composite(parent, SWT.NONE);
        topshell = parent.getShell();
        c.setLayout(new RowLayout());
        btNewHistogram = new Button(c, SWT.PUSH);
        btNewHistogram.setText("New Histogram");
        btNewHistogram.addSelectionListener(this);
        btNewHistogram.addDisposeListener(this);
        btNewPattern = new Button(c, SWT.PUSH);
        btNewPattern.setText("New Pattern");
        btNewPattern.addSelectionListener(this);
        btResetAccumulation = new Button(c, SWT.PUSH);
        btResetAccumulation.setText("Reset Accumulation");
        btResetAccumulation.addSelectionListener(this);
        Label lb = new Label(c, SWT.NONE);
        lb.setText("jSCSI Server: ");
        serverName = new Text(c, SWT.SINGLE | SWT.BORDER);
        serverName.setLayoutData(new RowData(200, -1));
        serverName.setText(Activator.getDefault().getPluginPreferences().
                getString(PreferenceConstants.P_STRING_DEFAULT_LOG_FILE));
        Label lb2 = new Label(c, SWT.NONE);
        lb2.setText("Type-File: ");
        typeFileName = new Text(c, SWT.SINGLE | SWT.BORDER);
        typeFileName.setLayoutData(new RowData(200, -1));
        typeFileName.setText(Activator.getDefault().getPluginPreferences().
                getString(PreferenceConstants.P_STRING_DEFAULT_TYPE_FILE));
        Label lb3 = new Label(c, SWT.NONE);
        lb3.setText("Value added at hit: ");
        sc = new Scale(c, SWT.HORIZONTAL);
        sc.setMaximum(128);
        sc.setMinimum(1);
        sc.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(final SelectionEvent e) {
                addValue = sc.getSelection();
            }
        });
        Label lb4 = new Label(c, SWT.NONE);
        lb4.setText("Value subtracted by time: ");
        sc2 = new Scale(c, SWT.HORIZONTAL);
        sc2.setMaximum(30);
        sc2.setMinimum(1);
        sc2.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(final SelectionEvent e) {
                loseValue = sc2.getSelection();
            }
        });
        btApply = new Button(c, SWT.PUSH);
        btApply.addSelectionListener(this);
        btApply.setText("Apply");
        btStop = new Button(c, SWT.PUSH);
        btStop.addSelectionListener(this);
        btStop.setText("Stop");
        Thread th = new Thread(this);
        th.start();
    }
    /**
     * Implements setFocus from Workbench (sets focus
     * on btNewHistogram).
     */
    public final void setFocus() {
        btNewHistogram.setFocus();
    }
    /**
     * Is called when View is closed, sets running value
     * to false.
     * @param e - DisposeEvent from Eclipse
     */
    public final void widgetDisposed(final DisposeEvent e) {
        running = false;
    }
}

/**
* Internal representation of all data values to visualize.
* @author Halld�r Janetzko
*/
class Values {
    /**HashMaps to put device and values together (for histogram).*/
    private HashMap < String, float[] >
        valuesHistNotAccumulatedR = new HashMap < String, float[] > (),
        valuesHistNotAccumulatedW = new HashMap < String, float[] > (),
        valuesHistAccumulatedR = new HashMap < String, float[] > (),
        valuesHistAccumulatedW = new HashMap < String, float[] > ();
    /**HashMaps to put device and values together (for pattern).*/
    private HashMap < String, byte[] >
        valuesPatW = new HashMap < String, byte[] > (),
        valuesPatR = new HashMap < String, byte[] > ();
    /**HashMaps to put device and internal data representation
     * for pattern together.*/
    private HashMap < String, PatternData >
        patDataW = new HashMap < String, PatternData > (),
        patDataR = new HashMap < String, PatternData > ();
    /**HashMaps to save device and last block touch of
     * this device (for histogram).*/
    private HashMap < String, Integer >
        lastPosW = new HashMap < String, Integer > (),
        lastPosR = new HashMap < String, Integer > ();
    /**HashMaps to put device and internal data representation
     * for histogram together.*/
    private HashMap < String, HistogramData >
        histoDataW = new HashMap < String, HistogramData > (),
        histoDataR = new HashMap < String, HistogramData > ();
    /**Port to communicate with jSCSI server.*/
    private int port = 1986;
    /**Thread to read from network.*/
    private NetworkReader networkReader;
    /**Backlink to Control object for other classes.*/
    private Control control;
    /**Lines of data which are going to be visualized.*/
    private String[] lines;
    /**Array of block types for different coloring.*/
    private byte[] types;
    /**Socket to communicato with jSCSI server.*/
    private Socket socket;
    /**URL of jSCSI server.*/
    private String jscsiServer;
    /**
     * Constructor of Values which needs jSCSI server URL,
     * the type file and the Control object.
     * @param jSCSI - String of URL to jSCSI server
     * @param typeFile - Path and name of type file
     * @param ctr - Control object, which creates this Values object
     */
    public Values(final String jSCSI,
            final String typeFile, final Control ctr) {
        this.control = ctr;
        this.jscsiServer = jSCSI;
        setTypes(typeFile);
    }
    /**
     * Get method which returns the types array.
     * @retrun array of types
     */
    public byte[] getTypes() {
        return types;
    }
    /**
     * Get method which returns a hashtable.
     * @return the hashtable
     */
    public HashMap < String, byte[] > getValuesPatW() {
        return valuesPatW;
    }
    /**
     * Get method which returns a hashtable.
     * @return the hashtable
     */
    public HashMap < String, byte[] > getValuesPatR() {
        return valuesPatR;
    }
    /**
     * Get method which returns a hashtable.
     * @return the hashtable
     */
    public HashMap < String, float[] > getValuesHistNotAccumulatedR() {
        return valuesHistNotAccumulatedR;
    }
    /**
     * Get method which returns a hashtable.
     * @return the hashtable
     */
    public HashMap < String, float[] > getValuesHistNotAccumulatedW() {
        return valuesHistNotAccumulatedW;
    }
    /**
     * Get method which returns a hashtable.
     * @return the hashtable
     */
    public HashMap < String, float[] > getValuesHistAccumulatedR() {
        return valuesHistAccumulatedR;
    }
    /**
     * Get method which returns a hashtable.
     * @return the hashtable
     */
    public HashMap < String, float[] > getValuesHistAccumulatedW() {
        return valuesHistAccumulatedW;
    }
    /**
     * Get method which returns the network reader object.
     * @return NetworkReader object
     */
    public NetworkReader getNetworkReader() {
        return networkReader;
    }
    /**
     * Returns Socket to jSCSI server.
     * @return Socket to jSCSI server.
     */
    public Socket getSocket() {
        return socket;
    }
    /**
     * Method which pulls new data from the network reader
     * and processes them.
     */
    public void getData() {
        Iterator < String > iterHistogram = histoDataW.keySet().iterator();
        while (iterHistogram.hasNext()) {
            histoDataW.get(iterHistogram.next()).nextTime();
        }
        iterHistogram = histoDataR.keySet().iterator();
        while (iterHistogram.hasNext()) {
            histoDataR.get(iterHistogram.next()).nextTime();
        }
        Iterator < PatternData > iterPattern = patDataW.values().iterator();
        while (iterPattern.hasNext()) {
            iterPattern.next().loseValue();
        }
        iterPattern = patDataR.values().iterator();
        while (iterPattern.hasNext()) {
            iterPattern.next().loseValue();
        }
        String[] res = new String[control.getTimeResolution()];
        long time = System.currentTimeMillis();
        int i = 0;
        while (i < control.getTimeResolution()
                && System.currentTimeMillis() - time < 200) {
            if (!networkReader.getList().isEmpty()) {
                try {
                    String line = (String) networkReader.getList().get(0);
                    networkReader.getList().remove(0);
                    if (line != null) {
                        res[i] = line;
                        i++;
                    }
                } catch (Exception ex) { }
            }
        }
        try {
            if (networkReader.getList().isEmpty()) {
                Thread.sleep(100);
            }
        } catch (Exception e) { }
        for (int j = i; j < control.getTimeResolution(); j++) {
            res[j] = "  ";
        }
        lines = res;
        analyse();
        iterHistogram = histoDataW.keySet().iterator();
        while (iterHistogram.hasNext()) {
            String s = iterHistogram.next();
            valuesHistNotAccumulatedW.put(s,
                    histoDataW.get(s).buildFloatArrayNotAccumulated());
            valuesHistAccumulatedW.put(s,
                    histoDataW.get(s).buildFloatArrayAccumulated());
        }
        iterHistogram = histoDataR.keySet().iterator();
        while (iterHistogram.hasNext()) {
            String s = iterHistogram.next();
            valuesHistNotAccumulatedR.put(s,
                    histoDataR.get(s).buildFloatArrayNotAccumulated());
            valuesHistAccumulatedR.put(s,
                    histoDataR.get(s).buildFloatArrayAccumulated());
        }
        Iterator < String > iterPatData = patDataW.keySet().iterator();
        while (iterPatData.hasNext()) {
            String aktuell = iterPatData.next();
            valuesPatW.put(aktuell,
                    patDataW.get(aktuell).buildByteArray());
        }
        iterPatData = patDataR.keySet().iterator();
        while (iterPatData.hasNext()) {
            String aktuell = iterPatData.next();
            valuesPatR.put(aktuell, patDataR.get(aktuell).buildByteArray());
        }
    }
    /**
     * In this method the new data are processed and
     * put in the different objects.
     */
    public void analyse() {
        String line = null;
        int pos;
        char readWrite;
        String device;
        for (int i = 0; i < control.getTimeResolution(); i++) {
            line = lines[i];
            if (line.contains("teardown")) {
                device = line.substring(line.indexOf(" "));
                patDataW.remove(device);
                patDataR.remove(device);
                valuesPatW.remove(device);
                valuesPatR.remove(device);
                histoDataW.remove(device);
                histoDataR.remove(device);
                lastPosW.remove(device);
                lastPosR.remove(device);
            }
            if (line.lastIndexOf(',') >= 0 && !line.contains("teardown")) {
                pos = Integer.parseInt(line.substring(
                        line.lastIndexOf(',') + 1));
                line = line.substring(0, line.lastIndexOf(','));
                readWrite = line.charAt(line.length() - 1);
                device = line.substring(0, line.lastIndexOf(','));
                try {
                    if (!patDataW.containsKey(device)) {
                        patDataW.put(device, new PatternData(control));
                        patDataR.put(device, new PatternData(control));
                        histoDataW.put(device, new HistogramData());
                        histoDataR.put(device, new HistogramData());
                        lastPosR.put(device, new Integer(-5));
                        lastPosW.put(device, new Integer(-5));
                    }
                    if (readWrite == 'w') {
                        patDataW.get(device).addValue(pos);
                        if (lastPosW.get(device).intValue() != -5) {
                            histoDataW.get(device).addValue(pos
                                    - lastPosW.get(device).intValue());
                        }
                        lastPosW.put(device, new Integer(pos));
                    }
                    if (readWrite == 'r') {
                        patDataR.get(device).addValue(pos);
                        if (lastPosR.get(device).intValue() != -5) {
                            histoDataR.get(device).addValue(pos
                                    - lastPosR.get(device).intValue());
                        }
                        lastPosR.put(device, new Integer(pos));
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
    /**
     * This method resets the Accumulation of the
     * hsitogram data.
     */
    public void resetAccumulation() {
        Iterator < String > iter = histoDataW.keySet().iterator();
        while (iter.hasNext()) {
            histoDataW.get(iter.next()).resetAccumulation();
        }
        iter = histoDataR.keySet().iterator();
        while (iter.hasNext()) {
            histoDataR.get(iter.next()).resetAccumulation();
        }
    }
    /**
     * This methods reads the block types from
     * the typefile and processes it.
     * @param typefilename - the nam e of the pathfile
     */
    public void setTypes(final String typefilename) {
        try {
            ArrayList < String > typeList = new ArrayList < String > ();
            String line;
            byte type;
            int pos;
            File f = new File(typefilename);
            FileReader fr = new FileReader(f);

            LineNumberReader lnr3 = new LineNumberReader(fr);
            while ((line = lnr3.readLine()) != null) {
                typeList.add(line);
            }
            lnr3.close();
            fr.close();
            types = new byte[typeList.size() + 1];
            for (int i = 0; i < typeList.size(); i++) {
                line = typeList.get(i);
                pos = Integer.parseInt(line.substring(0, line.indexOf(',')));
                type = Byte.parseByte(line.substring(
                        line.indexOf(',') + 1, line.length()));
                if (type >= 0 && type <= 9 && pos >= 0) {
                    types[pos] = type;
                }
            }
        } catch (Exception e) {
            types = null;
        }
    }
    /**
     * This method starts the connection to the
     * jSCSI server.
     * @return everything went OK
     */
    public boolean startConnection() {
        try {
            socket = new Socket(jscsiServer, port);
            networkReader = new NetworkReader(
                    new ObjectInputStream(socket.getInputStream()), control);
            networkReader.start();
            return true;
        } catch (Exception e) {
            MessageDialog.openError(control.getTopshell(),
                    "Connection Error",
                    "Can't connect to jSCSI Server!\n" + e.toString());
            control.setRunning(false);
            return false;
        }
    }
    /**
     * This method stops the network reader thread.
     */
    public void killThread() {
        if (networkReader != null) {
            networkReader.stopNetworkReader();
        }
        if (socket != null) {
            try {
                socket.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

/**
* This class is an internal representation of the
* pattern values to visualize.
* @author Halld�r Janetzko
*/
class PatternData {
    /**HashMap of block, value.*/
    private HashMap < Integer, Integer > values;
    /**block number.*/
    private int max = 0;
    /**Control object to get add and lose value.*/
    private Control ctr;
    /**
     * Constructor of PatternData.
     * @param c - the Control object
     */
    public PatternData(final Control c) {
        values = new HashMap < Integer, Integer > ();
        ctr = c;
    }
    /**
     * Method adds a certain value (given by Control) to
     * the internal block representation.
     * @param pos - the Block on which a value has to be added
     */
    public void addValue(final int pos) {
        if (pos >= 0) {
            if (pos > max) {
                max = pos;
            }
            if (!values.containsKey(new Integer(pos))) {
                values.put(new Integer(pos), new Integer(-127));
            } else {
                int value = values.get(new Integer(pos)).intValue();
                value += ctr.getAddValue();
                if (value > 127) {
                    value = 127;
                }
                values.put(new Integer(pos), new Integer(value));
            }
        }
    }
    /**
     * Every internal block representation has to lose a
     * certain value given by Control.
     */
    public void loseValue() {
        for (int pos = 0; pos < max; pos++) {
            if (values.containsKey(new Integer(pos))) {
                int value = values.get(new Integer(pos)).intValue();
                value -= ctr.getLoseValue();
                if (value < -128) {
                    value = -128;
                }
                values.put(new Integer(pos), new Integer(value));
            }
        }
    }
    /**
     * This methods creates an byte array containing all values
     * for the pattern.
     * @return byte - Array of values
     */
    public byte[] buildByteArray() {
        byte[] res = new byte[max];
        for (int i = 0; i < res.length; i++) {
            if (values.containsKey(new Integer(i))) {
                res[i] = (byte) (values.get(new Integer(i)).intValue());
            } else {
                res[i] = (byte) (-128);
            }
        }
        return res;
    }
}

/**
* This class manages all values and assign the
* different jump lengths.
* @author Halld�r Janetzko
*/
class HistogramData {
    /**The bin objects are stored here.*/
    private BinData[] count = new BinData [Control.numberOfBins];
    /**
     * Constructor which initializes the bin objects
     * in the array.
     */
    public HistogramData() {
        for (int i = 0; i < count.length; i++) {
            count[i] = new BinData();
        }
    }
    /**
     * This method adds a hit to the suitable
     * bin according to the jump.
     * @param value of the jumping distance
     */
    public void addValue(final int value) {
        if (value < -200) {
            count[0].increaseValue();
        }
        if (value >= -200 && value <= -101) {
            count[1].increaseValue();
        }
        if (value >= -100 && value <= -41) {
            count[2].increaseValue();
        }
        if (value >= -40 && value <= -16) {
            count[3].increaseValue();
        }
        if (value >= -15 && value <= -6) {
            count[4].increaseValue();
        }
        if (value >= -5 && value <= -3) {
            count[5].increaseValue();
        }
        if (value == -2) {
            count[6].increaseValue();
        }
        if (value == -1) {
            count[7].increaseValue();
        }
        if (value == 0) {
            count[8].increaseValue();
        }
        if (value == 1) {
            count[9].increaseValue();
        }
        if (value == 2) {
            count[10].increaseValue();
        }
        if (value >= 3 && value <= 5) {
            count[11].increaseValue();
        }
        if (value >= 6 && value <= 15) {
            count[12].increaseValue();
        }
        if (value >= 16 && value <= 40) {
            count[13].increaseValue();
        }
        if (value >= 41 && value <= 100) {
            count[14].increaseValue();
        }
        if (value >= 101 && value <= 200) {
            count[15].increaseValue();
        }
        if (value > 200) {
            count[16].increaseValue();
        }
    }
    /**
     * This method returns an float array consisting
     * of the different bin heights, which are
     * accumulated.
     * @return float array for histogram
     */
    public float[] buildFloatArrayAccumulated() {
        float[] array = new float[count.length];
        for (int i = 0; i < count.length; i++) {
            array[i] = count[i].getAccumulatedValue();
        }
        return array;
    }
    /**
     * This method returns an float array consisting
     * of the different bin heights, which are not
     * accumulated.
     * @return float array for histogram
     */
    public float[] buildFloatArrayNotAccumulated() {
        float[] result = new float[count.length];
        for (int i = 0; i < count.length; i++) {
            result[i] = count[i].getNotAccumulatedValue();
        }
        return result;
    }
    /**
     * This method increases the timestamp
     * of every bin, to ensure the right
     * calculation of the bin height.
     */
    public void nextTime() {
        for (int i = 0; i < count.length; i++) {
            count[i].increaseTimestamp();
            count[i].calculateValue();
        }
    }
    /**
     * This method sets the height of every
     * bin to 0.
     */
    public void reset() {
        for (int i = 0; i < count.length; i++) {
            count[i].reset();
        }
    }
    /**
     * This method resets the accumulation
     * of every bin for instance when another
     * device is choosen.
     */
    public void resetAccumulation() {
        for (int i = 0; i < count.length; i++) {
            count[i].resetAccumulation();
        }
    }
}

/**
* This class represents a single bin of the histogram. The
* actual height is calculated of the last 5 values by
* using an exponential function.
* @author Halld�r Janetzko
*/
class BinData {
    /**A value between 0 and 4 (incl.) for calculation of
     *  bin height.
     */
    private int timestamp = 0;
    /**Height calculated with exponential function.*/
    private float calculatedHeight;
    /**All values accumulated.*/
    private float valuesAccumulated = 0;
    /**Array to store the last five values.*/
    private int[] valueAtTimestamp = new int[5];
    /**
     * The value at the current timestamp and the
     * accumulated value is increased by 1.
     */
    public void increaseValue() {
        valueAtTimestamp[timestamp]++;
        calculatedHeight++;
        valuesAccumulated++;
    }
    /**
     * The value of the timestamp is increased by 1 and
     * resetted if it is greater than 4.
     */
    public void increaseTimestamp() {
        timestamp++;
        if (timestamp > 4) {
            timestamp = 0;
        }
    }
    /**
     * In this method is the bin height calculated by
     * using an exponential weighting function.
     */
    public void calculateValue() {
        int[] temp = new int[5];
        for (int i = 0; i < 5; i++) {
            temp[i] = valueAtTimestamp[timestamp];
            timestamp++;
            if (timestamp > 4) {
                timestamp = 0;
            }
        }
        calculatedHeight = (float) (temp[0] + temp[1] * 0.5
                + temp[2] * 0.25 + temp[3] * 0.125 + temp[4] * 0.0625);
        valueAtTimestamp[timestamp] = 0;
    }
    /**
     * This method returns the bin height consisting of
     * the last 5 values.
     * @return calculated bin height
     */
    public float getNotAccumulatedValue() {
        return calculatedHeight;
    }
    /**
     * This method returns the bin height consisting of
     * all last values.
     * @return accumulated bin height
     */
    public float getAccumulatedValue() {
        return valuesAccumulated;
    }
    /**
     * The last 5 values are set to 0.
     */
    public void reset() {
        for (int i = 0; i < 5; i++) {
            valueAtTimestamp[i] = 0;
        }
        calculatedHeight = 0;
    }
    /**
     * The accumulation of all values is
     * set to 0.
     */
    public void resetAccumulation() {
        valuesAccumulated = 0;
    }
}

/**
* This class reads the incoming data from the
* jSCSI server and stores them in a
* synchronized list.
* @author Halld�r Janetzko
*/
class NetworkReader extends Thread {
    /**Stream to read the LoggingEvents from.*/
    private ObjectInputStream ois;
    /**Control object.*/
    private Control control;
    /**List in which the Strings from the network are stored.*/
    private List list;
    /**Boolean to check whether the Thread should be running.*/
    private boolean run = false;
    /**
     * The constructor of NetworkReader which needs a ObjectInputStream
     * and a backlink to Control.
     * @param stream - Stream to read the LoggingEvents from
     * @param ctr - Control object
     */
    public NetworkReader(final ObjectInputStream stream, final Control ctr) {
        this.ois = stream;
        this.control = ctr;
        list = Collections.synchronizedList(new LinkedList());
    }
    /**
     * This method return the list where the
     * events are stored in.
     * @return list of events
     */
    public List getList() {
        return list;
    }
    /**
     * Run-method of thread. Here are the objects read from the
     * network and stored as strings.
     */
    public void run() {
        run = true;
        while (run) {
            try {
                LoggingEvent le = (LoggingEvent) ois.readObject();
                String line = (String) le.getMessage();
                if (line.contains("teardown")) {
                    list.add(line);
                } else {
                    int length = Integer.parseInt(
                            line.substring(line.lastIndexOf(',') + 1));
                    line = line.substring(0, line.lastIndexOf(','));
                    int firstPos = Integer.parseInt(
                            line.substring(line.lastIndexOf(',') + 1));
                    line = line.substring(0, line.lastIndexOf(','));
                    if (line != null) {
                        for (int i = 0; i < length; i++) {
                            list.add(line + "," + (firstPos + i));
                        }
                    }
                }
                while (list.size() > 3 * control.getTimeResolution()) {
                    list.remove(0);
                }
            } catch (SocketException se) {
                final String exc = se.toString();
                if (control.getRunning()) {
                    control.getDisplay().asyncExec(new Runnable() {
                        public void run() {
                            MessageDialog.openError(control.getTopshell(),
                                    "Connection Error",
                                    "Connection to jSCSI Server lost!\n" + exc);
                        }
                    });
                }
                try {
                    Thread.sleep(1000);
                    run = false;
                    stopNetworkReader();
                } catch (Exception e) { }
            } catch (Exception e) { }
        }
    }
    /**
     * This method stops the Thread. It is called
     * when the shell of Control is disposed.
     */
    public void stopNetworkReader() {
        run = false;
        try {
            ois.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
TOP

Related Classes of org.jscsi.whiskas.views.PatternData

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.
te();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); ga('create', 'UA-20639858-1', 'auto'); ga('send', 'pageview');