diff --git a/CachePrefetchManagement.c b/CachePrefetchManagement.c new file mode 100644 index 0000000..a6dbf32 --- /dev/null +++ b/CachePrefetchManagement.c @@ -0,0 +1,460 @@ +#include "CachePrefetchManagement.h" +#include "CachePrefetchManagementApi.h" +#include +#include + +#define _CRT_SECURE_NO_WARNINGS // Required for localtime_s on some compilers + +#pragma region Init variables + +SequenceCollectionCtrlBlk_t* prefetchSeqCollection_CB; + +FILE* ErrorFile; + +void Prefetch_INIT(void) +{ + char filename[] = "ErrorLog.txt"; + + // Open the file for writing without overwriting existing content + if (fopen_s(&ErrorFile, filename, "a") != 0) { + perror("Unable to open the file for writing"); + exit(1); + } + + prefetchSeqCollection_CB = (SequenceCollectionCtrlBlk_t*)malloc(sizeof(SequenceCollectionCtrlBlk_t)); + + if (prefetchSeqCollection_CB == NULL) { + fprintf(ErrorFile, "Failed to allocate memory for Sequence Pointer - - - "); + PrintCurrentTimeToErrorFile(); + fclose(ErrorFile); + perror("Failed to allocate memory for Sequence Pointer"); + exit(1); + } + + prefetchSeqCollection_CB->singleRangesArray.index = 0; + + + //initial the SeqRangeInfoArray with garbage values + for (int i = 0; i < MAX_SUPPORTED_PARALLEL_RANGE; i++) + { + prefetchSeqCollection_CB->seqRangeInfoArray[i] = (SeqRangeInfo_t*)malloc(sizeof(SeqRangeInfo_t)); + + if (prefetchSeqCollection_CB->seqRangeInfoArray[i] == NULL) { + fprintf(ErrorFile, "Failed to allocate memory for prefetchSeqCollection_CB->seqRangeInfoArray - - - "); + PrintCurrentTimeToErrorFile(); + fclose(ErrorFile); + perror("Failed to allocate memory for prefetchSeqCollection_CB->seqRangeInfoArray"); + exit(1); + } + + prefetchSeqCollection_CB->seqRangeInfoArray[i]->counter = -1; + + prefetchSeqCollection_CB->seqRangeInfoArray[i]->counterUse = -1; + + prefetchSeqCollection_CB->seqRangeInfoArray[i]->dir = IN_VALID_DIR; + + prefetchSeqCollection_CB->seqRangeInfoArray[i]->lastInsertedRange = GetDefaultRange(); + + prefetchSeqCollection_CB->seqRangeInfoArray[i]->nextExpectedRange = GetDefaultRange(); + + prefetchSeqCollection_CB->singleRangesArray.array[i] = GetDefaultRange(); + + prefetchSeqCollection_CB->RangesInLoadingArray[i] = GetDefaultRange(); + + } +} + +#pragma endregion + +#pragma region Range Functions + +bool CheckValidationOfRange(Range_t range) +{ + if (!(IsEqualRanges(GetDefaultRange(), range))) + if (range.topLeft.x + SUPPORTED_RANGE_WIDTH == range.bottomRight.x && range.topLeft.y - SUPPORTED_RANGE_LENGTH == range.bottomRight.y) + return true; + return false; +} +//get default range for delete range +Range_t GetDefaultRange(void) { + Range_t defRange = INIT_RANGE_VALUE; + return defRange; +} + +//check if the 2 ranges are equal +bool IsEqualRanges(Range_t me, Range_t other) +{ + return me.bottomRight.x == other.bottomRight.x && + me.bottomRight.y == other.bottomRight.y && + me.topLeft.x == other.topLeft.x && + me.topLeft.y == other.topLeft.y; +} + +//function to get the next expected range of sequence by the sequence's direction +Range_t GetNextRangeByDirection(Range_t range, Range_Direction_t dir) +{ + int bottomRightX = range.bottomRight.x; + int bottomRightY = range.bottomRight.y; + int topLeftX = range.topLeft.x; + int topLeftY = range.topLeft.y; + + switch (dir) { + case UP: + bottomRightY = range.bottomRight.y + SUPPORTED_RANGE_LENGTH;//up the bottomRightY in SUPPORTED_RANGE_LENGTH + topLeftY = range.topLeft.y + SUPPORTED_RANGE_LENGTH;//up the topLeftY in SUPPORTED_RANGE_LENGTH + break; + case DOWN: + bottomRightY = range.bottomRight.y - SUPPORTED_RANGE_LENGTH;//down bottomRightY in SUPPORTED_RANGE_LENGTH + topLeftY = range.topLeft.y - SUPPORTED_RANGE_LENGTH;//down topLeftY in SUPPORTED_RANGE_LENGTH + break; + case LEFT: + bottomRightX = range.bottomRight.x - SUPPORTED_RANGE_WIDTH;//down the bottomRightX in SUPPORTED_RANGE_WIDTH + topLeftX = range.topLeft.x - SUPPORTED_RANGE_WIDTH;//down the topLeftX in SUPPORTED_RANGE_WIDTH + break; + case RIGHT: + bottomRightX = range.bottomRight.x + SUPPORTED_RANGE_WIDTH;//up the bottomRightX in SUPPORTED_RANGE_WIDTH + topLeftX = range.topLeft.x + SUPPORTED_RANGE_WIDTH;//up the topLeftX in SUPPORTED_RANGE_WIDTH + break; + } + //set the bottomRight Point_t + Point_t myBottomRight = { bottomRightX,bottomRightY }; + + //set the topLeft Point + Point_t myTopLeft = { topLeftX , topLeftY }; + + Range_t nextRange = { myBottomRight,myTopLeft };//set the new Range to return + //declare the variables to the start... + return nextRange; +} + +//return the direction that the range continue the single range and IN_VALID_DIR if it not continue +Range_Direction_t IsRangeCompleteSingleRangeToSequence(Range_t range, Range_t singleRange) +{ + //same longitude line + if (range.topLeft.x == singleRange.topLeft.x) { + //if the y of topLeft of current Range_t same my bottomRight y - it down direction + if (range.topLeft.y == singleRange.bottomRight.y) + return DOWN; + + //if the y of bottom right of current Range_t same my topLeft y - it up direction + if (range.bottomRight.y == singleRange.topLeft.y) + return UP; + } + + else if (range.topLeft.y == singleRange.topLeft.y) { + + //if the x of topLeft of current Range_t same myBottomRight x - it right direction + if (range.topLeft.x == singleRange.bottomRight.x) + return RIGHT; + + //if the x of topLeft of current Range_t same myBottomRight x - it down direction + + if (range.bottomRight.x == singleRange.topLeft.x) + return LEFT; + } + //if the current Range_t doesn't continue according to any direction + return IN_VALID_DIR; +} + +//for check if range in loading +bool IsRangeContainedInOtherRange(Range_t currentSmallRange, Range_t containRange) +{ + if ((containRange.topLeft.x <= currentSmallRange.topLeft.x) && + (containRange.topLeft.y >= currentSmallRange.topLeft.y) && + (containRange.bottomRight.x >= currentSmallRange.bottomRight.x) && + (containRange.bottomRight.y <= currentSmallRange.bottomRight.y)) { + + return true; // True, Range_t is contained + } + return false; // False, Range_t is not contained +} + +#pragma endregion + +#pragma region sequence Collection Functions + +// Function to check if a given range continues an existing sequence in seqRangeInfoArray. +int IsRangeContinueSequence(Range_t range) +{ + int index = -1; + + // Iterate through prefetchSeqCollection_CB to find a match for range's NextExpectedRange. + for (int i = 0; i < MAX_SUPPORTED_PARALLEL_RANGE; i++) + { + + if (IsEqualRanges(prefetchSeqCollection_CB->seqRangeInfoArray[i]->nextExpectedRange, range)) { + + // Update sequence details if range continues the sequence. + prefetchSeqCollection_CB->seqRangeInfoArray[i]->counterUse = 0; + prefetchSeqCollection_CB->seqRangeInfoArray[i]->lastInsertedRange = range; + prefetchSeqCollection_CB->seqRangeInfoArray[i]->nextExpectedRange = GetNextRangeByDirection(range, prefetchSeqCollection_CB->seqRangeInfoArray[i]->dir); + prefetchSeqCollection_CB->seqRangeInfoArray[i]->counter++; + index = i; + break; + } + } + return index; +} + +// Function to check if a given range continues an existing range in singleRangeArray to sequence. +//if y create the new sequence +int IsRangeCreateNewSequence(Range_t range) +{ + int index = -1; + SeqRangeInfo_t* newSeq; + newSeq = (SeqRangeInfo_t*)malloc(sizeof(SeqRangeInfo_t)); + Range_Direction_t direction = IN_VALID_DIR; + // Function to check if a given range creates a new sequence by comparing it with ranges in singleRangesArray. + for (int i = 0; i < MAX_SUPPORTED_PARALLEL_RANGE; i++) + { + // Check if range creates a new sequence with singleRangesArray[i]. + if (!IsEqualRanges(prefetchSeqCollection_CB->singleRangesArray.array[i], GetDefaultRange())) + { + direction = IsRangeCompleteSingleRangeToSequence(range, prefetchSeqCollection_CB->singleRangesArray.array[i]); + } + if (direction != IN_VALID_DIR) + { + // Create new sequence and update prefetchSeqCollection_CB; remove corresponding range from singleRangesArray. + + newSeq->counter = INIT_COUNTER; + newSeq->counterUse = 0; + newSeq->dir = direction; + newSeq->lastInsertedRange = range; + newSeq->nextExpectedRange = GetNextRangeByDirection(range, direction); + + index = GetLastUsedSequence(); + prefetchSeqCollection_CB->seqRangeInfoArray[index] = newSeq; + + prefetchSeqCollection_CB->singleRangesArray.array[i] = GetDefaultRange(); + + direction = IN_VALID_DIR; + return index; + } + } + return index; +} + +//for LRU +int GetLastUsedSequence(void) +{ + int max = -1; + int index = -1; + // Iterates through prefetchSeqCollection_CB_t to find the sequence with the highest CounterUse. + for (int i = 0; i < MAX_SUPPORTED_PARALLEL_RANGE; i++) { + if (prefetchSeqCollection_CB->seqRangeInfoArray[i]->counterUse == -1) { + return i; + } + if (prefetchSeqCollection_CB->seqRangeInfoArray[i]->counterUse > max) { + index = i; + max = prefetchSeqCollection_CB->seqRangeInfoArray[i]->counterUse; + } + } + return index; +} + +void Prefetch_InsertNewRange(Range_t range) +{ + if (!CheckValidationOfRange(range)) + { + fprintf(ErrorFile, "The inserted range is not valid - - - "); + PrintCurrentTimeToErrorFile(); + perror("The inserted range is not valid\n"); + } + else + InsertNewRange(range); +} + +//insert new range to the prefetchSeqCollection_CB and return if the range is single/create new sequence / continue an existing sequence +INSERT_ACTION_TYPE_t InsertNewRange(Range_t range)//return enum of state insert +{ + + //if the range continue sequence, insert it to sequence collection + int index = IsRangeContinueSequence(range); + + // If range continues an existing sequence, call ReadingAhead for asking the next range. + if (index != -1) { + IncreaseAllLRUCountersExceptSpecificCounter(index); + ReadingAhead(prefetchSeqCollection_CB->seqRangeInfoArray[index]); + return CONTINUE_SEQ; + } + + // Check if range creates a new sequence + // if true, insert it to sequence collection and remove the prev range from the single ranges collection + + index = IsRangeCreateNewSequence(range); + if (index != -1) { + IncreaseAllLRUCountersExceptSpecificCounter(index); + return CREATE_SEQ; + } + // if not, insert it into singleRangesArray + prefetchSeqCollection_CB->singleRangesArray.array[prefetchSeqCollection_CB->singleRangesArray.index] = range; + prefetchSeqCollection_CB->singleRangesArray.index = (prefetchSeqCollection_CB->singleRangesArray.index + 1) % MAX_SUPPORTED_PARALLEL_RANGE; + return INSERT_TO_SINGLE_RANGES_ARRAY; +} + +void IncreaseAllLRUCountersExceptSpecificCounter(int index) { + //run over on seqRangeInfoArray + for (int i = 0; i < MAX_SUPPORTED_PARALLEL_RANGE; i++) { + //if seqRangeInfoArray[i] is not the seq in index of seqRangeInfoArray that continue now + //and if it is not a null seqRangeInfoArray, update the counterUse up + if (i != index && !IsEqualRanges(prefetchSeqCollection_CB->seqRangeInfoArray[i]->lastInsertedRange, GetDefaultRange())) { + prefetchSeqCollection_CB->seqRangeInfoArray[i]->counterUse++; + } + } +} + +#pragma endregion + + +//read range/s ahead if its needed +void ReadingAhead(SeqRangeInfo_t* seq) +{ + Range_t r; + Range_Direction_t dir = seq->dir; + //if it is a new enough sequence, read double range + if (seq->counter == SIZE_OF_ENOUGH_SEQ) + { + r = seq->lastInsertedRange; + + for (size_t i = 0; i < COUNT_OF_RANGE_TO_READING_AHEAD; i++) + { + // Read two ranges forward and handle caching operations from disk. + r = GetNextRangeByDirection(r, seq->dir); + if (dir == DOWN) + { + if (r.bottomRight.y < 0) + r.bottomRight.y = 0; + } + else if (dir == LEFT) + { + if (r.topLeft.x < 0) + r.topLeft.x = 0; + } + AddRangeToLoadingRangeArray(r); + FetchFromDisk(r); + } + + r = GetNextRangeByDirection(r, seq->dir); + //send req to cache to load this range + return; + } + + else + { + r = seq->lastInsertedRange; + // Read two ranges forward and handle caching operations from disk. + for (int i = 0; i < COUNT_OF_RANGE_TO_READING_AHEAD; i++) + { + r = GetNextRangeByDirection(r, seq->dir); + } + //send req to cache to load this range + + //if the range need to reading ahead is not valid, read until the valid + if (dir == DOWN) { + if (r.bottomRight.y < 0) + r.bottomRight.y = 0; + } + + else if (dir == LEFT) { + if (r.topLeft.x < 0) + r.topLeft.x = 0; + } + AddRangeToLoadingRangeArray(r); + FetchFromDisk(r); + } +} + +#pragma region RangesInLoadingArray Functions + +//check if range in loading +bool Prefetch_IsRangeInLoading(Range_t rangeForSearch) +{ + if ((IsEqualRanges(GetDefaultRange(), rangeForSearch))) + { + fprintf(ErrorFile, "The range to found is not valid - - - "); + PrintCurrentTimeToErrorFile(); + perror("The range to found is not valid\n"); + } + else + { + for (int i = 0; i < MAX_SUPPORTED_PARALLEL_RANGE; i++) + { + if (IsRangeContainedInOtherRange(rangeForSearch, prefetchSeqCollection_CB->RangesInLoadingArray[i])) + return true; + } + } + return false; +} + +//remove loaded range from loadingArray +void Prefetch_RemoveRangeFromLoadingRanges(Range_t rangeForRemove) +{ + int index = FindRangeInLoadingRangesArray(rangeForRemove); + if (index != -1) + prefetchSeqCollection_CB->RangesInLoadingArray[index] = GetDefaultRange(); +} + +//get the next empty index in loadingArray +int GetNextEmptyIndexOfRangesInLoadingArray(void) +{ + int index = -1, i = 0; + while (index == -1 && i <= MAX_SUPPORTED_PARALLEL_RANGE) + { + if (IsEqualRanges(prefetchSeqCollection_CB->RangesInLoadingArray[i], GetDefaultRange())) + index = i; + else + i++; + } + return index == -1 ? 0 : index; +} + +//find the index of range +int FindRangeInLoadingRangesArray(Range_t rangeForRemove) +{ + int index = -1, i = 0; + while (index == -1 && i <= MAX_SUPPORTED_PARALLEL_RANGE) + { + if (IsEqualRanges(prefetchSeqCollection_CB->RangesInLoadingArray[i], rangeForRemove)) + index = i; + else + i++; + } + return index; +} + +//add range to loadingArray +void AddRangeToLoadingRangeArray(Range_t rangeForAdd) +{ + prefetchSeqCollection_CB->RangesInLoadingArray[GetNextEmptyIndexOfRangesInLoadingArray()] = rangeForAdd; +} +#pragma endregion + +void PrintCurrentTimeToErrorFile(void) +{ + time_t now; // Variable to hold the current time in seconds since Epoch + struct tm local_time; // Structure to store local time details + + // Get the current time securely + if (time(&now) == -1) { + perror("Error getting current time"); // Print an error message if getting current time fails + } + + // Convert the current time to local time structure securely + if (localtime_s(&local_time, &now) != 0) { + perror("Error converting to local time"); // Print an error message if conversion fails + } + + // Print the current date and time in the format "YYYY-MM-DD HH:MM:SS" + fprintf(ErrorFile, "The current date and time is: %04d-%02d-%02d %02d:%02d:%02d\n", + local_time.tm_year + 1900, // Year since 1900 + local_time.tm_mon + 1, // Month [0, 11] + local_time.tm_mday, // Day of the month [1, 31] + local_time.tm_hour, // Hours [0, 23] + local_time.tm_min, // Minutes [0, 59] + local_time.tm_sec); // Seconds [0, 59] +} + +void FetchFromDisk(Range_t range) +{ + //fetch from disk +} \ No newline at end of file diff --git a/CachePrefetchManagement.h b/CachePrefetchManagement.h new file mode 100644 index 0000000..6bedbea --- /dev/null +++ b/CachePrefetchManagement.h @@ -0,0 +1,122 @@ +#pragma once +#include +#include // For malloc, free +#define MAX_SUPPORTED_PARALLEL_RANGE 4 +#define SUPPORTED_RANGE_LENGTH 1 +#define SUPPORTED_RANGE_WIDTH 1 +#define INIT_COUNTER 2 +#define SIZE_OF_ENOUGH_SEQ 3 +#define INIT_POINT_VALUE { -1,-1 } +#define COUNT_OF_RANGE_TO_READING_AHEAD 2 +#define INIT_RANGE_VALUE {INIT_POINT_VALUE,INIT_POINT_VALUE} + +//struct that representing a point in a plane +typedef struct Point_s +{ + int x; + int y; +}Point_t; + +//struct that representing range of two points in a plane, bottom-right and top-left +typedef struct Range_s +{ + Point_t bottomRight; + Point_t topLeft; +}Range_t; + +//enum of the optional direction of sequences +typedef enum Range_Direction_e { + RIGHT, + LEFT, + UP, + DOWN, + IN_VALID_DIR +}Range_Direction_t; + +//enum of optional types of action in the insert function +typedef enum INSERT_ACTION_TYPE_e { + CONTINUE_SEQ, + CREATE_SEQ, + INSERT_TO_SINGLE_RANGES_ARRAY +}INSERT_ACTION_TYPE_t; + +//struct that representing information of sequence +typedef struct SeqRangeInfo_s +{ + Range_t lastInsertedRange; + Range_t nextExpectedRange; + Range_Direction_t dir; + int counterUse; + int counter; +}SeqRangeInfo_t; + +typedef struct CyclicArray_s { + Range_t array[MAX_SUPPORTED_PARALLEL_RANGE]; + int index; +}CyclicArray_t; + +//control block of the program +typedef struct SequenceCollectionCtrlBlk_s { + SeqRangeInfo_t* seqRangeInfoArray[MAX_SUPPORTED_PARALLEL_RANGE]; + CyclicArray_t singleRangesArray; + Range_t RangesInLoadingArray[MAX_SUPPORTED_PARALLEL_RANGE]; +}SequenceCollectionCtrlBlk_t; + +#pragma region Range Functions + +//function init the range +Range_t GetDefaultRange(void); + +//function get direction, range and num, and return the next range by the direction, double the num +Range_t GetNextRangeByDirection(Range_t range, Range_Direction_t dir); + +bool IsEqualRanges(Range_t me, Range_t other); + +//function check if currentSmallRange contained in containRange +bool IsRangeContainedInOtherRange(Range_t currentSmallRange, Range_t containRange); + +//function check if new range complete the last inserted range to sequence by some direction, if true it return the direction +Range_Direction_t IsRangeCompleteSingleRangeToSequence(Range_t range, Range_t singleRange); + +#pragma endregion + +#pragma region SequenceCollectionCtrlBlk Functions + +//function return the index to override by LRU +int GetLastUsedSequence(void); + +//internal function called by the external function-InsertNewRangeAPI +INSERT_ACTION_TYPE_t InsertNewRange(Range_t range); + +//function of Reading ahead when the seq is enough +void ReadingAhead(SeqRangeInfo_t* seq); + +//function of check if the new range continue some exist seq, and return the index of the found seq +int IsRangeContinueSequence(Range_t range); + +//function of check if the new range create new seq with single range from singleRangesArray +int IsRangeCreateNewSequence(Range_t range); + +//function of get index of seq that update now and up the counter use of the others seqs +void IncreaseAllLRUCountersExceptSpecificCounter(int index); +#pragma endregion + +#pragma region RangesInLoadingArray Functions + +//function return the index of the empty place of loadingArray +int GetNextEmptyIndexOfRangesInLoadingArray(void); + + +//function find the index of range in loadingArray +int FindRangeInLoadingRangesArray(Range_t rangeForRemove); + +//function get range and add it to the loadingArray +void AddRangeToLoadingRangeArray(Range_t rangeForAdd); + +bool CheckValidationOfRange(Range_t range); +#pragma endregion + +void PrintCurrentTimeToErrorFile(void); + +void FetchFromDisk(Range_t range); +//void Test(void); diff --git a/CachePrefetchManagementApi.h b/CachePrefetchManagementApi.h new file mode 100644 index 0000000..24090b7 --- /dev/null +++ b/CachePrefetchManagementApi.h @@ -0,0 +1,12 @@ +#pragma once + +//function that get range and check if its in loading +bool Prefetch_IsRangeInLoading(Range_t rangeForSearch); + +//function that get range to remove, find it and delete it from loadingArray +void Prefetch_RemoveRangeFromLoadingRanges(Range_t rangeForRemove); + +//external function of insert new range +void Prefetch_InsertNewRange(Range_t range); + +void Prefetch_INIT(void); diff --git a/ErrorLog.txt b/ErrorLog.txt new file mode 100644 index 0000000..c0eebae --- /dev/null +++ b/ErrorLog.txt @@ -0,0 +1,60 @@ + +Failed to allocate memory for Sequence Pointer - - - The current time is: 13:15:55 +The range to found is not valid - - - The current time is: 17:33:06 +The range to found is not valid - - - The current time is: 17:35:12 +The range to found is not valid - - - The current time is: 17:36:14 +The range to found is not valid - - - The current time is: 17:39:46 +The range to found is not valid - - - The current time is: 17:43:04 +The range to found is not valid - - - The current time is: 17:43:04 +The range to found is not valid - - - The current time is: 17:43:04 +The range to found is not valid - - - The current time is: 17:44:25 +The range to found is not valid - - - The current time is: 17:44:25 +The range to found is not valid - - - The current time is: 17:44:25 +The range to found is not valid - - - The current time is: 17:45:02 +The range to found is not valid - - - The current time is: 17:45:02 +The range to found is not valid - - - The current time is: 17:45:02 +The inserted range is not valid - - - The current time is: 12:08:27 +The inserted range is not valid - - - The current time is: 12:13:29 +The inserted range is not valid - - - The current time is: 12:13:29 +The inserted range is not valid - - - The current date and time is: 2024-07-29 12:16:48 +The inserted range is not valid - - - The current date and time is: 2024-07-29 12:16:48 +The inserted range is not valid - - - The current date and time is: 2024-07-29 13:10:23 +The inserted range is not valid - - - The current date and time is: 2024-07-29 13:10:23 +The inserted range is not valid - - - The current date and time is: 2024-09-15 10:19:08 +The inserted range is not valid - - - The current date and time is: 2024-09-15 10:19:08 +The inserted range is not valid - - - The current date and time is: 2024-09-15 10:38:50 +The inserted range is not valid - - - The current date and time is: 2024-09-15 10:38:50 +The inserted range is not valid - - - The current date and time is: 2024-09-15 10:47:07 +The inserted range is not valid - - - The current date and time is: 2024-09-15 10:47:07 +The inserted range is not valid - - - The current date and time is: 2024-09-15 10:49:09 +The inserted range is not valid - - - The current date and time is: 2024-09-15 10:49:09 +The inserted range is not valid - - - The current date and time is: 2024-09-15 10:51:02 +The inserted range is not valid - - - The current date and time is: 2024-09-15 10:51:02 +The inserted range is not valid - - - The current date and time is: 2024-09-15 10:54:08 +The inserted range is not valid - - - The current date and time is: 2024-09-15 10:54:08 +The inserted range is not valid - - - The current date and time is: 2024-09-15 10:58:40 +The inserted range is not valid - - - The current date and time is: 2024-09-15 10:58:40 +The inserted range is not valid - - - The current date and time is: 2024-09-15 11:04:57 +The inserted range is not valid - - - The current date and time is: 2024-09-15 11:04:57 +The inserted range is not valid - - - The current date and time is: 2024-09-15 11:08:45 +The inserted range is not valid - - - The current date and time is: 2024-09-15 11:08:45 +The inserted range is not valid - - - The current date and time is: 2024-09-15 11:55:25 +The inserted range is not valid - - - The current date and time is: 2024-09-15 11:55:25 +The inserted range is not valid - - - The current date and time is: 2024-09-15 11:57:33 +The inserted range is not valid - - - The current date and time is: 2024-09-15 11:57:33 +The inserted range is not valid - - - The current date and time is: 2024-09-15 12:00:03 +The inserted range is not valid - - - The current date and time is: 2024-09-15 12:00:03 +The inserted range is not valid - - - The current date and time is: 2024-09-15 12:03:46 +The inserted range is not valid - - - The current date and time is: 2024-09-15 12:03:46 +The inserted range is not valid - - - The current date and time is: 2024-09-15 12:07:12 +The inserted range is not valid - - - The current date and time is: 2024-09-15 12:07:12 +The inserted range is not valid - - - The current date and time is: 2024-09-15 12:08:47 +The inserted range is not valid - - - The current date and time is: 2024-09-15 12:08:47 +The inserted range is not valid - - - The current date and time is: 2024-09-15 12:13:56 +The inserted range is not valid - - - The current date and time is: 2024-09-15 12:13:56 +The inserted range is not valid - - - The current date and time is: 2024-09-15 12:24:42 +The inserted range is not valid - - - The current date and time is: 2024-09-15 12:24:42 +The inserted range is not valid - - - The current date and time is: 2024-09-15 12:24:42 +The inserted range is not valid - - - The current date and time is: 2024-09-15 12:24:42 +The inserted range is not valid - - - The current date and time is: 2024-09-15 12:32:17 +The inserted range is not valid - - - The current date and time is: 2024-09-15 12:32:17 diff --git a/Storage/.vs/Storage/FileContentIndex/8d8b4053-de17-436d-b9e4-2fe3f0ebdc18.vsidx b/Storage/.vs/Storage/FileContentIndex/8d8b4053-de17-436d-b9e4-2fe3f0ebdc18.vsidx new file mode 100644 index 0000000..fece554 Binary files /dev/null and b/Storage/.vs/Storage/FileContentIndex/8d8b4053-de17-436d-b9e4-2fe3f0ebdc18.vsidx differ diff --git a/Storage/.vs/Storage/v17/.suo b/Storage/.vs/Storage/v17/.suo new file mode 100644 index 0000000..75f1677 Binary files /dev/null and b/Storage/.vs/Storage/v17/.suo differ diff --git a/Storage/.vs/Storage/v17/Browse.VC.db b/Storage/.vs/Storage/v17/Browse.VC.db new file mode 100644 index 0000000..8aa90a6 Binary files /dev/null and b/Storage/.vs/Storage/v17/Browse.VC.db differ diff --git a/TestsByDoctest.cpp b/TestsByDoctest.cpp new file mode 100644 index 0000000..52cbc33 --- /dev/null +++ b/TestsByDoctest.cpp @@ -0,0 +1,398 @@ +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "./doctest/doctest/doctest.h" + +extern "C" { +#include "CachePrefetchManagement.h" +#include "CachePrefetchManagementApi.h" + + Range_t TestControlBlock[25];//control block to Test.c + extern SequenceCollectionCtrlBlk_t* prefetchSeqCollection_CB;//extern the control block of CachePrefetchManagement.h + +#pragma region PrintFunctions + + void PrintPoint(Point_t p) { + printf(" (%d,%d) ,", p.x, p.y); + } + + void PrintRange(Range_t range) + { + printf("topLeft: "); + PrintPoint(range.topLeft); + printf("bottomRight: "); + PrintPoint(range.bottomRight); + printf("\n"); + } + + void PrintSeq(SeqRangeInfo_t seq) { + printf("lastInsertedRange: "); + PrintRange(seq.lastInsertedRange); + printf("nextExpectedRange: "); + PrintRange(seq.nextExpectedRange); + printf("counterUse: "); + printf("%d", seq.counterUse); + printf("\ncounter: "); + printf("%d", seq.counter); + printf("\nDirection: "); + switch (seq.dir) + { + case 0: + printf("RIGHT\n"); + break; + case 1: + printf("LEFT\n"); + break; + case 2: + printf("UP\n"); + break; + case 3: + printf("DOWN\n"); + break; + case 4: + printf("IN_VALID_DIR\n"); + break; + } + printf("\n"); + + } + + void PrintSeqCollection() { + + printf("information of seq collection now:\n"); + + printf("information of seqRangeInfoArray:\n"); + + for (int i = 0; i < MAX_SUPPORTED_PARALLEL_RANGE; i++) + { + printf("seqRangeInfoArray[%d]:\n", i); + PrintSeq(*(prefetchSeqCollection_CB->seqRangeInfoArray[i])); + } + + printf("information of singleRangesArray.array:\n"); + + for (int i = 0; i < MAX_SUPPORTED_PARALLEL_RANGE; i++) + { + printf("singleRangesArray.array[%d]:\n", i); + PrintRange(prefetchSeqCollection_CB->singleRangesArray.array[i]); + } + + printf("\ninformation of RangesInLoadingArray:\n"); + + for (int i = 0; i < MAX_SUPPORTED_PARALLEL_RANGE; i++) + { + printf("RangesInLoadingArray[%d]:\n", i); + PrintRange(prefetchSeqCollection_CB->RangesInLoadingArray[i]); + } + } +#pragma endregion + + void InitTestControlBlock() { + int topLeftX; + int topLeftY; + int bottomRightX; + int bottomRightY; + Range_Direction_t dir; + TestControlBlock[0].bottomRight = { 5, 0 }; + TestControlBlock[0].topLeft = { 1, 10 }; + TestControlBlock[1].bottomRight = { 4, 3 }; + TestControlBlock[1].topLeft = { 2, 9 }; + + TestControlBlock[2].bottomRight = { 0, 0 }; + TestControlBlock[2].topLeft = { 0, 0 }; + TestControlBlock[3].bottomRight = {3,1 }; + TestControlBlock[3].topLeft = { 2,2 }; + TestControlBlock[4].bottomRight = { 3,2 }; + TestControlBlock[4].topLeft = { 2,3 }; + TestControlBlock[5].bottomRight = { 4,1 }; + TestControlBlock[5].topLeft = { 3, 2 }; + TestControlBlock[6].bottomRight = { 0,0 }; + TestControlBlock[6].topLeft = { 3,3 }; + + TestControlBlock[7] = GetNextRangeByDirection(GetNextRangeByDirection(TestControlBlock[4], UP), UP); + TestControlBlock[8] = GetNextRangeByDirection(GetNextRangeByDirection(TestControlBlock[3], LEFT), LEFT); + TestControlBlock[9] = GetNextRangeByDirection(TestControlBlock[7], UP); + + topLeftX = rand() % 100 + 1; + topLeftY = rand() % 100 + 1; + bottomRightX = topLeftX + 1; + bottomRightY = topLeftY - 1; + dir =Range_Direction_t( rand() % 4); + TestControlBlock[10].bottomRight = { bottomRightX,bottomRightY }; + TestControlBlock[10].topLeft = { topLeftX,topLeftY }; + TestControlBlock[11] = GetNextRangeByDirection(TestControlBlock[10], dir); + TestControlBlock[12] = GetNextRangeByDirection(TestControlBlock[11], dir); + TestControlBlock[13] = GetNextRangeByDirection(TestControlBlock[12], dir); + + topLeftX = rand() % 100 + 1; + topLeftY = rand() % 100 + 1; + bottomRightX = topLeftX + 1; + bottomRightY = topLeftY - 1; + dir =Range_Direction_t( rand() % 4); + + TestControlBlock[14].bottomRight = { bottomRightX,bottomRightY }; + TestControlBlock[14].topLeft = { topLeftX,topLeftY }; + TestControlBlock[15] = GetNextRangeByDirection(TestControlBlock[14], dir); + TestControlBlock[16] = GetNextRangeByDirection(TestControlBlock[15], dir); + TestControlBlock[17] = GetNextRangeByDirection(TestControlBlock[16], dir); + + topLeftX = rand() % 100 + 1; + topLeftY = rand() % 100 + 1; + bottomRightX = topLeftX + 1; + bottomRightY = topLeftY - 1; + dir =Range_Direction_t( rand() % 4); + + TestControlBlock[18].bottomRight = { bottomRightX,bottomRightY }; + TestControlBlock[18].topLeft = { topLeftX,topLeftY }; + TestControlBlock[19] = GetNextRangeByDirection(TestControlBlock[18], dir); + TestControlBlock[20] = GetNextRangeByDirection(TestControlBlock[19], dir); + TestControlBlock[21] = GetNextRangeByDirection(TestControlBlock[20], dir); + + topLeftX = rand() % 100 + 1; + topLeftY = rand() % 100 + 1; + bottomRightX = topLeftX + 1; + bottomRightY = topLeftY - 1; + dir =Range_Direction_t( rand() % 4); + + TestControlBlock[22].bottomRight = { bottomRightX,bottomRightY }; + TestControlBlock[22].topLeft = { topLeftX,topLeftY }; + TestControlBlock[23] = GetNextRangeByDirection(TestControlBlock[22], dir); + TestControlBlock[24] = GetNextRangeByDirection(TestControlBlock[23], dir); + TestControlBlock[25] = GetNextRangeByDirection(TestControlBlock[24], dir); + } + + void TestIsRangeContainedInOtherRange() { + CHECK(IsRangeContainedInOtherRange(TestControlBlock[1], TestControlBlock[0])); + CHECK(IsRangeContainedInOtherRange(TestControlBlock[1], TestControlBlock[1])); + CHECK(IsRangeContainedInOtherRange(TestControlBlock[0], TestControlBlock[0])); + CHECK_FALSE(IsRangeContainedInOtherRange(TestControlBlock[0], TestControlBlock[1])); + } + + void TestIsRangeCompleteSingleRangeToSequence() { + CHECK(IsRangeCompleteSingleRangeToSequence(TestControlBlock[4], TestControlBlock[3]) == UP); + CHECK(IsRangeCompleteSingleRangeToSequence(TestControlBlock[3], TestControlBlock[4]) == DOWN); + CHECK(IsRangeCompleteSingleRangeToSequence(TestControlBlock[3], TestControlBlock[3]) == IN_VALID_DIR); + CHECK(IsRangeCompleteSingleRangeToSequence(TestControlBlock[5], TestControlBlock[3]) == RIGHT); + CHECK(IsRangeCompleteSingleRangeToSequence(TestControlBlock[3], TestControlBlock[5]) == LEFT); + } + + void TestGetNextRangeByDirection() { + + /*PrintRange(TestControlBlock[4]); + + PrintRange(GetNextRangeByDirection(TestControlBlock[3], UP, 1));*/ + + CHECK(IsEqualRanges(GetNextRangeByDirection(TestControlBlock[3], UP), TestControlBlock[4])); + CHECK(IsEqualRanges(GetNextRangeByDirection(TestControlBlock[4], DOWN), TestControlBlock[3])); + CHECK(IsEqualRanges(GetNextRangeByDirection(TestControlBlock[5], LEFT), TestControlBlock[3]) ); + CHECK(IsEqualRanges(GetNextRangeByDirection(TestControlBlock[3], RIGHT), TestControlBlock[5])); + CHECK(IsRangeCompleteSingleRangeToSequence(GetNextRangeByDirection(TestControlBlock[3], UP), TestControlBlock[3]) == UP ); + CHECK(IsRangeCompleteSingleRangeToSequence(GetNextRangeByDirection(TestControlBlock[3], DOWN), TestControlBlock[3]) == DOWN); + CHECK(IsRangeCompleteSingleRangeToSequence(GetNextRangeByDirection(TestControlBlock[3], RIGHT), TestControlBlock[3]) == RIGHT); + CHECK(IsRangeCompleteSingleRangeToSequence(GetNextRangeByDirection(TestControlBlock[3], LEFT), TestControlBlock[3]) == LEFT ); + + } + + void TestIsEqualRanges() + { + CHECK_FALSE(IsEqualRanges(TestControlBlock[1], TestControlBlock[0]) ); + CHECK(IsEqualRanges(TestControlBlock[0], TestControlBlock[0]) ); + + } + + void TestPrefetch_RemoveRangeFromLoadingRanges() { + + CHECK(GetNextEmptyIndexOfRangesInLoadingArray() == 3); + + Prefetch_RemoveRangeFromLoadingRanges(TestControlBlock[8]); + CHECK_FALSE(Prefetch_IsRangeInLoading(TestControlBlock[8])); + CHECK(FindRangeInLoadingRangesArray(TestControlBlock[8]) ==-1); + CHECK(GetNextEmptyIndexOfRangesInLoadingArray() == 2); + + Prefetch_RemoveRangeFromLoadingRanges(TestControlBlock[7]); + CHECK_FALSE(Prefetch_IsRangeInLoading(TestControlBlock[7])); + CHECK(FindRangeInLoadingRangesArray(TestControlBlock[7]) == -1); + CHECK(GetNextEmptyIndexOfRangesInLoadingArray() == 0); + + Prefetch_RemoveRangeFromLoadingRanges(TestControlBlock[9]); + CHECK_FALSE(Prefetch_IsRangeInLoading(TestControlBlock[9])); + CHECK(FindRangeInLoadingRangesArray(TestControlBlock[9]) == -1); + CHECK(GetNextEmptyIndexOfRangesInLoadingArray() == 0); + + } + + void TestInsertNewRange() { + +#pragma region the first insert has to insert to the singleRangeArray[0] + + CHECK(InsertNewRange(TestControlBlock[3]) == INSERT_TO_SINGLE_RANGES_ARRAY ); + CHECK(IsEqualRanges(prefetchSeqCollection_CB->singleRangesArray.array[0], TestControlBlock[3])); + printf("CHECK(InsertNewRange(TestControlBlock[3])== INSERT_TO_SINGLE_RANGES_ARRAY\n\n"); + + PrintSeqCollection(); +#pragma endregion + + +#pragma region the second insert + //the second insert + //has to insert to the seqRangeInfoArray[0] new sequence + // with the current and prev ranges and delete the prev insert from the singleRangeArray[0] + + CHECK(InsertNewRange(TestControlBlock[4]) == CREATE_SEQ ); + CHECK(IsEqualRanges(prefetchSeqCollection_CB->singleRangesArray.array[3], GetDefaultRange())); + CHECK(prefetchSeqCollection_CB->seqRangeInfoArray[0]->counter == 2); + printf("CHECK(InsertNewRange(TestControlBlock[4]) == CREATE_SEQ\n\n"); + + PrintSeqCollection(); + +#pragma endregion + + +#pragma region the third insert has to update the seqRangeinfoArray[0] + + CHECK(InsertNewRange(GetNextRangeByDirection(TestControlBlock[4], UP)) == CONTINUE_SEQ ); + CHECK(prefetchSeqCollection_CB->seqRangeInfoArray[0]->counter == 3); + CHECK(prefetchSeqCollection_CB->seqRangeInfoArray[0]->counterUse == 0); + CHECK(prefetchSeqCollection_CB->seqRangeInfoArray[1]->counter == -1); + CHECK(Prefetch_IsRangeInLoading(TestControlBlock[7])); + CHECK(FindRangeInLoadingRangesArray(TestControlBlock[7]) != -1); + + printf("InsertNewRange(TestControlBlock[7]) == CONTINUE_SEQ\n"); + + PrintSeqCollection(); +#pragma endregion + + +#pragma region the fourth insert has to insert to the singleRangeArray[0] + + CHECK(InsertNewRange(TestControlBlock[5]) == INSERT_TO_SINGLE_RANGES_ARRAY ); + CHECK(prefetchSeqCollection_CB->seqRangeInfoArray[0]->counter == 3); + CHECK(prefetchSeqCollection_CB->seqRangeInfoArray[0]->counterUse == 0);//stay 0 because seqRangeInfoArray wasn't changed + CHECK(IsEqualRanges(prefetchSeqCollection_CB->singleRangesArray.array[1], TestControlBlock[5]));//singleRangeCurrentIndex was up + + printf("InsertNewRange(TestControlBlock[4]) == INSERT_TO_SINGLE_RANGES_ARRAY\n\n"); + + PrintSeqCollection(); + +#pragma endregion + + +#pragma region the fiveth insert has to update the seqRangeinfoArray[0] + + + CHECK(InsertNewRange(GetNextRangeByDirection(GetNextRangeByDirection(TestControlBlock[4], UP), UP)) == CONTINUE_SEQ ); + CHECK(prefetchSeqCollection_CB->seqRangeInfoArray[0]->counter == 4); + CHECK(prefetchSeqCollection_CB->seqRangeInfoArray[0]->counterUse == 0); + CHECK(IsEqualRanges(prefetchSeqCollection_CB->singleRangesArray.array[0], GetDefaultRange())); + CHECK(Prefetch_IsRangeInLoading(TestControlBlock[9])); + CHECK(FindRangeInLoadingRangesArray(TestControlBlock[9]) != -1); + printf("InsertNewRange(GetNextRangeByDirection(GetNextRangeByDirection(TestControlBlock[3], UP, 1), UP, 1)) == CONTINUE_SEQ\n\n"); + + PrintSeqCollection(); +#pragma endregion + + +#pragma region the sixth insert + // has to insert to the seqRangeInfoArray[1] + // new sequence with the current and prev ranges (from singleRangeArray[1]) + // and delete the prev insert from the singleRangeArray[1] + + CHECK(InsertNewRange(TestControlBlock[3]) == CREATE_SEQ); + PrintSeqCollection(); + CHECK(IsEqualRanges(prefetchSeqCollection_CB->singleRangesArray.array[1], GetDefaultRange())); + CHECK(prefetchSeqCollection_CB->seqRangeInfoArray[1]->counter == 2); + CHECK(prefetchSeqCollection_CB->seqRangeInfoArray[1]->counterUse == 0); + CHECK(prefetchSeqCollection_CB->seqRangeInfoArray[0]->counterUse > 0); + printf("InsertNewRange(TestControlBlock[0]) == CREATE_SEQ\n\n"); + PrintSeqCollection(); +#pragma endregion + + +#pragma region the seventh insert has to update the seqRangeinfoArray[1] + CHECK(InsertNewRange(GetNextRangeByDirection(TestControlBlock[3], LEFT)) == CONTINUE_SEQ ); + //change the next expected range of TestControlBlock[3], to be valid value + TestControlBlock[8].topLeft.x = 0; + PrintSeqCollection(); + CHECK(Prefetch_IsRangeInLoading(TestControlBlock[8])); + CHECK(FindRangeInLoadingRangesArray(TestControlBlock[8]) != -1); + printf("InsertNewRange(GetNextRangeByDirection(TestControlBlock[3], LEFT, 1)== CONTINUE_SEQ\n\n"); + PrintSeqCollection(); +#pragma endregion + + } + + void TestInsertNewRangeRandom() { + + CHECK(InsertNewRange(TestControlBlock[10]) == INSERT_TO_SINGLE_RANGES_ARRAY); + CHECK(InsertNewRange(TestControlBlock[14]) == INSERT_TO_SINGLE_RANGES_ARRAY); + + CHECK(InsertNewRange(TestControlBlock[11]) == CREATE_SEQ); + CHECK(InsertNewRange(TestControlBlock[15]) == CREATE_SEQ); + + CHECK(InsertNewRange(TestControlBlock[12]) == CONTINUE_SEQ); + CHECK(InsertNewRange(TestControlBlock[16]) == CONTINUE_SEQ); + + CHECK(InsertNewRange(TestControlBlock[13]) == CONTINUE_SEQ); + CHECK(InsertNewRange(TestControlBlock[17]) == CONTINUE_SEQ); + + CHECK(InsertNewRange(TestControlBlock[18]) == INSERT_TO_SINGLE_RANGES_ARRAY); + CHECK(InsertNewRange(TestControlBlock[19]) == CREATE_SEQ); + CHECK(InsertNewRange(TestControlBlock[20]) == CONTINUE_SEQ); + CHECK(InsertNewRange(TestControlBlock[21]) == CONTINUE_SEQ); + + } + void TestOverrideSeqByCounterUse() { + //insert to seq in seqRangeInfoArray[1] + CHECK(InsertNewRange(prefetchSeqCollection_CB->seqRangeInfoArray[1]->nextExpectedRange) == CONTINUE_SEQ); + + CHECK(InsertNewRange(TestControlBlock[22]) == INSERT_TO_SINGLE_RANGES_ARRAY); + CHECK(InsertNewRange(TestControlBlock[23]) == CREATE_SEQ); + CHECK(InsertNewRange(TestControlBlock[24]) == CONTINUE_SEQ); + CHECK(InsertNewRange(TestControlBlock[25]) == CONTINUE_SEQ); + + //check if the next seq inserted to index 2 in seqRangeInfoArray + CHECK(prefetchSeqCollection_CB->seqRangeInfoArray[2]->counterUse == 0); + + PrintSeqCollection(); + } + + void TestValidationInput() + { + Range_t range; + range.bottomRight = TestControlBlock[0].bottomRight; + range.topLeft = TestControlBlock[1].topLeft; + + Prefetch_InsertNewRange(GetDefaultRange()); + Prefetch_InsertNewRange(range); + + } + + TEST_CASE("testing the IsRangeContainedInOtherRange function") { + InitTestControlBlock(); + TestIsRangeContainedInOtherRange(); + } + + TEST_CASE("testing the TestIsRangeCompleteSingleRangeToSequence function") { + TestIsRangeCompleteSingleRangeToSequence(); + } + + TEST_CASE("testing the TestGetNextRangeByDirection function") { + TestGetNextRangeByDirection(); + } + + TEST_CASE("testing the TestIsEqualRanges function") { + TestIsEqualRanges(); + } + + TEST_CASE("TestInsertNewRange") { + Prefetch_INIT(); + TestInsertNewRange(); + } + TEST_CASE("TestInsertNewRange") { + TestInsertNewRangeRandom(); + } + TEST_CASE("TestOverrideSeqByCounterUse") { + TestOverrideSeqByCounterUse(); + } + TEST_CASE("TestCheckValidation") { + TestValidationInput(); + } +} \ No newline at end of file