xref: /OpenGrok/opengrok-indexer/src/main/java/org/opengrok/indexer/index/NumLinesLOCAggregator.java (revision fb4fc4bcc2970158c11a79b4070ebcd0797d96d6)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * See LICENSE.txt included in this distribution for the specific
9  * language governing permissions and limitations under the License.
10  *
11  * When distributing Covered Code, include this CDDL HEADER in each
12  * file and include the License file at LICENSE.txt.
13  * If applicable, add the following below this CDDL HEADER, with the
14  * fields enclosed by brackets "[]" replaced with your own identifying
15  * information: Portions Copyright [yyyy] [name of copyright owner]
16  *
17  * CDDL HEADER END
18  */
19 
20 /*
21  * Copyright (c) 2020, Chris Fraire <cfraire@me.com>.
22  */
23 package org.opengrok.indexer.index;
24 
25 import org.opengrok.indexer.analysis.AccumulatedNumLinesLOC;
26 import org.opengrok.indexer.analysis.NumLinesLOC;
27 import org.opengrok.indexer.web.Util;
28 
29 import java.io.File;
30 import java.util.HashMap;
31 import java.util.Iterator;
32 import java.util.Map;
33 
34 /**
35  * Represents an accumulator of net-deltas of #Lines and LOC for directories.
36  */
37 public class NumLinesLOCAggregator {
38     private final Object syncRoot = new Object();
39 
40     private final HashMap<String, DeltaData> registeredDeltas = new HashMap<>();
41 
42     /**
43      * Gets an iterator over all registered data, explicit and derived, and not
44      * ordered.
45      * @return a defined instance
46      */
iterator()47     public Iterator<AccumulatedNumLinesLOC> iterator() {
48         return new AccumulationsIterator(registeredDeltas.entrySet().iterator());
49     }
50 
51     /**
52      * Registers the specified counts. Values should be negative when deleting a
53      * file or when updating a file's analysis to reverse former values before
54      * re-registering.
55      */
register(NumLinesLOC counts)56     public void register(NumLinesLOC counts) {
57         File file = new File(counts.getPath());
58         File directory = file.getParentFile();
59         if (directory != null) {
60             synchronized (syncRoot) {
61                 do {
62                     String dirPath = Util.fixPathIfWindows(directory.getPath());
63                     DeltaData extantDelta = registeredDeltas.get(dirPath);
64                     if (extantDelta == null) {
65                         extantDelta = new DeltaData();
66                         registeredDeltas.put(dirPath, extantDelta);
67                     }
68                     extantDelta.numLines += counts.getNumLines();
69                     extantDelta.loc += counts.getLOC();
70                 } while ((directory = directory.getParentFile()) != null &&
71                         directory.getPath().length() > 0);
72             }
73         }
74     }
75 
76     private static class DeltaData {
77         long numLines;
78         long loc;
79     }
80 
81     private static class AccumulationsIterator implements Iterator<AccumulatedNumLinesLOC> {
82         private final Iterator<Map.Entry<String, DeltaData>> underlying;
83 
AccumulationsIterator(Iterator<Map.Entry<String, DeltaData>> underlying)84         AccumulationsIterator(Iterator<Map.Entry<String, DeltaData>> underlying) {
85             this.underlying = underlying;
86         }
87 
88         @Override
hasNext()89         public boolean hasNext() {
90             return underlying.hasNext();
91         }
92 
93         @Override
next()94         public AccumulatedNumLinesLOC next() {
95             Map.Entry<String, DeltaData> underlyingNext = underlying.next();
96             String path = underlyingNext.getKey();
97             DeltaData values = underlyingNext.getValue();
98             return new AccumulatedNumLinesLOCImpl(path, values.numLines, values.loc);
99         }
100     }
101 
102     private static class AccumulatedNumLinesLOCImpl implements AccumulatedNumLinesLOC {
103 
104         private final String path;
105         private final long numLines;
106         private final long loc;
107 
AccumulatedNumLinesLOCImpl(String path, long numLines, long loc)108         AccumulatedNumLinesLOCImpl(String path, long numLines, long loc) {
109             this.path = path;
110             this.numLines = numLines;
111             this.loc = loc;
112         }
113 
114         @Override
getPath()115         public String getPath() {
116             return path;
117         }
118 
119         @Override
getNumLines()120         public long getNumLines() {
121             return numLines;
122         }
123 
124         @Override
getLOC()125         public long getLOC() {
126             return loc;
127         }
128     }
129 }
130