-
-
Save autoletics/e8a7509b81a46bf5fefe to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
j.s.p.strategy.enabled=true | |
j.s.p.strategies=mp | |
j.s.p.strategy.mp.factory.class=com.jinspired.jxinsight.probes.strategy.multipass.StrategyFactory | |
j.s.p.strategy.mp.factory.classpath=/Users/wlouth/IdeaProjects/multipass-probes-strategy/classes/ | |
j.s.p.strategy.mp.environment.imports=label,file,write | |
j.s.p.strategy.mp.environment.import.label=!managed | |
j.s.p.strategy.mp.environment.import.label.type=string | |
j.s.p.strategy.mp.environment.import.file=multipass.config | |
j.s.p.strategy.mp.environment.import.file.type=string | |
j.s.p.strategy.mp.environment.import.write=true | |
j.s.p.strategy.mp.environment.import.write.type=boolean |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.jinspired.jxinsight.probes.strategy.multipass; | |
import org.jinspired.probes.Probes; | |
import org.jinspired.probes.strategy.ProbesStrategy; | |
import org.jinspired.probes.strategy.ProbesStrategyFactory; | |
import java.io.*; | |
import java.util.*; | |
import java.util.concurrent.ConcurrentHashMap; | |
import static java.text.MessageFormat.format; | |
import static org.jinspired.probes.Probes.label; | |
import static org.jinspired.probes.Probes.name; | |
import static org.jinspired.probes.Probes.parse; | |
/** | |
* Created by william@autoletics.com on 08/03/2015. | |
*/ | |
public final class StrategyFactory extends Thread | |
implements ProbesStrategyFactory { | |
static final Integer YES_INT = new Integer(1); | |
static final Integer NO_INT = new Integer(-1); | |
static final String YES_TAG = YES_INT.toString(); | |
static final String NO_TAG = NO_INT.toString(); | |
Options options; | |
static final ConcurrentHashMap<Probes.Name, Integer> global | |
= new ConcurrentHashMap<>(); | |
@Override | |
public void init(Probes.Environment env) { | |
final Options o = new Options( | |
label(env.getString(name("label"))), // the matching label | |
env.getString(name("file")), // the voting file | |
env.getBoolean(name("write"))); // write voting file | |
final File f = new File(o.file); | |
// check whether the file is present | |
// it might not be if this is a first | |
// run of the playback with strategy | |
if(f.exists()) { | |
// we use a properties file for persistence | |
// of votes to allow use inspection & edit | |
final Properties p = new Properties(); | |
try { | |
final ConcurrentHashMap<Probes.Name, Integer> m = global; | |
p.load(new FileInputStream(o.file)); | |
// iterate over probe names loaded from file | |
final Iterator<Map.Entry<Object,Object>> it | |
= p.entrySet().iterator(); | |
while(it.hasNext()) { | |
final Map.Entry e = it.next(); | |
// place past result in map | |
m.put( | |
parse(e.getKey().toString()), | |
e.getValue().equals(YES_TAG) ? YES_INT : NO_INT); | |
} | |
} catch(IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
options = o; | |
// has (re)writing been enabled | |
if(o.write) { | |
// register a thread shutdown hook | |
// which when called writes out the | |
// name=vote to a properties file | |
Runtime.getRuntime().addShutdownHook(this); | |
} | |
} | |
@Override | |
public void run() { | |
// iterate through map writing out | |
// name=vote based on label match | |
final Iterator<Map.Entry<Probes.Name,Integer>> it | |
= global.entrySet().iterator(); | |
final Properties p = new Properties(); | |
while(it.hasNext()) { | |
final Map.Entry<Probes.Name, Integer> e | |
= it.next(); | |
final Probes.Name n = e.getKey(); | |
p.setProperty( | |
n.toString(), | |
e.getValue() == YES_INT && n.contains(options.label) ? YES_TAG : NO_TAG); | |
} | |
try { | |
final Options o = options; | |
// write contents of properties | |
// table to the filesystem | |
p.store(new FileOutputStream(o.file), | |
format("label={0}, file={1}, write={2}", | |
o.label, | |
o.file, | |
o.write)); | |
} catch(IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
/** | |
* Returns an implementation of a strategy used in deciding whether a probe (method) is metered | |
* | |
* @param ctx the thread context | |
* @return the strategy used for probe metering voting purposes | |
*/ | |
@Override | |
public ProbesStrategy create(Probes.Context ctx) { | |
return new Strategy(options); | |
} | |
/** | |
* A thread specific (i.e threadsafe) strategy implementation class that | |
* stores past recollections within a properties file for retreival | |
* across multi passes through the same simulated playback (memory recall) | |
*/ | |
static final class Strategy implements ProbesStrategy { | |
final Options options; | |
final IdentityHashMap<Probes.Name, Integer> local = new IdentityHashMap(); | |
Strategy( Options options ) {this.options = options;} | |
@Override | |
public int vote(Probes.Probe p) { | |
final Probes.Name n = p.getName(); | |
Integer v; | |
// check whether the thread has | |
// seen this probe name before | |
if((v = local.get(n)) == null) { | |
// check whether the probe name | |
// is mapped globally already | |
if((v = global.get(n)) == null) { | |
// start off with a YES vote | |
// though must recheck at | |
// end of run in case the | |
// probe name was disabled | |
global.putIfAbsent(n, v = YES_INT); | |
} | |
// put the result into the | |
// local name->vote map | |
local.put(n, v); | |
} | |
return v; | |
} | |
} | |
/** | |
* A class holding strategy configuration | |
*/ | |
static final class Options { | |
final Probes.Label label; | |
final String file; | |
final boolean write; | |
Options(Probes.Label label, | |
String file, | |
boolean write) { | |
this.file = file; | |
this.label = label; | |
this.write = write; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment