package com.github.rohansuri.art.ycsb.string; import org.apache.commons.io.IOUtils; import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.infra.Blackhole; import java.io.FileInputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.*; import java.util.concurrent.TimeUnit; public class E { @State(Scope.Benchmark) public static class EData extends Data { @Param({"e_uniform_1000_url_txn.dat", "e_uniform_5000_url_txn.dat", "e_uniform_10000_url_txn.dat", "e_uniform_50000_url_txn.dat", "e_uniform_100000_url_txn.dat", "e_uniform_500000_url_txn.dat", "e_uniform_1000000_url_txn.dat", "e_uniform_5000000_url_txn.dat", "e_uniform_10000000_url_txn.dat", "e_uniform_50000000_url_txn.dat"}) String workloadFile; boolean[] operation; // what is the ith operation? true == SCAN, false == INSERT String[] scanStart; Integer[] scanRange; String[] toInsert; Object holder; @Setup public void setup() throws IOException { super.loadInMap(workloadFile); holder = new Object(); List<String> s = IOUtils .readLines(new FileInputStream(workloadDirectory + workloadFile), StandardCharsets.US_ASCII); int i = 0; operation = new boolean[s.size()]; List<String> scanStartList = new ArrayList<>(); List<Integer> scanRangeList = new ArrayList<>(); List<String> toInsertList = new ArrayList<>(); for (String op : s) { if (op.startsWith("SCAN")) { operation[i] = true; int scan = op.indexOf(" "); int range = op.lastIndexOf(" "); scanStartList.add(op.substring(scan + 1, range)); scanRangeList.add(Integer.parseInt(op.substring(range + 1))); } else if (op.startsWith("INSERT")) { operation[i] = false; String toInsert = op.substring(op.indexOf(" ") + 1); toInsertList.add(toInsert); } else { throw new RuntimeException("expected either SCAN or INSERT operations in workload E"); } i++; } scanStart = scanStartList.toArray(String[]::new); scanRange = scanRangeList.toArray(Integer[]::new); toInsert = toInsertList.toArray(String[]::new); } } @Benchmark @BenchmarkMode({Mode.AverageTime}) @OutputTimeUnit(TimeUnit.NANOSECONDS) public int rangeScanAndInsert(Blackhole bh, EData d) { int lastInsert = 0; int lastScan = 0; for (int i = 0; i < d.operation.length; i++) { if (d.operation[i]) { // scan NavigableMap<String, Object> tailMap = d.m.tailMap(d.scanStart[lastScan], true); // creation of iterator results in one getCeilingEntry call Iterator<Map.Entry<String, Object>> tail = tailMap.entrySet().iterator(); for (int j = 0; j < d.scanRange[lastScan]-1 && tail.hasNext() ; j++) { // all next calls, call successors (which calls first on Node) bh.consume(tail.next()); } lastScan++; } else { // insert bh.consume(d.m.put(d.toInsert[lastInsert++], d.holder)); } } return d.m.size(); } }