33
33
// Default constructor, no max bytes
34
34
CacheMemory::CacheMemory() : CacheBase(0) {
35
// Set cache type name
36
cache_type = "CacheMemory";
38
needs_range_processing = false;
38
41
// Constructor that sets the max bytes to cache
39
CacheMemory::CacheMemory(int64 max_bytes) : CacheBase(max_bytes) {
42
CacheMemory::CacheMemory(long long int max_bytes) : CacheBase(max_bytes) {
43
// Set cache type name
44
cache_type = "CacheMemory";
46
needs_range_processing = false;
43
49
// Default destructor
47
53
frame_numbers.clear();
54
ordered_frame_numbers.clear();
49
56
// remove critical section
50
57
delete cacheCriticalSection;
51
58
cacheCriticalSection = NULL;
62
// Calculate ranges of frames
63
void CacheMemory::CalculateRanges() {
64
// Only calculate when something has changed
65
if (needs_range_processing) {
67
// Create a scoped lock, to protect the cache from multiple threads
68
const GenericScopedLock<CriticalSection> lock(*cacheCriticalSection);
70
// Sort ordered frame #s, and calculate JSON ranges
71
std::sort(ordered_frame_numbers.begin(), ordered_frame_numbers.end());
73
// Clear existing JSON variable
75
ranges = Json::Value(Json::arrayValue);
77
// Increment range version
80
vector<long int>::iterator itr_ordered;
81
long int starting_frame = *ordered_frame_numbers.begin();
82
long int ending_frame = *ordered_frame_numbers.begin();
84
// Loop through all known frames (in sequential order)
85
for (itr_ordered = ordered_frame_numbers.begin(); itr_ordered != ordered_frame_numbers.end(); ++itr_ordered) {
86
long int frame_number = *itr_ordered;
87
if (frame_number - ending_frame > 1) {
88
// End of range detected
91
// Add JSON object with start/end attributes
92
// Use strings, since long ints are supported in JSON
93
stringstream start_str;
94
start_str << starting_frame;
96
end_str << ending_frame;
97
range["start"] = start_str.str();
98
range["end"] = end_str.str();
101
// Set new starting range
102
starting_frame = frame_number;
105
// Set current frame as end of range, and keep looping
106
ending_frame = frame_number;
109
// APPEND FINAL VALUE
112
// Add JSON object with start/end attributes
113
// Use strings, since long ints are supported in JSON
114
stringstream start_str;
115
start_str << starting_frame;
116
stringstream end_str;
117
end_str << ending_frame;
118
range["start"] = start_str.str();
119
range["end"] = end_str.str();
120
ranges.append(range);
122
// Reset needs_range_processing
123
needs_range_processing = false;
54
127
// Add a Frame to the cache
55
128
void CacheMemory::Add(tr1::shared_ptr<Frame> frame)
115
190
// Gets the maximum bytes value
116
int64 CacheMemory::GetBytes()
191
long long int CacheMemory::GetBytes()
118
193
// Create a scoped lock, to protect the cache from multiple threads
119
194
const GenericScopedLock<CriticalSection> lock(*cacheCriticalSection);
121
int64 total_bytes = 0;
196
long long int total_bytes = 0;
123
198
// Loop through frames, and calculate total bytes
124
199
deque<long int>::reverse_iterator itr;
133
208
// Remove a specific frame
134
209
void CacheMemory::Remove(long int frame_number)
211
Remove(frame_number, frame_number);
214
// Remove range of frames
215
void CacheMemory::Remove(long int start_frame_number, long int end_frame_number)
136
217
// Create a scoped lock, to protect the cache from multiple threads
137
218
const GenericScopedLock<CriticalSection> lock(*cacheCriticalSection);
139
220
// Loop through frame numbers
140
deque<long int>::iterator itr;
141
for(itr = frame_numbers.begin(); itr != frame_numbers.end(); ++itr)
143
if (*itr == frame_number)
145
// erase frame number
146
frame_numbers.erase(itr);
151
// Remove frame from map. If frame_number doesn't exist, frames.erase returns zero.
152
frames.erase(frame_number);
221
deque<long int>::iterator itr = frame_numbers.begin();
222
while (itr != frame_numbers.end())
224
if (*itr >= start_frame_number && *itr <= end_frame_number)
226
// erase frame number
227
itr = frame_numbers.erase(itr++);
232
// Loop through ordered frame numbers
233
vector<long int>::iterator itr_ordered = ordered_frame_numbers.begin();
234
while (itr_ordered != ordered_frame_numbers.end())
236
if (*itr_ordered >= start_frame_number && *itr_ordered <= end_frame_number)
238
// erase frame number
239
frames.erase(*itr_ordered);
240
itr_ordered = ordered_frame_numbers.erase(itr_ordered++);
245
// Needs range processing (since cache has changed)
246
needs_range_processing = true;
155
249
// Move frame to front of queue (so it lasts longer)
161
255
// Does frame exists in cache?
162
256
/* FIXME if the frame number isn't present, the loop will do nothing, so why protect it?
163
257
* Is it to save time by avoiding a loop?
164
* Do we really need to optmize the case where we've been given a nonexisting frame_number? */
258
* Do we really need to optimize the case where we've been given a nonexisting frame_number? */
165
259
if (frames.count(frame_number))
167
261
// Loop through frame numbers
320
// Generate JSON string of this object
321
string CacheMemory::Json() {
323
// Return formatted string
324
return JsonValue().toStyledString();
327
// Generate Json::JsonValue for this object
328
Json::Value CacheMemory::JsonValue() {
330
// Proccess range data (if anything has changed)
333
// Create root json object
334
Json::Value root = CacheBase::JsonValue(); // get parent properties
335
root["type"] = cache_type;
336
root["ranges"] = ranges;
339
stringstream range_version_str;
340
range_version_str << range_version;
341
root["version"] = range_version_str.str();
347
// Load JSON string into this object
348
void CacheMemory::SetJson(string value) throw(InvalidJSON) {
350
// Parse JSON string into JSON objects
353
bool success = reader.parse( value, root );
356
throw InvalidJSON("JSON could not be parsed (or is invalid)", "");
360
// Set all values that match
365
// Error parsing JSON (or missing keys)
366
throw InvalidJSON("JSON is invalid (missing keys or invalid data types)", "");
370
// Load Json::JsonValue into this object
371
void CacheMemory::SetJsonValue(Json::Value root) throw(InvalidFile, ReaderClosed) {
373
// Close timeline before we do anything (this also removes all open and closing clips)
377
CacheBase::SetJsonValue(root);
379
if (!root["type"].isNull())
380
cache_type = root["type"].asString();
b'\\ No newline at end of file'