DBHOST="farm6.csail.mit.edu"
WEBHOSTS=["farm5.csail.mit.edu",
          #"farm6.csail.mit.edu",
          "farm7.csail.mit.edu",
          "farm8.csail.mit.edu",
          "farm9.csail.mit.edu",
          "farm10.csail.mit.edu",
          "farm11.csail.mit.edu",
#          "farm12.csail.mit.edu",
#          "farm13.csail.mit.edu",
          "farm14.csail.mit.edu"
          ]
DBUSER="cecchet"
DBNAME="rubis"
SRCPATH="/u/drkp/txcache-deploy/src"
RUBISPATH=SRCPATH+"/RUBiS-1.4.3"
PINCUSHIONPATH=SRCPATH+"/pincushion/pincushion"
INVALDPATH=SRCPATH+"/invald/invald"
SERVERPATH=SRCPATH+"/server/server"
SUMLATENCIESPATH=SRCPATH+"/support/sumlatencies"
SERVERSTATSPATH=SRCPATH+"/support/serverstats"
JAVAPATH="/usr/lib/jvm/java-6-sun"
LOCALPHPPATH="/u/drkp/txcache-deploy-local/"
SNAPSHOTARCHIVE="/u/drkp/txcache-deploy-local/snapshots/"
DBARCHIVE="/data/drkp/rubis-pgdumps/"

MEMSIZE=2097152
REMOTECLIENTHOSTS=["farm2.csail.mit.edu",
                   "farm3.csail.mit.edu",
                   "farm4.csail.mit.edu"]
NUMCLIENTS = [500, 1000]
#              1250, 1500, 1750, 2000, 2250, 2500, 2750,
#              3000, 3250, 3500, 3750,
#    4000, 4250, 4500, 4750, 5000, 5250, 5500,
# 5750, 6000, 6250, 6500, 6750, 7000, 7250, 7500]
STDWARMUP=[]
#CACHEHOSTS=[("rhythmicon.csail.mit.edu", 16001)]
CACHEHOSTS=[("farm12.csail.mit.edu", 16001),
            ("farm13.csail.mit.edu", 16001)]
#CACHEHOSTS=[(x, 16001) for x in WEBHOSTS]
PINCUSHIONHOST=(CACHEHOSTS[0][0], 16000)
INVALDHOST=CACHEHOSTS[0][0]
STDPINPOLICY="latest bounded pin with variety (5 secs)"
STDFRESHNESS=30.0

import sys, os, re, time, glob, subprocess

os.putenv("JAVA_HOME", JAVAPATH)

def startDB(db):
        os.system("ssh -t -A %s %s/start-db %s" % (DBHOST, RUBISPATH, db))

def reloadDB(db, snapshot):
    os.system("ssh -t -A %s %s/reload-db %s %s" % (DBHOST,
                                                   RUBISPATH,
                                                   db,
                                                   snapshot))
    
def stopDB(config):
    if config.dumpCache:
        os.system("ssh %s php %s/PHP/UpdateVirtualTimeBase.php" % (DBHOST, RUBISPATH))
        os.system("ssh %s pg_dump -U %s -h localhost %s -f %s/rubis-pgdump-%s" % (DBHOST, DBUSER, DBNAME, DBARCHIVE, config.dumpCache))
    os.system("ssh -A %s %s/stop-db %s" % (DBHOST, RUBISPATH, config.pgsql))

def vacuum():
    os.system("vacuumdb -zf -h %s -U %s %s" % (DBHOST, DBUSER, DBNAME))
#    os.system("echo REINDEX DATABASE %s | psql -h %s -U %s %s" %
#              (DBNAME, DBHOST, DBUSER, DBNAME))
#    os.system("echo CLUSTER | psql -h %s -U %s %s" %
#              (DBHOST, DBUSER, DBNAME))
#    os.system("echo ANALYZE | psql -h %s -U %s %s" %
#              (DBHOST, DBUSER, DBNAME))

def primeDBCache():
    os.system("psql -h %s -U %s %s < %s/database/seqscan_all.sql" %
              (DBHOST, DBUSER, DBNAME, RUBISPATH))

def flushCache():
#    for x in set([y[0] for y in CACHEHOSTS] + WEBHOSTS + [DBHOST]):
    # just do the DBHOST -- buffer caches shouldn't matter on the other nodes
    for x in set([DBHOST]):
        os.system("ssh %s sudo sync" % (x))
        os.system("ssh %s sudo %s/bench-scripts/drop_caches" % (x, RUBISPATH))

def startCache(config):
    print "Starting cache"
    os.system("rm ~/pincushion.log ~/invald.log ~/server.*.log")
    os.system("ssh %s 'ulimit -c unlimited ; %s -h %s -u %s -d %s -s %d'>> ~/pincushion.log 2>&1 &" %
              (PINCUSHIONHOST[0], PINCUSHIONPATH,
               DBHOST, DBUSER, DBNAME,
               (config.freshnessReq + 15)))
    restoreArg = ""
    for host,port in CACHEHOSTS:
        if config.restoreSnapshot:
            snapshotFile =  "%s/store-%s-%s-%s" % (SNAPSHOTARCHIVE,
                                                   host, port,
                                                   config.restoreSnapshot)
            cacheSize = config.cacheSize
#            if host == "farm10.csail.mit.edu":
#                    cacheSize="2138M"
            if os.path.isfile("/nfs/" + host + snapshotFile):
                restoreArg = " -l " + snapshotFile
            else:
                if restoreArg != "":
                    # We found a snapshot for some other cache server...
                    raise Exception("Found cache snapshot for some but not all cache servers: couldn't find %s" % snapshotFile)
            os.system("ssh %s 'ulimit -c unlimited ; %s -p %d -s %s -t %s %s'>> ~/server.%s.%d.log 2>&1 &" %
                  (host, SERVERPATH, port, config.cacheSize,
                   (config.freshnessReq + 15),
                   restoreArg,
                   host, port))

    # Generate nodes.txt
    nodesTxt = file(os.path.join(RUBISPATH,
                                 "PHP", "nodes.txt"), "w")
    nodesTxt.write(config.pinPolicy + "\n")
    nodesTxt.write("%s:%d\n" % (PINCUSHIONHOST[0], PINCUSHIONHOST[1]))
    for host, port in CACHEHOSTS:
        nodesTxt.write("%s:%d\n" % (host, port))
    nodesTxt.close()

    # Start invald
    time.sleep(15)
    os.system("ssh %s 'ulimit -c unlimited ; %s -h %s -u %s -d %s -n %s'>> ~/invald.log 2>&1 &" %
              (INVALDHOST, INVALDPATH,
               DBHOST, DBUSER, DBNAME,
               os.path.join(RUBISPATH, "PHP", "nodes.txt")))
    
