//+----------------------------------------------------------------------+
//|								    DAPsim								 |
//| Dean Morrison												11/30/06 |
//| University of Florida												 |
//| Department of Electrical and Computer Engineering					 |
//+----------------------------------------------------------------------+
//| Description: DAPsim is a trace-driven simulator developed in C++ for |
//| the purpose of designing, testing, and evaluating demand prepaging 	 |
//| policies.  It currently implements my proposed concept of Dynamically|
//| Adaptive Prepaging, but may be modified to evaluate many other 		 |
//| policies.															 |
//|																		 |
//| Reuse Policy: Use of this software for personal or instructional	 |
//| purposes is granted without fee provided that the source bears a	 |
//| clear and complete citation.										 |
//+----------------------------------------------------------------------+

#include <string>
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <list>
#include <map>
#include <math.h>

#include "main.h"
#include "UsedPageQ.h"
#include "PrepagedPageQ.h"

using namespace std;

class VirtualMMU {
private:
	int MMSize;			// Size of Main Memory
	int prepagedAlloc;	// Max size of Prepaged Queue
	int degree;
	int predictionScheme;
	int historySize;
	UsedPageQ usedPageQ;
	PrepagedPageQ prepagedPageQ;

public:
	// Prediction lists used to determine most effective prediction scheme
	vector<unsigned long int> addressLocalPredictions;
	vector<unsigned long int> recencyLocalPredictions;
	vector<unsigned long int> stridePredictions;
	vector<unsigned long int> hybridPredictions;
	// Prediction histograms
	int addressLocalHistogram[DEFAULT_MAX_DEGREE];
	int recencyLocalHistogram[DEFAULT_MAX_DEGREE];
	int strideHistogram[DEFAULT_MAX_DEGREE];
	int hybridHistogram[DEFAULT_MAX_DEGREE];

	// Global Variables
	long int transfers;
	double avg_transfer;
	double transfer_rate;

	VirtualMMU();
	VirtualMMU(int newMMSize, int newPrepagedAlloc, int newDegree, int newPredictionScheme);

	void printVMMU(void);
	
	void setMMSize(int newMMSize);
	void setPrepagedAlloc(int newPrepagedAlloc);
	void setDegree(int newDegree);
	void setHistorySize(int newHistorySize);

	int getMMSize(void);
	int getPrepagedAlloc(void);
	int getDegree(void);
	int getHistorySize(void);

	int incDegree(void);
	int decDegree(void);

	UsedPageQ * getUsedPageQ(void);
	PrepagedPageQ * getPrepagedPageQ(void);

	int handlePageRef(unsigned long int referencedPage, int preParamMode);

	vector<unsigned long int> generatePrepageList(unsigned long int referencedPage);
	void printPrepageList(vector<unsigned long int> *prepageList);
	void fetchPrepages(vector<unsigned long int> prepageList);

	void updatePrepagedAlloc(void);
	void updateDegree(void);
	void updatePredictionScheme(void);

	unsigned int calculateBenefit(int targetAlloc);
	unsigned int calculateCost(int targetAlloc);

	void initializePredictionHistograms(void);
	void clearPredictionHistograms(void);
	int calculateHistTotal(int histogram[]);
	void updatePredictionHistograms(unsigned long int referencedPage);
	void printPredictionHistograms(void);
	void printPredictionLists(void);

};
