/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package hw10;
import java.util.*;

/**
 *
 * @author kvaradar
 */
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here

        double f = 0.1;
        double rand;
        LinkedList<Integer> MyQueue = new LinkedList<Integer>();
        /* A queue for storing last 100000 ipAddresses seen */
        Hashtable<Integer,MyWord> h = new Hashtable<Integer,MyWord>();
        /* A hash table for remembering the frequency of the ipAddresses
         * among the last 100000
         */
        Collection<MyWord> c;
        Iterator<MyWord> itr;
        MyWord mostFrequent, temp, htWord;
        int newIPAddress,oldIPAddress;

        /* First implementation of algorithm begins*/
        long tStart = System.currentTimeMillis();

        for (int j = 0; j < 1000000; j ++) {
            // process 10000000 events

            // first generate event

            rand = Math.random();
            if (rand < f) { // a query for most frequent word
                c = h.values(); //returns collection of ipAddresses with frequencies
                itr = c.iterator();
                if (itr.hasNext()) {//collection is non-empty, else query is pointless
                    mostFrequent = itr.next(); //initialize to first thing in collection
                    while(itr.hasNext()) { //go thru collection to find most frequent
                        temp = itr.next();
                        if (temp.frequency > mostFrequent.frequency)
                            mostFrequent = temp;
                    }
                //System.out.println("Most frequent ipAddress is: " + mostFrequent.ipAddress);
                }
            }
            else { // next event is another ipAddress
                newIPAddress = (int) (10000 * Math.random());
                // System.out.println(newIPAddress);
                MyQueue.add(newIPAddress);
                htWord = h.get(newIPAddress);
                if (htWord == null) { //newIPAddress not among the ones in hash table
                    h.put(newIPAddress, new MyWord(newIPAddress,1));
                }
                else {
                    htWord.frequency = htWord.frequency + 1;
                    h.put(newIPAddress, htWord);
                }

                if (MyQueue.size() > 100000) { // need to remove the statistic of
                                               // most ancient word in our window
                    oldIPAddress = MyQueue.get(0);
                    htWord = h.get(oldIPAddress);
                    if (htWord != null) {
                        if (htWord.frequency <= 1)
                            h.remove(oldIPAddress);
                        else {
                            htWord.frequency = htWord.frequency - 1;
                            h.put(oldIPAddress, htWord);
                        }

                    }
                    MyQueue.remove(0);
                }
            }
        }

        long tEnd = System.currentTimeMillis();
        System.out.println("Time taken in milliseconds: " + (tEnd - tStart));
        /*First implementation ends */


        MyQueue.clear();
        Hashtable<Integer,Entry<Integer,Integer>> h1 = new Hashtable<Integer,Entry<Integer,Integer>>();
        AdaptablePriorityQueue<Integer,Integer> pq = new AdaptablePriorityQueue<Integer,Integer>();
        int topIPAddress;
        Entry<Integer,Integer> entry1,entry2;
        /* Second implementation runs, though on diferent input */
        tStart = System.currentTimeMillis();

        for (int j = 0; j < 1000000; j ++) {
            // process 10000000 events

            // first generate event

            rand = Math.random();
            if (rand < f) {// a query for most frequent IP address

                if (pq.size() > 0)
                  topIPAddress = pq.min().getValue();// get the most frequent IP address
                                                   // from the priority queue
                //System.out.println("Most frequent IP Address is: " + topIPAddress);
            }
            else { // next event is another ipAddress
                newIPAddress = (int) (10000 * Math.random());
                //System.out.println(newIPAddress);
                MyQueue.add(newIPAddress);
                entry1 = h1.get(newIPAddress);
                if (entry1 == null) { //newIPAddress not among the ones in hash table
                    h1.put(newIPAddress, pq.insert(1,newIPAddress));
                }
                else {
                    pq.replaceKey(entry1, entry1.getKey() + 1);
                }

                if (MyQueue.size() > 100000) { // need to remove the statistic of
                                               // most ancient word in our window
                    oldIPAddress = MyQueue.get(0);
                    entry2 = h1.get(oldIPAddress);
                    if (entry2 != null) { // if done right, it won't be null
                        if (entry2.getKey() <= 1){
                            pq.remove(entry2);
                            h1.remove(oldIPAddress);
                        }
                        else {
                            pq.replaceKey(entry2, entry2.getKey() - 1);
                        }

                    }
                    MyQueue.remove(0);
                }
            }
        }

        tEnd = System.currentTimeMillis();
        System.out.println("Time taken in milliseconds: " + (tEnd - tStart));
    }

}