def stopCache(config):
    if (config.dumpCache):
        print "Dumping and stopping cache"
        for host, port in CACHEHOSTS:
            os.system("ssh %s killall -QUIT server" % host)
        time.sleep(1)        
        for host, port in CACHEHOSTS:
            os.system("ssh %s mv /tmp/store.dump %s/store-%s-%s-%s" %
                      (host, SNAPSHOTARCHIVE, host, port,
                       config.dumpCache))
    else:
        print "Stopping cache"
        for host, port in CACHEHOSTS:
            os.system("ssh %s killall -INT server" % host)
    os.system("ssh %s killall pincushion" % PINCUSHIONHOST[0])
    os.system("ssh %s killall invald" % INVALDHOST)
    
def makeConfigPHP(config):
    # Figure out the virtual time base
    vbase = int(subprocess.Popen(["ssh", DBHOST, "php",
                                  os.path.join(RUBISPATH, "PHP",
                                               "GetVirtualTimeBase.php")],
                                 stdout=subprocess.PIPE).communicate()[0])
    print "Virtual time base is", vbase
    rbase = time.time()
    print "Real time base is", rbase
        
        
    # Generate txcache-config.php
    configPHP = file(os.path.join(RUBISPATH,
                                  "PHP", "txcache-config.php"), "w")
    configPHP.write("<?php\n")
    configPHP.write("""define('DBCONNSTRING', "user=%s dbname=%s host=%s");\n""" %
                    (DBUSER, DBNAME, DBHOST))
    configPHP.write("define('TXCACHE', true);\n")
    configPHP.write("define('MICROCACHE', %s);\n" %
                    (str(config.microCache)))
    configPHP.write("define('TXCACHEBYPASS', %d);\n" %
                    (config.txcachebypassArg))
    configPHP.write("define('TXCACHEINVALIDATIONS', %s);\n" %
                    "false")
                    #(str(config.useCache)))
    configPHP.write("define('FRESHNESS', %f);\n" %
                       (config.freshnessReq))
    if (config.randomizeFreshness is None):
        configPHP.write("define('RANDOMIZE_FRESHNESS', false);\n")
    else:
        configPHP.write("define('RANDOMIZE_FRESHNESS', true);\n")
        configPHP.write("define('RANDOMIZE_FRESHNESS_FACTOR', %f);" % config.randomizeFreshness)
    configPHP.write("define('VIRTUALIZE_TIME', true);\n")
    configPHP.write("define('VIRTUAL_TIME_BASE', %d);\n" % vbase)
    configPHP.write("define('REAL_TIME_BASE', %d);\n" % rbase)
    
    configPHP.write("?>");
    configPHP.close()

def startApache(config):
    for host in WEBHOSTS:
        # Set up apache config
        os.system("ssh -t %s sudo ln -s -f %s/apache-rubis-farm /etc/apache2/sites-enabled/001-rubis" %
                  (host, RUBISPATH))
        # Install PHP module
        os.system("ssh -t %s sudo make -C %s phpclient-install" %
                  (host, SRCPATH))
        # Make local copy of PHP source directory        
        os.system("ssh -t %s rm -rf %s %s" % (host,
                                              os.path.join(LOCALPHPPATH, "PHP"),
                                              os.path.join(LOCALPHPPATH, "fcgi-wrapper")))
        os.system("ssh -t %s cp -r %s %s %s" % (host,
                                                os.path.join(RUBISPATH, "PHP"),
                                                os.path.join(RUBISPATH, "fcgi-wrapper"),                                                
                                                LOCALPHPPATH))
        # Start Apache
        os.system("ssh -t %s sudo /etc/init.d/apache2 start" % (host))

def stopApache():
    for host in WEBHOSTS:
        os.system("ssh -t %s sudo /etc/init.d/apache2 stop" % (host))
        os.system("ssh -t %s sudo killall php5-cgi" % (host))
    
