All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fiftyone.device.example.batch.FutureUaProcessor Maven / Gradle / Ivy

There is a newer version: 3.2.18.1
Show newest version
/* *********************************************************************
 * This Source Code Form is copyright of 51Degrees Mobile Experts Limited. 
 * Copyright © 2017 51Degrees Mobile Experts Limited, 5 Charlotte Close,
 * Caversham, Reading, Berkshire, United Kingdom RG4 7BY
 * 
 * This Source Code Form is the subject of the following patents and patent
 * applications, owned by 51Degrees Mobile Experts Limited of 5 Charlotte
 * Close, Caversham, Reading, Berkshire, United Kingdom RG4 7BY: 
 * European Patent No. 2871816;
 * European Patent Application No. 17184134.9;
 * United States Patent Nos. 9,332,086 and 9,350,823; and
 * United States Patent Application No. 15/686,066.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0.
 * 
 * If a copy of the MPL was not distributed with this file, You can obtain
 * one at http://mozilla.org/MPL/2.0/.
 * 
 * This Source Code Form is "Incompatible With Secondary Licenses", as
 * defined by the Mozilla Public License, v. 2.0.
 * ********************************************************************* */
package fiftyone.device.example.batch;

import fiftyone.mobile.detection.Match;
import fiftyone.mobile.detection.Provider;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.*;

/**
 * Implementation of UaProcessor that uses ExecutorCompletionService to do detections.
 * 

* All results are stored in memory, so while this class is fast to execute it cannot carry * out large numbers of detections. It's fine for the 20k HTTP User-Agents distributed as a sample. */ public class FutureUaProcessor extends UaProcessor.Base { private class Result { String userAgent; Match match; long time; Result(String userAgent, long time, Match match) { this.userAgent = userAgent; this.match = match; this.time = time; } } // the collection of results from detection List results; // for collection of cpu time consumed during detection final static ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); final static boolean cpuTimeSupported = threadMXBean.isThreadCpuTimeSupported(); /** * Get CPU time in nanoseconds. The run time may not support resolutions finer than microsecond * @return CPU time as long. */ public static long getCpuTime( ) { return cpuTimeSupported ? threadMXBean.getCurrentThreadCpuTime( ) : 0L; } public FutureUaProcessor(BufferedReader useragents, Provider provider, int numberOfThreads, int limit) throws IOException { super(useragents, provider, numberOfThreads, limit); } @Override public void process() throws Exception { ExecutorService es = Executors.newFixedThreadPool(numberOfThreads); BlockingQueue> completionQueue = new LinkedBlockingQueue>(20000); ExecutorCompletionService ecs = new ExecutorCompletionService(es, completionQueue); try { // keep track of how many futures we have processed // in this implementation we don't actually process any results before the end int taken = 0; // record the wall-clock time now start = System.currentTimeMillis(); // submit all test HTTP User-Agent strings for detection while (count < limit && useragents.ready()) { final String nextUserAgent = useragents.readLine(); ecs.submit(new Callable() { @Override public Result call() throws Exception { // measure the cpu time for detection long start = getCpuTime(); // do the detection Match match = provider.match(nextUserAgent); long time = getCpuTime() - start; return new Result(nextUserAgent, time, match); } } ); count++; } // wait for all submitted futures to complete and store result in memory results = new ArrayList(count); for (int i = 0; i < count-taken; i++) { Result result = ecs.take().get(); results.add(result); } // all results are now in so we can stop the wall-clock time stop = System.currentTimeMillis(); } finally { es.shutdown(); } } @Override public void printStats(PrintWriter output) { // sort the results into increasing time to execute (or if equal, then alpha sort on ua) Collections.sort(results, new Comparator() { @Override public int compare(Result o1, Result o2) { int diff = (int) (o1.time / 1000 - o2.time / 1000); return diff != 0 ? diff : o1.userAgent.compareTo(o2.userAgent); } }); long totalTime = 0; for (Result result : results) { totalTime += result.time; } long elapsedMillis = stop - start; output.printf("%,d Detections%n", results.size()); output.printf("Elapsed clock time %,d millis on %d threads, %,d detections/sec, %,d micros average%n", elapsedMillis, numberOfThreads, results.size()*1000/elapsedMillis, elapsedMillis*1000/results.size()); output.printf("Total cpu time %,d millis%n", totalTime/1000/1000); output.printf("Average cpu was %,d micros%n", totalTime/results.size()/1000); output.printf("Fastest cpu was %,d micros %s%n", results.get(0).time/1000, results.get(0).userAgent); output.printf("Slowest cpu was %,d micros %s%n", results.get(results.size() - 1).time / 1000, results.get(results.size() - 1).userAgent); super.printStats(output); } @Override public void writeResults(BufferedWriter writer) throws IOException { writeHeaders(writer); for (Result result: results) { writeMatch(writer, result.userAgent, result.time/1000, result.match); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy