View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *  http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.any23.writer;
19  
20  import org.apache.any23.extractor.ExtractionContext;
21  import org.eclipse.rdf4j.model.Resource;
22  import org.eclipse.rdf4j.model.IRI;
23  import org.eclipse.rdf4j.model.Value;
24  
25  import java.util.HashMap;
26  import java.util.Map;
27  import java.util.Map.Entry;
28  import java.util.concurrent.atomic.AtomicInteger;
29  
30  
31  /**
32   * {@link TripleHandler} decorator useful to
33   * perform benchmarking.
34   */
35  public class BenchmarkTripleHandler implements TripleHandler {
36  
37      /**
38       * Decorated.
39       */
40      private TripleHandler underlyingHandler;
41  
42      /**
43       * Collected statistics. 
44       */
45      private final Map<String, StatObject> stats;
46  
47      /**
48       * Constructor.
49       * @param tripleHandler a configured {@link org.apache.any23.writer.TripleHandler}
50       */
51      public BenchmarkTripleHandler(TripleHandler tripleHandler) {
52          if(tripleHandler == null) {
53              throw new NullPointerException("tripleHandler cannot be null.");
54          }
55          underlyingHandler = tripleHandler;
56          stats = new HashMap<String, StatObject>();
57          stats.put("SUM", new StatObject());
58      }
59  
60      /**
61       * Returns the report as a human readable string.
62       *
63       * @return a human readable report.
64       */
65      public String report() {
66          StringBuilder sb = new StringBuilder();
67          StatObject sum = stats.get("SUM");
68  
69          sb.append("\n>Summary: ");
70          sb.append("\n   -total calls: ").append(sum.methodCalls);
71          sb.append("\n   -total triples: ").append(sum.triples);
72          sb.append("\n   -total runtime: ").append(sum.runtime).append(" ms!");
73          if (sum.runtime != 0)
74              sb.append("\n   -tripls/ms: ").append(sum.triples.get() / sum.runtime);
75          if (sum.methodCalls.get() != 0)
76              sb.append("\n   -ms/calls: ").append(sum.runtime / sum.methodCalls.get());
77  
78          stats.remove("SUM");
79  
80          for (Entry<String, StatObject> ent : stats.entrySet()) {
81              sb.append("\n>Extractor: "       ).append(ent.getKey());
82              sb.append("\n   -total calls: "  ).append(ent.getValue().methodCalls);
83              sb.append("\n   -total triples: ").append(ent.getValue().triples);
84              sb.append("\n   -total runtime: ").append(ent.getValue().runtime).append(" ms!");
85              if (ent.getValue().runtime != 0)
86                  sb.append("\n   -tripls/ms: "  ).append(ent.getValue().triples.get() / ent.getValue().runtime);
87              if (ent.getValue().methodCalls.get() != 0)
88                  sb.append("\n   -ms/calls: "   ).append(ent.getValue().runtime / ent.getValue().methodCalls.get());
89  
90          }
91  
92          return sb.toString();
93      }
94  
95      public void startDocument(IRI documentIRI) throws TripleHandlerException {
96          underlyingHandler.startDocument(documentIRI);
97      }
98  
99      public void close() throws TripleHandlerException {
100         underlyingHandler.close();
101     }
102 
103     public void closeContext(ExtractionContext context) throws TripleHandlerException {
104         if (stats.containsKey(context.getExtractorName())) {
105             stats.get(context.getExtractorName()).interimStop();
106             stats.get("SUM").interimStop();
107         }
108         underlyingHandler.closeContext(context);
109     }
110 
111     public void openContext(ExtractionContext context) throws TripleHandlerException {
112         if (!stats.containsKey(context.getExtractorName())) {
113             stats.put(context.getExtractorName(), new StatObject());
114         }
115         stats.get(context.getExtractorName()).methodCalls.incrementAndGet();
116         stats.get(context.getExtractorName()).interimStart();
117         stats.get("SUM").methodCalls.incrementAndGet();
118         stats.get("SUM").interimStart();
119         underlyingHandler.openContext(context);
120     }
121 
122     public void receiveTriple(Resource s, IRI p, Value o, IRI g, ExtractionContext context)
123     throws TripleHandlerException {
124         if (!stats.containsKey(context.getExtractorName())) {
125             stats.put(context.getExtractorName(), new StatObject());
126         }
127         stats.get(context.getExtractorName()).triples.incrementAndGet();
128         stats.get("SUM").triples.incrementAndGet();
129         underlyingHandler.receiveTriple(s, p, o, g, context);
130     }
131 
132     public void receiveNamespace(String prefix, String uri, ExtractionContext context) throws TripleHandlerException {
133         underlyingHandler.receiveNamespace(prefix, uri, context);
134     }
135 
136     public void endDocument(IRI documentIRI) throws TripleHandlerException {
137         underlyingHandler.endDocument(documentIRI);
138     }
139 
140     public void setContentLength(long contentLength) {
141         underlyingHandler.setContentLength(contentLength);
142     }
143 
144     /**
145      * A single statistics.
146      */
147     private class StatObject {
148 
149         AtomicInteger methodCalls = new AtomicInteger(0);
150         AtomicInteger triples     = new AtomicInteger(0);
151         long runtime    = 0;
152         long intStart   = 0;
153 
154         /**
155          * Takes the start time.
156          */
157         public void interimStart() {
158             intStart = System.currentTimeMillis();
159         }
160 
161         /**
162          * Takes the stop time.
163          */
164         public void interimStop() {
165             runtime += (System.currentTimeMillis() - intStart);
166             intStart = 0;
167         }
168     }
169 
170 }
171