def runBench(config, numClients, args=""):
    # Setup
    os.putenv("NUM_CLIENTS", str(numClients / (len(REMOTECLIENTHOSTS)+1)))
    os.putenv("REMOTE_CLIENTS", ",".join(REMOTECLIENTHOSTS))
    os.putenv("HTTPD_HOSTNAMES", ",".join([x+":4312" for x in WEBHOSTS]))
    os.system("%s/make-properties %s" % (RUBISPATH, args))
    if config.reloadDBEachTime:
        config.setup()
    for host in WEBHOSTS:
        os.system("ssh -t %s sudo find /tmp/clog /tmp/stats /tmp/phptimes -delete" % (host))
    if config.useCache:
        for host, port in CACHEHOSTS:
            os.system("%s -c %s:%d" % (SERVERSTATSPATH, host, port))

    # I don't think we need to vacuum if we reload the DB each time,
    # but I could be wrong...
    # XXX but we do need to analyze, right?
    if (not config.reloadDBEachTime) and config.vacuum:
        vacuum()
        
    startApache(config)

    # Run
    os.system("make emulator")

    # Find bench directory and create info directory
    benchDir = findLatestBench()
    os.system("mkdir %s/bench/%s/info" % (RUBISPATH,
                                          benchDir))

    
    # Get apache server-status before we stop it
    for host in WEBHOSTS:
        os.system("curl -o %s/bench/%s/info/apache-status-%s http://%s/server-status" %
                  (RUBISPATH, benchDir, host, host))
    
    # Cleanup
    stopApache()
    # keep cache servers running for now so we can collect stats
    
    # Get results & configuration
    os.system("svn status -qv %s > %s/bench/%s/info/svnstatus" %
              (SRCPATH, RUBISPATH, benchDir))
    os.system("svn diff %s > %s/bench/%s/info/svndiff" %
              (SRCPATH, RUBISPATH, benchDir))
    for host in WEBHOSTS:
        os.system("scp %s:/etc/apache2/apache2.conf %s/bench/%s/info/apache2.conf-%s" %
                  (host, RUBISPATH, benchDir, host))
    # Postgres won't start unless the data dir is 700, but then we
    # can't read postgresql.conf. This is stupid, so treat accordingly.
    os.system("ssh %s sudo chmod 755 %s/data" % (DBHOST, config.pgsql))
    os.system("scp %s:%s/data/postgresql.conf %s/bench/%s/info/" %
              (DBHOST, config.pgsql, RUBISPATH, benchDir))
    os.system("ssh %s sudo chmod 700 %s/data" % (DBHOST, config.pgsql))
    os.system("scp %s:%s/pgsql.log %s/bench/%s/info/" %
              (DBHOST, config.pgsql, RUBISPATH, benchDir))
    # Get (less interesting) latencies & logs even if cache isn't running
    for host in WEBHOSTS:
        os.system("rsync -a %s:/tmp/clog/ %s/bench/%s/info/clog-%s" %
                  (host, RUBISPATH, benchDir, host))
        os.system("rsync -a %s:/tmp/stats/ %s/bench/%s/info/stats-%s" %
                  (host, RUBISPATH, benchDir, host))
        os.system("scp %s:/tmp/phptimes %s/bench/%s/info/phptimes-%s" %
                  (host, RUBISPATH, benchDir, host))
        os.system("%s %s/bench/%s/info/stats-*/* > %s/bench/%s/info/latency.txt 2>&1" %
                  (SUMLATENCIESPATH, RUBISPATH, benchDir,
                   RUBISPATH, benchDir))
    if config.useCache:
         if config.debugDump:
             print "Generating debug dumps"    
             for host, port in CACHEHOSTS:
                 os.system("ssh %s 'rm -f /tmp/store.debugdump /tmp/store.debugdump.bz2 ; killall -PWR server'" % host)
             time.sleep(30)
                 
         os.system("cp ~/server*.log ~/pincushion.log ~/invald.log %s/bench/%s/info/" %
                  (RUBISPATH, benchDir))
         for host, port in CACHEHOSTS:
            os.system("%s %s:%d > %s/bench/%s/info/cachestats.%s.%d" %
                      (SERVERSTATSPATH, host, port,
                       RUBISPATH, benchDir, host, port))
         if config.debugDump:
             procs = [subprocess.Popen("ssh %s bzip2 /tmp/store.debugdump" % host, shell=True) for host, port in CACHEHOSTS]
             for x in procs:
                     os.waitpid(x.pid, 0)                     
             procs = [subprocess.Popen("scp %s:/tmp/store.debugdump.bz2 %s/bench/%s/info/store.debugdump.%s.%d.bz2" % (host, RUBISPATH, benchDir, host, port), shell=True) for host, port in CACHEHOSTS]
             for x in procs:
                     os.waitpid(x.pid, 0)                     
             for host, port in CACHEHOSTS:
                 os.system("ssh %s rm /tmp/store.debugdump.bz2" % host)
            

    if config.reloadDBEachTime:
        config.stop()

    return BenchResult(findLatestBench())

def findLatestBench():
    dirs = os.listdir(os.path.join(RUBISPATH, "bench"))
    times = [(os.stat(os.path.join(RUBISPATH, "bench", x)).st_mtime,
              x)
             for x in dirs]
    return max(times)[1]

class BenchResult:
    def __init__(self, name):
        self.name = name
        indexFile = file(os.path.join(RUBISPATH, "bench",
                                      name, "index.html")).readlines()
        perfFile = file(os.path.join(RUBISPATH, "bench",
                                      name, "perf.html")).readlines()
        for line in indexFile:
            if line.startswith("Total number of clients for this experiment"):
                self.numClients = int(line.split(":")[1].split("<br>")[0])

        runtimeStatsLine = [x for x in perfFile
                            if "Average throughput" in x][1]
        self.avgLatency = int(re.search("<B>([0-9]*) ms</B>",
                                        runtimeStatsLine).groups()[0])
        self.avgThroughput = int(re.search("<B>([0-9]*) req/s</B>",
                                           runtimeStatsLine).groups()[0])

        # Read clogs
        clogs = glob.glob(os.path.join(RUBISPATH, "bench", name,
                                       "info", "clog-*", "*"))
        self.statlines = []
        for x in clogs:
            f = file(x)
            lines = f.readlines()
            sl = [x for x in lines if "STATLINE" in x]
            if len(sl) == 0:
                continue
            self.statlines.append(sl[-1])

        statlinesSplit = [x.split("STATLINE ")[1].split(" ")
                               for x in self.statlines]
        if len(statlinesSplit) > 0:
            self.statlineSummary = [sum(int(x[i]) for x in statlinesSplit)
                                    for i in range(len(statlinesSplit[0]))]
        else:
            self.statlineSummary = []

    def __str__(self):
        return "%s: %d clients, %d ms, %d req/s STATLINE %s" % (self.name,
                                                                self.numClients,
                                                                self.avgLatency,
                                                                self.avgThroughput,
                                                                " ".join([str(x) for x in self.statlineSummary]))


def runSeries(config, numClients):
    results = []
    for n in numClients:
        results.append(runBench(config, n, config.makePropertiesArgs))
    return results

def runSeriesRepeated(config, numClients, n):
    return runSeries(config, [numClients]*n)

def runSeriesDynamic(config, maxRuns, startClients, increment, afterPeak):
    results = []
    n = startClients
    stopAfterPeak = afterPeak

    while True:
        lastResult = runBench(config, n, config.makePropertiesArgs)
        results.append(lastResult)

        print "Run ", len(results)
        print "n =", n, "(linear throughput would be:", 0.165*n, ")"
        print "Last throughput:", lastResult.avgThroughput
        if len(results) >= maxRuns:
            print "Stopping -- reached maxRuns:", maxRuns
            return results
        if len(results) >= stopAfterPeak:
            print "Stopping -- reached stopAfterPeak:", stopAfterPeak
            return results

        print "Last latency:", lastResult.avgLatency

        maxThroughput = max([x.avgThroughput for x in results])
        print "Max throughput:", maxThroughput
        if lastResult.avgLatency >= 2000:
            print "Latency too high. Will stop at", stopAfterPeak
        elif lastResult.avgThroughput == maxThroughput:
            stopAfterPeak = len(results) + afterPeak
            print "Still at peak -- resetting stopAfterPeak to", stopAfterPeak
        else:
            print "Past peak. Will stop at", stopAfterPeak
            
        n += increment

def runSeriesFindPeak(config, startClients, increment, tolerance):
    results = []
    n = startClients
    peakThroughput = 0
    lastThroughput = 0
    leftBound = 0
    rightBound = 0
    cache = {}
    
    # Find peak with a coarse scan
    while lastThroughput == peakThroughput:
        print "In fast/coarse scan. Running", n
        lastResult = runBench(config, n, config.makePropertiesArgs)
        results.append(lastResult)
        lastThroughput = lastResult.avgThroughput
        cache[n] = lastThroughput
        print "In fast/coarse scan. Run", len(results)
        print "n =", n, "(linear throughput would be:", 0.165*n, ")"
        print "Last throughput:", lastThroughput
        print "Last latency:", lastResult.avgLatency
        if (lastThroughput >= peakThroughput):
            peakThroughput = lastThroughput
            leftBound = n
        rightBound = n
        n += increment


    leftBound -= increment
    n = leftBound 
    if (n < startClients):
        print "ERROR: coarse scan increment too high!"
        return results

    print "Fast/coarse scan done. Starting slow/fine scan from", n, "to", rightBound
    
    # Find peak again with a fine-grained scan
    peakThroughput = 0
    lastThroughput = 0    
    while n <= rightBound:
        try:
            lastThroughput = cache[n]
            print "In slow/fine scan. Reusing cached value:", n, "=>", cache[n]
        except KeyError:
            print "In slow/fine scan. Running:", n,
            lastResult = runBench(config, n, config.makePropertiesArgs)
            results.append(lastResult)
            lastThroughput = lastResult.avgThroughput
            print "In slow/fine scan. Run", len(results)
        print "n =", n, "(linear throughput would be:", 0.165*n, ")"
        print "Last throughput:", lastThroughput
        print "Last latency:", lastResult.avgLatency
        if (lastThroughput >= peakThroughput):
            peakThroughput = lastThroughput
        n += tolerance

    print "Found peak at ", peakThroughput
    

    # print "Peak throughput for scanning phase:", peakThroughput
    # print "Starting binary search over", leftBound, rightBound

    # while (rightBound - leftBound) > tolerance:
    #     print "Binary search:", leftBound, rightBound
    #     n = (rightBound + leftBound)/2
    #     print "Trying", n
    #     lastResult = runBench(config, n, config.makePropertiesArgs)
    #     results.append(lastResult)
    #     lastThroughput = lastResult.avgThroughput
    #     print "Run", len(results)
    #     print "Last throughput:", lastThroughput
    #     if (lastThroughput >= peakThroughput):
    #         print "New peak throughput"
    #         peakThroughput = lastThroughput
    #         leftBound = n
    #     else:
    #         print "Less than peak throughput"
    #         rightBound = n

    # print "Binary search done -- peak lies in", leftBound, rightBound
    # return results

        
def printResults(results):
    for x in results:
        print x

def dumpResults(results, filename):
    f = file(filename, "w")
    f.writelines([str(x)+"\n" for x in results])

def makeResultsDirectory(results, resdirpath):
    os.mkdir(resdirpath)
    dumpResults(results, os.path.join(resdirpath,
                                      os.path.basename(resdirpath)+".txt"))
    i=0
    for res in results:
        i+=1
        os.symlink(os.path.join(RUBISPATH, "bench", res.name),
                   os.path.join(resdirpath, str(i)+"-"+str(res.numClients)+"-bench"))
        os.symlink(os.path.join(RUBISPATH, "bench", res.name, "info"),
                   os.path.join(resdirpath, str(i)+"-"+str(res.numClients)+"-info"))


class ExperimentConfig:
    def __init__(self, name, pgsql, reloadDB=True, reloadDBEachTime=True,
                 vacuum=True, flushCache=False, warmup=STDWARMUP,
                 makePropertiesArgs="medium mediumsize shortupramp",
                 useCache=False, doItAnyway=False, memcachedMode=False,
                 microCache=False,
                 freshnessReq=STDFRESHNESS, pinPolicy=STDPINPOLICY,
                 primeDBCache=False, cacheSize="64M", randomizeFreshness=None,
                 dumpCache=None, restoreSnapshot="medium",
                 debugDump=False,
                 runSeriesFn=(lambda x : runSeries(x, NUMCLIENTS))):
        self.name = name
        self.pgsql = pgsql
        self.reloadDB = reloadDB
        self.reloadDBEachTime = reloadDBEachTime
        self.vacuum = vacuum
        self.flushCache = flushCache
        self.warmup = warmup
        self.makePropertiesArgs = makePropertiesArgs
        self.useCache = useCache
        self.microCache = microCache
        self.doItAnyway = doItAnyway
        self.memcachedMode = memcachedMode
        self.freshnessReq = freshnessReq
        self.pinPolicy = pinPolicy
        self.runSeriesFn = runSeriesFn
        self.primeDBCache = primeDBCache
        self.cacheSize = cacheSize
        self.randomizeFreshness = randomizeFreshness
        self.dumpCache = dumpCache
        self.debugDump = debugDump
        self.restoreSnapshot = restoreSnapshot
        if self.memcachedMode:
            self.txcachebypassArg = 3
            self.useCache = True
        elif self.doItAnyway:
            self.txcachebypassArg = 2
            self.useCache = True
        elif self.useCache:
            self.txcachebypassArg = 0
        else:
            self.txcachebypassArg = 1
                
        if reloadDBEachTime:
            # no point in reloading the DB and warming up at the
            # beginning if we're just going to reload it on each run
            self.reloadDB = False
            self.warmup = []
                

    def go(self):
        if not self.reloadDBEachTime:
            self.setup()
        self.run()
        if not self.reloadDBEachTime:        
            self.stop()

    def cleanup(self):
        os.system("killall java")
        for x in REMOTECLIENTHOSTS:
            os.system("ssh %s killall java" % x)
        for host, port in CACHEHOSTS:
            os.system("ssh %s killall server" % host)
        os.system("ssh %s killall pincushion" % PINCUSHIONHOST[0])
        os.system("ssh %s killall invald" % INVALDHOST)
        for host in WEBHOSTS:
            os.system("ssh %s sudo /etc/init.d/apache2 stop" % host)
            os.system("ssh %s sudo killall php5-cgi" % host)
            
    def setup(self):
        self.cleanup()
        time.sleep(1)
        if self.reloadDB or self.reloadDBEachTime:
            reloadDB(self.pgsql, self.restoreSnapshot) # implicit startDB
        else:
            startDB(self.pgsql)
        #stopDB(self)
        if self.flushCache:
            flushCache()
        #startDB(self.pgsql)
        if self.primeDBCache:
            primeDBCache()
        if self.useCache:
            startCache(self)
        # Apache must start after cache so correct cache config is used
        # Also, will delay startup so we can clean up logs in runBench
        # startApache()
        makeConfigPHP(self)

        for x in self.warmup:
            runBench(self, x, self.makePropertiesArgs)

    def run(self):
        results = self.runSeriesFn(self)
        printResults(results)
        makeResultsDirectory(results, ("results/results-"+
                              time.strftime("%Y%m%d%H%M%S")+
                              "-"+self.name))

    def stop(self):
        if self.useCache:
            stopCache(self)
        stopDB(self)



