2011-10-11 08:44:27 -05:00
|
|
|
/**
|
|
|
|
|
* \file
|
|
|
|
|
* \brief Source code for the Cache class
|
|
|
|
|
* \author Copyright (c) 2011 Jonathan Thomas
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "../include/Cache.h"
|
|
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
using namespace openshot;
|
|
|
|
|
|
2012-10-10 15:21:33 -05:00
|
|
|
// Default constructor, no max frames
|
|
|
|
|
Cache::Cache() : max_frames(-1), current_frame(0) { };
|
2011-10-11 08:44:27 -05:00
|
|
|
|
|
|
|
|
// Constructor that sets the max frames to cache
|
2012-07-05 00:01:42 -05:00
|
|
|
Cache::Cache(int max_frames) : max_frames(max_frames), current_frame(0) { };
|
2011-10-11 08:44:27 -05:00
|
|
|
|
|
|
|
|
// Add a Frame to the cache
|
2012-08-15 17:27:14 -05:00
|
|
|
void Cache::Add(int frame_number, Frame *frame)
|
2011-10-11 08:44:27 -05:00
|
|
|
{
|
|
|
|
|
// Only add frame if it does not exist in the cache
|
|
|
|
|
if (!frames.count(frame_number))
|
|
|
|
|
{
|
|
|
|
|
// Add frame to queue and map
|
|
|
|
|
frames[frame_number] = frame;
|
2011-10-26 00:34:48 -05:00
|
|
|
frame_numbers.push_front(frame_number);
|
2011-10-11 08:44:27 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check for the existance of a frame in the cache
|
|
|
|
|
bool Cache::Exists(int frame_number)
|
|
|
|
|
{
|
|
|
|
|
// Is frame number cached
|
|
|
|
|
if (frames.count(frame_number))
|
|
|
|
|
return true;
|
|
|
|
|
else
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get a frame from the cache
|
2012-08-15 17:27:14 -05:00
|
|
|
Frame* Cache::GetFrame(int frame_number)
|
2011-10-11 08:44:27 -05:00
|
|
|
{
|
|
|
|
|
// Does frame exists in cache?
|
|
|
|
|
if (Exists(frame_number))
|
|
|
|
|
{
|
|
|
|
|
// return the Frame object
|
|
|
|
|
return frames[frame_number];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
// throw an exception for the missing frame
|
|
|
|
|
throw OutOfBoundsFrame("Frame not found in the cache", frame_number, -1);
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-26 00:34:48 -05:00
|
|
|
// Get the smallest frame number
|
2012-08-15 17:27:14 -05:00
|
|
|
Frame* Cache::GetSmallestFrame()
|
2011-10-24 08:22:21 -05:00
|
|
|
{
|
2011-10-26 00:34:48 -05:00
|
|
|
// Loop through frame numbers
|
|
|
|
|
deque<int>::iterator itr;
|
|
|
|
|
int smallest_frame = -1;
|
|
|
|
|
for(itr = frame_numbers.begin(); itr != frame_numbers.end(); ++itr)
|
|
|
|
|
{
|
|
|
|
|
if (*itr < smallest_frame || smallest_frame == -1)
|
|
|
|
|
smallest_frame = *itr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Return frame (or error if no frame found)
|
|
|
|
|
return GetFrame(smallest_frame);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Remove a specific frame
|
2012-08-15 17:27:14 -05:00
|
|
|
void Cache::Remove(int frame_number, bool delete_data)
|
2011-10-26 00:34:48 -05:00
|
|
|
{
|
|
|
|
|
// Get the frame (or throw exception)
|
2012-08-15 17:27:14 -05:00
|
|
|
Frame *f = GetFrame(frame_number);
|
2011-10-26 00:34:48 -05:00
|
|
|
|
|
|
|
|
// Loop through frame numbers
|
2012-07-05 00:01:42 -05:00
|
|
|
deque<int>::iterator itr;
|
|
|
|
|
for(itr = frame_numbers.begin(); itr != frame_numbers.end(); ++itr)
|
|
|
|
|
{
|
|
|
|
|
if (*itr == frame_number)
|
|
|
|
|
{
|
|
|
|
|
// erase frame number
|
|
|
|
|
frame_numbers.erase(itr);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-10-26 00:34:48 -05:00
|
|
|
|
2012-08-15 17:27:14 -05:00
|
|
|
// Deallocate frame (if requested)
|
|
|
|
|
if (delete_data)
|
|
|
|
|
delete frames[frame_number];
|
|
|
|
|
|
2012-07-05 00:01:42 -05:00
|
|
|
// Remove frame from map
|
|
|
|
|
frames.erase(frame_number);
|
2011-10-24 08:22:21 -05:00
|
|
|
}
|
|
|
|
|
|
2012-08-15 17:27:14 -05:00
|
|
|
// Remove a specific frame
|
|
|
|
|
void Cache::Remove(int frame_number)
|
|
|
|
|
{
|
|
|
|
|
// Remove and delete frame data
|
|
|
|
|
Remove(frame_number, true);
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-11 08:44:27 -05:00
|
|
|
// Clear the cache of all frames
|
|
|
|
|
void Cache::Clear()
|
|
|
|
|
{
|
2012-08-15 17:27:14 -05:00
|
|
|
deque<int>::iterator itr;
|
|
|
|
|
for(itr = frame_numbers.begin(); itr != frame_numbers.end(); ++itr)
|
|
|
|
|
{
|
|
|
|
|
// Deallocate frame
|
|
|
|
|
delete frames[*itr];
|
2011-10-11 08:44:27 -05:00
|
|
|
|
2012-08-15 17:27:14 -05:00
|
|
|
// Remove frame from map
|
|
|
|
|
frames.erase(*itr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// pop each of the frames from the queue... which empties the queue
|
2011-10-26 00:34:48 -05:00
|
|
|
while(!frame_numbers.empty()) frame_numbers.pop_back();
|
2011-10-11 08:44:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Count the frames in the queue
|
|
|
|
|
int Cache::Count()
|
|
|
|
|
{
|
|
|
|
|
// Return the number of frames in the cache
|
|
|
|
|
return frames.size();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Clean up cached frames that exceed the number in our max_frames variable
|
|
|
|
|
void Cache::CleanUp()
|
|
|
|
|
{
|
2012-10-10 15:21:33 -05:00
|
|
|
if (max_frames > 0)
|
|
|
|
|
{
|
|
|
|
|
// Count previous frames (relative to the current frame), and determine the smallest frame number
|
|
|
|
|
// Loop through frame numbers
|
|
|
|
|
deque<int>::iterator itr;
|
|
|
|
|
int previous_frames = 0;
|
|
|
|
|
int smallest_frame = -1;
|
|
|
|
|
for (itr = frame_numbers.begin(); itr != frame_numbers.end(); ++itr) {
|
|
|
|
|
if (*itr < current_frame)
|
|
|
|
|
previous_frames++;
|
2011-10-11 08:44:27 -05:00
|
|
|
|
2012-10-10 15:21:33 -05:00
|
|
|
if (*itr < smallest_frame || smallest_frame == -1)
|
|
|
|
|
smallest_frame = *itr;
|
|
|
|
|
}
|
2012-07-05 00:01:42 -05:00
|
|
|
|
2012-10-10 15:21:33 -05:00
|
|
|
// check against max size
|
|
|
|
|
if (previous_frames > max_frames) {
|
|
|
|
|
// Get the difference
|
|
|
|
|
int diff = previous_frames - max_frames;
|
|
|
|
|
int removed_count = 0;
|
2012-07-05 00:01:42 -05:00
|
|
|
|
2012-10-10 15:21:33 -05:00
|
|
|
// Loop through frames and remove the oldest
|
|
|
|
|
for (int x = smallest_frame; x < current_frame; x++) {
|
2012-07-05 00:01:42 -05:00
|
|
|
|
2012-10-10 15:21:33 -05:00
|
|
|
// Does frame exist?
|
|
|
|
|
if (Exists(x)) {
|
|
|
|
|
// Remove the frame, increment count
|
|
|
|
|
Remove(x);
|
|
|
|
|
removed_count++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Break after the correct # has been removed
|
|
|
|
|
if (removed_count == diff)
|
|
|
|
|
break;
|
2012-07-05 00:01:42 -05:00
|
|
|
}
|
|
|
|
|
}
|
2011-10-11 08:44:27 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-07-01 01:43:06 -05:00
|
|
|
|
|
|
|
|
// Display a list of cached frame numbers
|
|
|
|
|
void Cache::Display()
|
|
|
|
|
{
|
|
|
|
|
cout << "----- Cache List (" << frames.size() << ") ------" << endl;
|
|
|
|
|
deque<int>::iterator itr;
|
|
|
|
|
|
|
|
|
|
int i = 1;
|
|
|
|
|
for(itr = frame_numbers.begin(); itr != frame_numbers.end(); ++itr)
|
|
|
|
|
{
|
|
|
|
|
cout << " " << i << ") --- Frame " << *itr << endl;
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-11 08:44:27 -05:00
|
|
|
// Display the list of cache and clear the cache (mainly for debugging reasons)
|
|
|
|
|
void Cache::DisplayAndClear()
|
|
|
|
|
{
|
|
|
|
|
cout << "----- Cache List (" << frames.size() << ") ------" << endl;
|
|
|
|
|
int i = 1;
|
|
|
|
|
while(!frame_numbers.empty())
|
|
|
|
|
{
|
|
|
|
|
// Print the frame number
|
2011-10-26 00:34:48 -05:00
|
|
|
int frame_number = frame_numbers.back();
|
2011-10-11 08:44:27 -05:00
|
|
|
cout << " " << i << ") --- Frame " << frame_number << endl;
|
|
|
|
|
|
|
|
|
|
// Remove this frame
|
2011-10-26 00:34:48 -05:00
|
|
|
Remove(frame_number);
|
2011-10-11 08:44:27 -05:00
|
|
|
|
|
|
|
|
// increment counter
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|