package Model;


/**
 * F&uuml;hrt die gew&uuml;nschten Laufzeittests durch.
 * 
 * @author ISB-Arbeitskreis, Umsetzungshilfen Informatik 12
 * @version 1.0
 */

import java. util. *;

public class TESTSUCHE
{
    /* Anzahl der Datenelemente in Liste und / oder Baum */
    private int anzahl;
    /* Die zu testende Lsite */
    private Model. Liste. LISTE l;
    /* Der zu testende Baum */
    private Model. Baum. BAUM b;
    /* Erzeugerelement f&uuml;r die Schl&uuml;sselwerte */
    private GENERATOR g;
    /* Der Zufallsgeneratur f&uuml;r die Auswahl der zu suchenden Werte */
    private Random zufall;
    /* Die Laufzeitsummen */
    private long summe1, summe2;
    /* Die vorhandenen Datenelemente */
    private ArrayList<DATENELEMENT> schluesselwerte;

    /**
     * Legt die ben&ouml;tigten Objekte an und besetzt die Attributwerte.
     * @param anzahl Anzahl der Datenelemente in Liste und / oder Baum
     */
    public TESTSUCHE (int anzahl)
    {
        this. anzahl = anzahl;
        zufall = new Random ();
        l = new Model. Liste. LISTE ();
        b = new Model. Baum. BAUM ();
        g = new GENERATOR (10);
        schluesselwerte = new ArrayList<DATENELEMENT> ();
        for (int i = 1; i <= anzahl; i++)
        {
            schluesselwerte. add (new STRINGDATEN (g. BezeichnerGenerieren ()));
        }
    }
    
    /**
     * Zu suchendes Testelement ausw&auml;hlen.
     * @return Testelement
     */
    private DATENELEMENT TestWaehlen ()
    {
        return schluesselwerte. get (zufall. nextInt (anzahl));
    }
    
    /**
     * Misst die Zeit f&uumlr einen Suchvorgang in der Liste.
     * Um die unterschiedlichen Prozessorfremdbelastungen auszugleichen
     * wird der Vorgang hndert Mal wiederholt und die minimale Suchzeit ermittelt.
     * @param d das zu suchende Datenelement
     * @return das Minimum der ben&ouml;tigten Suchzeiten
     */
    private long ZeitFuerListenSucheMessen (DATENELEMENT d)
    {
        long start, ende, min;
        min = Long. MAX_VALUE;
        for (int i = 1; i <= 100; i++)
        {
            start = System. nanoTime ();
            l. Suchen (d);
            ende = System. nanoTime ();
            min = Math. min (min, ende - start);
        }
        return min;
    }
    
    /**
     * Misst die Zeit f&uumlr einen Suchvorgang im Baum.
     * Um die unterschiedlichen Prozessorfremdbelastungen auszugleichen
     * wird der Vorgang hndert Mal wiederholt und die minimale Suchzeit ermittelt.
     * @param d das zu suchende Datenelement
     * @return das Minimum der ben&ouml;tigten Suchzeiten
     */
    private long ZeitFuerBaumSucheMessen (DATENELEMENT d)
    {
        long start, ende, min;
        min = Long. MAX_VALUE;
        for (int i = 1; i <= 100; i++)
        {
            start = System. nanoTime ();
            b. Suchen (d);
            ende = System. nanoTime ();
            min = Math. min (min, ende - start);
        }
        return min;
    }
    
    /**
     * Bestimmt die durschnittlichen Suchzeiten.
     * @param anzahl Anzahl der auszuf&uuml;hrenden Suchvorg&auml;nge
     * @param liste gibt an, ob in der Liste gesucht werden soll
     * @param baum gibt an, ob im Baum gesucht werden soll
     */
    public void DurchschnittsTest (int anzahl, boolean liste, boolean baum)
    {
        for (DATENELEMENT d: schluesselwerte)
        {
            if (liste)
            {
                l. Einfuegen (d);
            }
            if (baum)
            {
                b. Einfuegen (d);
            }
        }
        summe1 = 0;
        summe2 = 0;
        for (int i = 1; i <= anzahl; i++)
        {
            DATENELEMENT d;
            d = TestWaehlen ();
            if (liste)
            {
                summe1 += ZeitFuerListenSucheMessen (d);
            }
            if (baum)
            {
                summe2 += ZeitFuerBaumSucheMessen (d);
            }
        }
        summe1 /= anzahl;
        summe2 /= anzahl;
    }
    
    /**
     * Meldet die durchschnittliche Zeit f&uuml;r die Suche in der Liste.
     * @return Suchzeit
     */
    public long ZeitFuerListensucheGeben ()
    {
        return summe1;
    }
    
    /**
     * Meldet die durchschnittliche Zeit f&uuml;r die Suche im Baum.
     * @return Suchzeit
     */
    public long ZeitFuerBaumsucheGeben ()
    {
        return summe2;
    }
}