EXPERIMENTS = [
#    ExperimentConfig("mediumdb-memcached-freshness1-primed-inval-256M", "/u/drkp/txcache-deploy-db/pgsql/obj", memcachedMode=True, microCache=True, freshnessReq=1, randomizeFreshness=None, cacheSize="128M", reloadDBEachTime=True, restoreSnapshot="medium-primed-new", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 10000, 2500, 3))),
#    ExperimentConfig("mediumdb-memcached-freshness30-primed-inval-256M", "/u/drkp/txcache-deploy-db/pgsql/obj", memcachedMode=True, microCache=True, freshnessReq=30, randomizeFreshness=None, cacheSize="128M", reloadDBEachTime=True, restoreSnapshot="medium-primed", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 17500, 2500, 2))),
#    ExperimentConfig("mediumdb-memcached-freshness30-primed-inval-64M", "/u/drkp/txcache-deploy-db/pgsql/obj", memcachedMode=True, microCache=True, freshnessReq=30, randomizeFreshness=None, cacheSize="32M", reloadDBEachTime=True, restoreSnapshot="medium-primed", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 15000, 2500, 2))),
#    ExperimentConfig("mediumdb-memcached-freshness30-primed-inval-512M", "/u/drkp/txcache-deploy-db/pgsql/obj", memcachedMode=True, microCache=True, freshnessReq=30, randomizeFreshness=None, cacheSize="256M", reloadDBEachTime=True, restoreSnapshot="medium-primed", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 25000, 2500, 2))),
#    ExperimentConfig("mediumdb-memcached-freshness30-primed-inval-128M", "/u/drkp/txcache-deploy-db/pgsql/obj", memcachedMode=True, microCache=True, freshnessReq=30, randomizeFreshness=None, cacheSize="64M", reloadDBEachTime=True, restoreSnapshot="medium-primed", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 15000, 2500, 2))),
#    ExperimentConfig("mediumdb-memcached-freshness30-primed-inval-1G", "/u/drkp/txcache-deploy-db/pgsql/obj", memcachedMode=True, microCache=True, freshnessReq=30, randomizeFreshness=None, cacheSize="512M", reloadDBEachTime=True, restoreSnapshot="medium-primed", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 25000, 2500, 2))),
#    ExperimentConfig("mediumdb-memcached-primed-inval-512M", "/u/drkp/txcache-deploy-db/pgsql/obj", memcachedMode=True, microCache=True, cacheSize="256M", reloadDBEachTime=True, restoreSnapshot="medium-primed", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 12500, 2500, 2))),
#    ExperimentConfig("mediumdb-txcache-freshness30-primed-inval-512M-test", "/u/drkp/txcache-deploy-db/pgsql/obj", useCache=True, microCache=True, freshnessReq=30, randomizeFreshness=None, cacheSize="256M", reloadDBEachTime=True, restoreSnapshot="medium-primed", runSeriesFn=(lambda x: runSeries(x, [20000]))),
#    ExperimentConfig("mediumdb-stock-primed", "/u/drkp/txcache-deploy-db/postgresql-8.2.11/obj", reloadDBEachTime=True, restoreSnapshot="medium-primed-new", runSeriesFn=(lambda x: runSeries(x, [5000, 10000, 20000]))),
#    ExperimentConfig("mediumdb-txcache-freshness30-dump", "/u/drkp/txcache-deploy-db/pgsql/obj", useCache=True, microCache=True, debugDump=True, dumpCache="medium-primed-autoinval", freshnessReq=30, randomizeFreshness=None, cacheSize="1536M", reloadDBEachTime=False, makePropertiesArgs="mediumsize hour", runSeriesFn=(lambda x: runSeries(x, [10000]*1))),
    #ExperimentConfig("mediumdb-txcache-freshness300", "/u/drkp/txcache-deploy-db/pgsql/obj", useCache=True, microCache=True, freshnessReq=300, runSeriesFn=(lambda x: runSeriesDynamic(x, 50, 15000, 5000, 3))),
#    ExperimentConfig("mediumdb-txcache-freshness30-16m", "/u/drkp/txcache-deploy-db/pgsql/obj", useCache=True, microCache=True, freshnessReq=30, cacheSize="8M", runSeriesFn=(lambda x: runSeries(x, [19000]))),
#    ExperimentConfig("mediumdb-stock", "/u/drkp/txcache-deploy-db/postgresql-8.2.11/obj", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 5000, 1000, 3))),
#    ExperimentConfig("mediumdb-modified", "/u/drkp/txcache-deploy-db/pgsql/obj", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 3000, 1000, 3))),
#    ExperimentConfig("mediumdb-stock", "/u/drkp/txcache-deploy-db/postgresql-8.2.11/obj", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 3000, 1000, 3))),
#    ExperimentConfig("mediumdb-stock-primed-test", "/u/drkp/txcache-deploy-db/postgresql-8.2.11/obj", reloadDBEachTime=True, restoreSnapshot="medium-primed-autoinval", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 4000, 1000, 3))),
#    ExperimentConfig("mediumdb-stock-primed-for-cputime", "/u/drkp/txcache-deploy-db/postgresql-8.2.11/obj", reloadDBEachTime=True, restoreSnapshot="medium-primed-autoinval", runSeriesFn=(lambda x: runSeries(x, [3000]))),
#    ExperimentConfig("mediumdb-txcache-freshness30-primed-inval-256M", "/u/drkp/txcache-deploy-db/pgsql/obj", useCache=True, microCache=True, freshnessReq=30, randomizeFreshness=None, cacheSize="128M", reloadDBEachTime=True, restoreSnapshot="medium-primed-new", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 22500, 2500, 3))),
   ExperimentConfig("mediumdb-txcache-freshness30-primed-autoinval-512M", "/u/drkp/txcache-deploy-db/pgsql/obj", useCache=True, microCache=True, freshnessReq=30, randomizeFreshness=None, cacheSize="256M", reloadDBEachTime=True, restoreSnapshot="medium-primed-autoinval", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 20000, 2500, 2))),
