// snf_saccades.cpp // Saccades engine adaptation for MessageSniffer // Copyright 2014 MicroNeil Research Corporation (www.microneil.com) // Licensed to ARM Research Labs for use in Message Sniffer. #include #include #include "snf_saccades.hpp" bool doesOverlap(unsigned int workingStart, unsigned int testStart, unsigned int workingFinish) { return( testStart >= workingStart && testStart <= workingFinish ); } std::vector saccades_engine::recall() { std::vector recollection; int markersSize = markers.size(); if(0 < markersSize) { std::set::iterator i; recollection.reserve(markers.size()); bool isFirstPass = true; unsigned int workingStart = 0; unsigned int workingFinish = 0; for(i = markers.begin(); i != markers.end(); i++) { const saccade& theSaccade = (*i).theSaccade; if(isFirstPass) { workingStart = theSaccade.start; workingFinish = theSaccade.finish; isFirstPass = false; } else { if(doesOverlap(workingStart, theSaccade.start, workingFinish)) { workingFinish = theSaccade.finish; } else { recollection.push_back(saccade::unstretched(workingStart, workingFinish)); workingStart = theSaccade.start; workingFinish = theSaccade.finish; } } } recollection.push_back(saccade::unstretched(workingStart, workingFinish)); } return recollection; } void saccades_engine::disconnectEngram(int theSlot) { saccade_engram& current = engrams.at(theSlot); saccade_engram& above = engrams.at(current.nextFresh); above.nextStale = current.nextStale; if(mostStale == theSlot) { mostStale = current.nextFresh; } else { saccade_engram& below = engrams.at(current.nextStale); below.nextFresh = current.nextFresh; } current.nextFresh = saccade_engram::NoneMore; current.nextStale = saccade_engram::NoneMore; } void saccades_engine::connectFreshestEngram(int theSlot) { engrams.at(theSlot).nextStale = mostFresh; if(mostFresh != saccade_engram::NoneMore) { engrams.at(mostFresh).nextFresh = theSlot; } mostFresh = theSlot; if(mostStale == saccade_engram::NoneMore) { mostStale = theSlot; } } void saccades_engine::freshenEngram(int theSlot) { if(mostFresh == theSlot) return; disconnectEngram(theSlot); connectFreshestEngram(theSlot); } void saccades_engine::makeEngram(saccade s) { int newSlot = engrams.size(); engrams.push_back(saccade_engram(s)); connectFreshestEngram(newSlot); markers.insert(saccade_marker(s, newSlot)); } void saccades_engine::recycleEngram(saccade s) { int recycleSlot = mostStale; saccade_marker dropMarker(engrams.at(recycleSlot).theSaccade, recycleSlot); markers.erase(dropMarker); engrams.at(recycleSlot).theSaccade = s; saccade_marker insertMarker(s, recycleSlot); markers.insert(insertMarker); freshenEngram(recycleSlot); } void saccades_engine::evoke(saccade s) { bool stillGrowing = (capacity > engrams.size()); std::set::iterator i; saccade_marker testMarker(s,0); i = markers.find(testMarker); bool isRemembered = (i != markers.end()); if(isRemembered) { freshenEngram((*i).theSlot); } else { if(stillGrowing) { makeEngram(s); } else { recycleEngram(s); } } } void saccades_engine::learn(std::vector& experiences) { for(unsigned int i = 0; i < experiences.size(); i++) { evoke(experiences[i]); } }