Browse Source

Added missing snf_saccades files from previous commit.


git-svn-id: https://svn.microneil.com/svn/SNFMulti/trunk@54 dc71a809-1921-45c4-985c-09c81d0142d9
wx
madscientist 11 years ago
parent
commit
2c96f26dd9
2 changed files with 248 additions and 0 deletions
  1. 125
    0
      snf_saccades.cpp
  2. 123
    0
      snf_saccades.hpp

+ 125
- 0
snf_saccades.cpp View File

@@ -0,0 +1,125 @@
// 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 <set>
#include <vector>
#include "snf_saccades.hpp"
using namespace std;
bool doesOverlap(unsigned int workingStart, unsigned int testStart, unsigned int workingFinish) {
return(
testStart >= workingStart &&
testStart <= workingFinish
);
}
vector<saccade> saccades_engine::recall() {
vector<saccade> recollection;
int markersSize = markers.size();
if(0 < markersSize) {
set<saccade_marker>::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());
set<saccade_marker>::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(vector<saccade>& experiences) {
for(unsigned int i = 0; i < experiences.size(); i++) {
evoke(experiences[i]);
}
}

+ 123
- 0
snf_saccades.hpp View File

@@ -0,0 +1,123 @@
// 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 <set>
#include <vector>
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<saccade_engram> engrams;
set<saccade_marker> 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<saccade> recall();
void learn(vector<saccade>& experiences);
};
#endif

Loading…
Cancel
Save