#   ExperimentConfig("mediumdb-txcache-freshness30-primed-autoinval-512M-for-cputime", "/u/drkp/txcache-deploy-db/pgsql/obj", useCache=True, microCache=True, freshnessReq=30, randomizeFreshness=None, cacheSize="256M", reloadDBEachTime=True, restoreSnapshot="medium-primed-autoinval", runSeriesFn=(lambda x: runSeries(x, [3000]))),
   ExperimentConfig("mediumdb-txcache-freshness30-primed-autoinval-1G", "/u/drkp/txcache-deploy-db/pgsql/obj", useCache=True, microCache=True, freshnessReq=30, randomizeFreshness=None, cacheSize="512M", reloadDBEachTime=True, restoreSnapshot="medium-primed-autoinval", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 20000, 2500, 2))),
   ExperimentConfig("mediumdb-txcache-freshness30-primed-autoinval-128M", "/u/drkp/txcache-deploy-db/pgsql/obj", useCache=True, microCache=True, freshnessReq=30, randomizeFreshness=None, cacheSize="64M", reloadDBEachTime=True, restoreSnapshot="medium-primed-autoinval", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 15000, 2500, 2))),
   ExperimentConfig("mediumdb-txcache-freshness30-primed-autoinval-64M", "/u/drkp/txcache-deploy-db/pgsql/obj", useCache=True, microCache=True, freshnessReq=30, randomizeFreshness=None, cacheSize="32M", reloadDBEachTime=True, restoreSnapshot="medium-primed-autoinval", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 10000, 2500, 2))),
   ExperimentConfig("mediumdb-txcache-freshness60-primed-autoinval-512M", "/u/drkp/txcache-deploy-db/pgsql/obj", useCache=True, microCache=True, freshnessReq=60, randomizeFreshness=None, cacheSize="256M", reloadDBEachTime=True, restoreSnapshot="medium-primed-autoinval", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 20000, 2500, 2))),
   ExperimentConfig("mediumdb-txcache-freshness15-primed-autoinval-512M", "/u/drkp/txcache-deploy-db/pgsql/obj", useCache=True, microCache=True, freshnessReq=15, randomizeFreshness=None, cacheSize="256M", reloadDBEachTime=True, restoreSnapshot="medium-primed-autoinval", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 12500, 2500, 2))),
   ExperimentConfig("mediumdb-txcache-freshness5-primed-autoinval-512M", "/u/drkp/txcache-deploy-db/pgsql/obj", useCache=True, microCache=True, freshnessReq=5, randomizeFreshness=None, cacheSize="256M", reloadDBEachTime=True, restoreSnapshot="medium-primed-autoinval", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 12500, 2500, 2))),
   ExperimentConfig("mediumdb-txcache-freshness1-primed-autoinval-512M", "/u/drkp/txcache-deploy-db/pgsql/obj", useCache=True, microCache=True, freshnessReq=1, randomizeFreshness=None, cacheSize="256M", reloadDBEachTime=True, restoreSnapshot="medium-primed-autoinval", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 10000, 2500, 2))),
   ExperimentConfig("mediumdb-txcache-freshness120-primed-autoinval-512M", "/u/drkp/txcache-deploy-db/pgsql/obj", useCache=True, microCache=True, freshnessReq=120, randomizeFreshness=None, cacheSize="256M", reloadDBEachTime=True, restoreSnapshot="medium-primed-autoinval", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 32500, 2500, 2))),
   ExperimentConfig("mediumdb-txcache-freshness300-primed-autoinval-512M", "/u/drkp/txcache-deploy-db/pgsql/obj", useCache=True, microCache=True, freshnessReq=300, randomizeFreshness=None, cacheSize="256M", reloadDBEachTime=True, restoreSnapshot="medium-primed-autoinval", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 32500, 2500, 2))),
#   ExperimentConfig("mediumdb-txcache-freshness210-primed-autoinval-512M", "/u/drkp/txcache-deploy-db/pgsql/obj", useCache=True, microCache=True, freshnessReq=210, randomizeFreshness=None, cacheSize="256M", reloadDBEachTime=True, restoreSnapshot="medium-primed-autoinval", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 32500, 2500, 2))),
   ExperimentConfig("mediumdb-txcache-freshness30-primed-autoinval-32M", "/u/drkp/txcache-deploy-db/pgsql/obj", useCache=True, microCache=True, freshnessReq=30, randomizeFreshness=None, cacheSize="16M", reloadDBEachTime=True, restoreSnapshot="medium-primed-autoinval", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 10000, 2500, 2))),
#    ExperimentConfig("mediumdb-txcache-freshness30-norand", "/u/drkp/txcache-deploy-db/pgsql/obj", useCache=True, microCache=True, freshnessReq=30, randomizeFreshness=None, runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 5000, 2000, 2))),
#    ExperimentConfig("mediumdb-txcache-freshness30-longupramp", "/u/drkp/txcache-deploy-db/pgsql/obj", useCache=True, microCache=True, freshnessReq=30, makePropertiesArgs="medium mediumsize longupramp", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 5000, 2000, 2))),
    #ExperimentConfig("mediumdb-txcache-freshness300-nomicrocache", "/u/drkp/txcache-deploy-db/pgsql/obj", useCache=True, microCache=False, freshnessReq=300, runSeriesFn=(lambda x: runSeriesDynamic(x, 50, 17000, 2000, 2))),
