// snf_saccades.hpp // Saccades engine adaptation for MessageSniffer // Copyright 2014 MicroNeil Research Corporation (www.microneil.com) // Licensed to ARM Research Labs for use in Message Sniffer. #ifndef _MN_SACCADES_ENGINE #define _MN_SACCADES_ENGINE #include #include using namespace std; class saccades_engine; class saccade { friend class saccades_engine; private: const static unsigned int stretchSize = 8; const static unsigned int stretchMark = stretchSize / 2; const static unsigned int stretchMask = ((~0UL) ^ (stretchSize - 1)); unsigned int stretchLeft(unsigned int s) { s = (stretchMark > s) ? s : (s - (stretchMark)); return (s & stretchMask); } unsigned int stretchRight(unsigned int f) { f = (start > f) ? start : f; return ((f + stretchSize + stretchMark) & stretchMask); } saccade() : start(0), finish(0) {} static saccade unstretched(unsigned int s, unsigned int f) { saccade u; u.start = s; u.finish = f; return u; } public: unsigned int start; unsigned int finish; saccade(unsigned int s, unsigned int f) : start(stretchLeft(s)), finish(stretchRight(f)) {} bool operator<(const saccade& r) const { if(start < r.start) return true; if(start > r.start) return false; return (finish < r.finish); } bool operator==(const saccade& r) const { return ( start == r.start && finish == r.finish ); } }; class saccade_marker { public: const saccade theSaccade; unsigned int theSlot; saccade_marker(saccade key, unsigned int slot) : theSaccade(key), theSlot(slot) {} bool operator<(const saccade_marker& r) const { return (theSaccade < r.theSaccade); } }; struct saccade_engram { static const int NoneMore = -1; int nextFresh; int nextStale; saccade theSaccade; saccade_engram() : nextFresh(NoneMore), nextStale(NoneMore), theSaccade(0,0) {} saccade_engram(saccade s) : nextFresh(NoneMore), nextStale(NoneMore), theSaccade(s) {} }; class saccades_engine { private: vector engrams; set markers; const unsigned int capacity; int mostFresh; int mostStale; void evoke(saccade s); void disconnectEngram(int theSlot); void connectFreshestEngram(int theSlot); void freshenEngram(int theSlot); void makeEngram(saccade s); void recycleEngram(saccade s); public: saccades_engine(unsigned int c) : capacity(c), mostFresh(saccade_engram::NoneMore), mostStale(saccade_engram::NoneMore) { engrams.reserve(capacity); } vector recall(); void learn(vector& experiences); }; #endif