#    ExperimentConfig("mediumdb-txcache-freshness300", "/u/drkp/txcache-deploy-db/pgsql/obj", useCache=True, microCache=True, freshnessReq=300, runSeriesFn=(lambda x: runSeriesDynamic(x, 50, 23000, 2000, 2))),
#    ExperimentConfig("mediumdb-txcache-freshness60", "/u/drkp/txcache-deploy-db/pgsql/obj", useCache=True, microCache=True, freshnessReq=60, runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 15000, 2000, 2))),
#    ExperimentConfig("mediumdb-txcache-freshness15", "/u/drkp/txcache-deploy-db/pgsql/obj", useCache=True, microCache=True, freshnessReq=15, runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 9000, 2000, 2))),
#    ExperimentConfig("mediumdb-txcache-freshness5", "/u/drkp/txcache-deploy-db/pgsql/obj", useCache=True, microCache=True, freshnessReq=5, runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 7000, 2000, 2))),
#    ExperimentConfig("mediumdb-txcache-freshness120", "/u/drkp/txcache-deploy-db/pgsql/obj", useCache=True, microCache=True, freshnessReq=120, runSeriesFn=(lambda x: runSeriesDynamic(x, 50, 13000, 2000, 2))),#    ExperimentConfig("mediumdb-txcache-freshness30-64m", "/u/drkp/txcache-deploy-db/pgsql/obj", useCache=True, microCache=True, freshnessReq=30, cacheSize="32M", runSeriesFn=(lambda x: runSeries(x, [19000]))),
#    ExperimentConfig("mediumdb-txcache-freshness30-32m", "/u/drkp/txcache-deploy-db/pgsql/obj", useCache=True, microCache=True, freshnessReq=30, cacheSize="16M", runSeriesFn=(lambda x: runSeries(x, [19000]))),
#    ExperimentConfig("mediumdb-txcache-freshness30-512m", "/u/drkp/txcache-deploy-db/pgsql/obj", useCache=True, microCache=True, freshnessReq=30, cacheSize="256M", runSeriesFn=(lambda x: runSeries(x, [19000]))),
#    ExperimentConfig("bigdb-stock-primed", "/u/drkp/txcache-deploy-db/postgresql-8.2.11/obj", makePropertiesArgs="medium", restoreSnapshot="big-primed", reloadDBEachTime=True, runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 750, 125, 3))),
#    ExperimentConfig("bigdb-txcache-freshness30-primed-inval-9G", "/u/drkp/txcache-deploy-db/pgsql/obj", makePropertiesArgs="medium", useCache=True, microCache=True, freshnessReq=30, randomizeFreshness=None, cacheSize="1138M", reloadDBEachTime=True, restoreSnapshot="big-primed", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 1500, 250, 3))),
#    ExperimentConfig("bigdb-txcache-freshness15-primed-inval-9G", "/u/drkp/txcache-deploy-db/pgsql/obj", makePropertiesArgs="medium", useCache=True, microCache=True, freshnessReq=15, randomizeFreshness=None, cacheSize="1138M", reloadDBEachTime=True, restoreSnapshot="big-primed", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 2000, 250, 3))),
#    ExperimentConfig("bigdb-txcache-freshness10-primed-inval-9G", "/u/drkp/txcache-deploy-db/pgsql/obj", makePropertiesArgs="medium", useCache=True, microCache=True, freshnessReq=10, randomizeFreshness=None, cacheSize="1138M", reloadDBEachTime=True, restoreSnapshot="big-primed", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 2000, 250, 3))),
#    ExperimentConfig("bigdb-txcache-freshness5-primed-inval-9G", "/u/drkp/txcache-deploy-db/pgsql/obj", makePropertiesArgs="medium", useCache=True, microCache=True, freshnessReq=5, randomizeFreshness=None, cacheSize="1138M", reloadDBEachTime=True, restoreSnapshot="big-primed", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 2000, 250, 3))),
#    ExperimentConfig("bigdb-txcache-freshness60-primed-inval-9G", "/u/drkp/txcache-deploy-db/pgsql/obj", makePropertiesArgs="medium", useCache=True, microCache=True, freshnessReq=60, randomizeFreshness=None, cacheSize="1138M", reloadDBEachTime=True, restoreSnapshot="big-primed", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 3000, 250, 2))),
#    ExperimentConfig("bigdb-txcache-freshness1-primed-inval-9G", "/u/drkp/txcache-deploy-db/pgsql/obj", makePropertiesArgs="medium", useCache=True, microCache=True, freshnessReq=5, randomizeFreshness=None, cacheSize="1138M", reloadDBEachTime=True, restoreSnapshot="big-primed", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 1500, 250, 3))),
#    ExperimentConfig("bigdb-txcache-freshness120-primed-inval-9G", "/u/drkp/txcache-deploy-db/pgsql/obj", makePropertiesArgs="medium", useCache=True, microCache=True, freshnessReq=120, randomizeFreshness=None, cacheSize="1138M", reloadDBEachTime=True, restoreSnapshot="big-primed", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 2000, 250, 3))),
#    ExperimentConfig("bigdb-txcache-freshness300-primed-inval-9G", "/u/drkp/txcache-deploy-db/pgsql/obj", makePropertiesArgs="medium", useCache=True, microCache=True, freshnessReq=300, randomizeFreshness=None, cacheSize="1138M", reloadDBEachTime=True, restoreSnapshot="big-primed", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 2000, 250, 3))),
#    ExperimentConfig("bigdb-txcache-freshness600-primed-inval-9G", "/u/drkp/txcache-deploy-db/pgsql/obj", makePropertiesArgs="medium", useCache=True, microCache=True, freshnessReq=600, randomizeFreshness=None, cacheSize="1138M", reloadDBEachTime=True, restoreSnapshot="big-primed", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 2000, 250, 3))),
#    ExperimentConfig("biggerdb-stock", "/u/drkp/txcache-deploy-db/postgresql-8.2.11/obj", makePropertiesArgs="medium bigger", restoreSnapshot="bigger", reloadDBEachTime=True, runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 1000, 125, 3))),
#    ExperimentConfig("bigdb-txcache-freshness30-dump", "/u/drkp/txcache-deploy-db/pgsql/obj", makePropertiesArgs="hour", restoreSnapshot="big", useCache=True, microCache=True, dumpCache="big-primed", freshnessReq=30, randomizeFreshness=None, cacheSize="1138M", reloadDBEachTime=False, debugDump=True, runSeriesFn=(lambda x: runSeries(x, [3000]*24)))
#     ExperimentConfig("bigdb-txcache-freshness30-primed-inval-9G-test", "/u/drkp/txcache-deploy-db/pgsql/obj", makePropertiesArgs="medium", useCache=True, microCache=True, freshnessReq=30, randomizeFreshness=None, cacheSize="1138M", reloadDBEachTime=True, restoreSnapshot="big-primed", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 3000, 250, 3))),
    # ExperimentConfig("bigdb-txcache-freshness30-primed-inval-1G", "/u/drkp/txcache-deploy-db/pgsql/obj", makePropertiesArgs="medium", useCache=True, microCache=True, freshnessReq=30, randomizeFreshness=None, cacheSize="128M", reloadDBEachTime=True, restoreSnapshot="big-primed", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 750, 250, 2))),
    # ExperimentConfig("bigdb-txcache-freshness30-primed-inval-2G", "/u/drkp/txcache-deploy-db/pgsql/obj", makePropertiesArgs="medium", useCache=True, microCache=True, freshnessReq=30, randomizeFreshness=None, cacheSize="256M", reloadDBEachTime=True, restoreSnapshot="big-primed", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 750, 250, 2))),
    # ExperimentConfig("bigdb-txcache-freshness30-primed-inval-3G", "/u/drkp/txcache-deploy-db/pgsql/obj", makePropertiesArgs="medium", useCache=True, microCache=True, freshnessReq=30, randomizeFreshness=None, cacheSize="384M", reloadDBEachTime=True, restoreSnapshot="big-primed", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 1000, 250, 2))),
    # ExperimentConfig("bigdb-txcache-freshness30-primed-inval-4G", "/u/drkp/txcache-deploy-db/pgsql/obj", makePropertiesArgs="medium", useCache=True, microCache=True, freshnessReq=30, randomizeFreshness=None, cacheSize="512M", reloadDBEachTime=True, restoreSnapshot="big-primed", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 1000, 250, 2))),
    # ExperimentConfig("bigdb-txcache-freshness30-primed-inval-6G", "/u/drkp/txcache-deploy-db/pgsql/obj", makePropertiesArgs="medium", useCache=True, microCache=True, freshnessReq=30, randomizeFreshness=None, cacheSize="768M", reloadDBEachTime=True, restoreSnapshot="big-primed", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 1250, 250, 2))),
    # ExperimentConfig("bigdb-txcache-freshness30-primed-inval-8G", "/u/drkp/txcache-deploy-db/pgsql/obj", makePropertiesArgs="medium", useCache=True, microCache=True, freshnessReq=30, randomizeFreshness=None, cacheSize="1G", reloadDBEachTime=True, restoreSnapshot="big-primed", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 1250, 250, 2))),
     #ExperimentConfig("bigdb-txcache-freshness30-primed-inval-9G", "/u/drkp/txcache-deploy-db/pgsql/obj", makePropertiesArgs="medium", useCache=True, microCache=True, freshnessReq=30, randomizeFreshness=None, cacheSize="1138M", reloadDBEachTime=True, restoreSnapshot="big-primed", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 2500, 250, 2))),
#     ExperimentConfig("bigdb-txcache-freshness30-primed-inval-10G", "/u/drkp/txcache-deploy-db/pgsql/obj", makePropertiesArgs="medium", useCache=True, microCache=True, freshnessReq=30, randomizeFreshness=None, cacheSize="1280M", reloadDBEachTime=True, restoreSnapshot="big-primed", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 2500, 250, 2))),
#    ExperimentConfig("bigdb-txcache-freshness30-primed10-inval-10G", "/u/drkp/txcache-deploy-db/pgsql/obj", makePropertiesArgs="medium", useCache=True, microCache=True, freshnessReq=30, randomizeFreshness=None, cacheSize="1138M", reloadDBEachTime=True, restoreSnapshot="big-primed10", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 2500, 250, 2))),
#      ExperimentConfig("bigdb-memcached-freshness30-primed-inval-1G", "/u/drkp/txcache-deploy-db/pgsql/obj", makePropertiesArgs="medium", memcachedMode=True, useCache=True, microCache=True, freshnessReq=30, randomizeFreshness=None, cacheSize="128M", reloadDBEachTime=True, restoreSnapshot="big-primed", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 1000, 250, 2))),
    #  ExperimentConfig("bigdb-memcached-freshness30-primed-inval-2G", "/u/drkp/txcache-deploy-db/pgsql/obj", makePropertiesArgs="medium", memcachedMode=True, useCache=True, microCache=True, freshnessReq=30, randomizeFreshness=None, cacheSize="256M", reloadDBEachTime=True, restoreSnapshot="big-primed", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 1000, 250, 2))),
    #  ExperimentConfig("bigdb-memcached-freshness30-primed-inval-3G", "/u/drkp/txcache-deploy-db/pgsql/obj", makePropertiesArgs="medium", memcachedMode=True, useCache=True, microCache=True, freshnessReq=30, randomizeFreshness=None, cacheSize="384M", reloadDBEachTime=True, restoreSnapshot="big-primed", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 1250, 250, 2))),
    #  ExperimentConfig("bigdb-memcached-freshness30-primed-inval-4G", "/u/drkp/txcache-deploy-db/pgsql/obj", makePropertiesArgs="medium", memcachedMode=True, useCache=True, microCache=True, freshnessReq=30, randomizeFreshness=None, cacheSize="512M", reloadDBEachTime=True, restoreSnapshot="big-primed", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 1500, 250, 2))),
    #  ExperimentConfig("bigdb-memcached-freshness30-primed-inval-6G", "/u/drkp/txcache-deploy-db/pgsql/obj", makePropertiesArgs="medium", memcachedMode=True, useCache=True, microCache=True, freshnessReq=30, randomizeFreshness=None, cacheSize="768M", reloadDBEachTime=True, restoreSnapshot="big-primed", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 1750, 250, 2))),
      # ExperimentConfig("bigdb-memcached-freshness30-primed-inval-8G", "/u/drkp/txcache-deploy-db/pgsql/obj", makePropertiesArgs="medium", memcachedMode=True, useCache=True, microCache=True, freshnessReq=30, randomizeFreshness=None, cacheSize="1G", reloadDBEachTime=True, restoreSnapshot="big-primed", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 2000, 250, 2))),
      # ExperimentConfig("bigdb-memcached-freshness30-primed-inval-9G", "/u/drkp/txcache-deploy-db/pgsql/obj", makePropertiesArgs="medium", memcachedMode=True, useCache=True, microCache=True, freshnessReq=30, randomizeFreshness=None, cacheSize="1138M", reloadDBEachTime=True, restoreSnapshot="big-primed", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 2250, 250, 2))),
    # ExperimentConfig("bigdb-memcached-freshness30-primed-inval-10G", "/u/drkp/txcache-deploy-db/pgsql/obj", makePropertiesArgs="medium", memcachedMode=True, useCache=True, microCache=True, freshnessReq=30, randomizeFreshness=None, cacheSize="1280M", reloadDBEachTime=True, restoreSnapshot="big-primed", runSeriesFn=(lambda x: runSeriesDynamic(x, 25, 2500, 250, 2))),
  ]


for experiment in EXPERIMENTS:
    experiment.go()

# dirs = os.listdir(os.path.join(RUBISPATH, "bench"))
# times = [(os.stat(os.path.join(RUBISPATH, "bench", x)).st_mtime,
#           x)
#          for x in dirs]
# times.sort()
# results = [BenchResult(x[1]) for x in times[-14:]]
# printResults(results)
# makeResultsDirectory(results, ("results/results-"+
#                                time.strftime("%Y%m%d%H%M%S")+
#                                "-"+"mediumdb-txcache-freshness30"))
