Mercurial > hg > mpdl-group
annotate software/mpdl-services/mpiwg-mpdl-lt/src/de/mpg/mpiwg/berlin/mpdl/lt/morph/app/MorphologyCache.java @ 23:e845310098ba
diverse Korrekturen
author | Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de> |
---|---|
date | Tue, 27 Nov 2012 12:35:19 +0100 |
parents | 7d6d969b10cf |
children |
rev | line source |
---|---|
19 | 1 package de.mpg.mpiwg.berlin.mpdl.lt.morph.app; |
2 | |
3 import java.util.ArrayList; | |
4 import java.util.Collections; | |
5 import java.util.Date; | |
6 import java.util.Enumeration; | |
7 import java.util.Hashtable; | |
8 | |
9 import java.util.logging.Logger; | |
10 | |
11 import de.mpg.mpiwg.berlin.mpdl.lt.general.Language; | |
12 import de.mpg.mpiwg.berlin.mpdl.lt.general.Constants; | |
13 import de.mpg.mpiwg.berlin.mpdl.lt.morph.app.Form; | |
14 import de.mpg.mpiwg.berlin.mpdl.lt.morph.app.Lemma; | |
15 import de.mpg.mpiwg.berlin.mpdl.lt.morph.db.DBMorphHandler; | |
16 import de.mpg.mpiwg.berlin.mpdl.lt.text.norm.Normalizer; | |
17 import de.mpg.mpiwg.berlin.mpdl.lucene.util.LuceneUtil; | |
18 import de.mpg.mpiwg.berlin.mpdl.util.Util; | |
19 import de.mpg.mpiwg.berlin.mpdl.exception.ApplicationException; | |
20 | |
21 public class MorphologyCache { | |
22 private static MorphologyCache instance; | |
23 private static Logger LOGGER = Logger.getLogger(MorphologyCache.class.getName()); | |
24 private static String DATA_DIR = Constants.getInstance().getDataDir(); | |
25 private static String DB_DIR_DONATUS = DATA_DIR + "/dataBerkeleyDB/donatus"; | |
26 public static int QUERY_MODE = 0; | |
27 public static int DOCUMENT_MODE = 1; | |
23
e845310098ba
diverse Korrekturen
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
20
diff
changeset
|
28 private static long MIN_RAM = 500000000; |
19 | 29 private static int MAX_HASHTABLE_SIZE = Constants.MORPHOLOGY_CACHE_SIZE; |
23
e845310098ba
diverse Korrekturen
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
20
diff
changeset
|
30 private Date touchTimer; |
19 | 31 protected int mode = QUERY_MODE; |
32 private Hashtable<String, Hashtable<String, Lemma>> forms = new Hashtable<String, Hashtable<String, Lemma>>(); // cache of forms: hashKey is formName | |
33 private Hashtable<String, Lemma> lemmas = new Hashtable<String, Lemma>(); // cache of lemmas: hashKey is lemmaName | |
23
e845310098ba
diverse Korrekturen
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
20
diff
changeset
|
34 private DBMorphHandler dbMorphHandler; // handles morph data (BerkeleyDB) |
19 | 35 private Date beginOfOperation; |
36 private Date endOfOperation; | |
37 | |
38 public static MorphologyCache getInstance() throws ApplicationException { | |
39 if (instance == null) { | |
40 instance = new MorphologyCache(); | |
41 instance.init(); | |
42 } | |
43 return instance; | |
44 } | |
45 | |
46 private void init() throws ApplicationException { | |
23
e845310098ba
diverse Korrekturen
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
20
diff
changeset
|
47 long maxMemory = Runtime.getRuntime().maxMemory(); |
e845310098ba
diverse Korrekturen
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
20
diff
changeset
|
48 if (maxMemory < MIN_RAM) { |
e845310098ba
diverse Korrekturen
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
20
diff
changeset
|
49 String message = "Morphology cache: at least " + MIN_RAM + " is needed as heap space: please start java with parameter -Xmx with more than this value)"; |
e845310098ba
diverse Korrekturen
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
20
diff
changeset
|
50 LOGGER.severe(message); |
e845310098ba
diverse Korrekturen
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
20
diff
changeset
|
51 throw new ApplicationException(message); |
e845310098ba
diverse Korrekturen
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
20
diff
changeset
|
52 } |
e845310098ba
diverse Korrekturen
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
20
diff
changeset
|
53 touchTimer = new Date(); |
19 | 54 instance.beginOperation(); |
23
e845310098ba
diverse Korrekturen
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
20
diff
changeset
|
55 dbMorphHandler = new DBMorphHandler(DB_DIR_DONATUS); |
e845310098ba
diverse Korrekturen
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
20
diff
changeset
|
56 dbMorphHandler.startReadOnly(); |
e845310098ba
diverse Korrekturen
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
20
diff
changeset
|
57 dbMorphHandler.openDatabases(); |
19 | 58 instance.endOperation(); |
59 Double elapsedTime = new Util().getSecondWithMillisecondsBetween(instance.beginOfOperation, instance.endOfOperation); | |
23
e845310098ba
diverse Korrekturen
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
20
diff
changeset
|
60 LOGGER.info("Morphology cache: morphology db opened read only (needed " + elapsedTime + " seconds, heap space: " + maxMemory + " bytes)"); |
19 | 61 } |
62 | |
63 public int getMode() { | |
64 return mode; | |
65 } | |
66 | |
67 public void setMode(int newMode) { | |
68 this.mode = newMode; | |
69 } | |
70 | |
71 public void end() throws ApplicationException { | |
23
e845310098ba
diverse Korrekturen
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
20
diff
changeset
|
72 dbMorphHandler.closeDatabases(); |
e845310098ba
diverse Korrekturen
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
20
diff
changeset
|
73 LOGGER.info("Morphology cache: db closed"); |
e845310098ba
diverse Korrekturen
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
20
diff
changeset
|
74 forms = null; |
e845310098ba
diverse Korrekturen
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
20
diff
changeset
|
75 lemmas = null; |
e845310098ba
diverse Korrekturen
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
20
diff
changeset
|
76 dbMorphHandler = null; |
e845310098ba
diverse Korrekturen
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
20
diff
changeset
|
77 instance = null; |
19 | 78 } |
79 | |
20
7d6d969b10cf
little corrections
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
19
diff
changeset
|
80 public ArrayList<Lemma> getLemmasByFormName(String lang, String formNameArg, int normMode) throws ApplicationException { |
19 | 81 String language = Language.getInstance().getLanguageId(lang); |
82 ArrayList<Lemma> retFormLemmas = null; | |
83 String formName = formNameArg; | |
20
7d6d969b10cf
little corrections
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
19
diff
changeset
|
84 Normalizer normalizer = new Normalizer(language); |
7d6d969b10cf
little corrections
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
19
diff
changeset
|
85 normalizer.setNormMode(normMode); |
7d6d969b10cf
little corrections
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
19
diff
changeset
|
86 formName = normalizer.normalize(formNameArg); |
19 | 87 // first look in local cache |
88 String key = language + "###" + formName; | |
89 Hashtable<String, Lemma> formLemmasHashtable = forms.get(key); | |
90 if (formLemmasHashtable == null) { | |
91 ArrayList<Lemma> dbFormLemmas = readLemmasByFormName(language, formName); | |
92 // put lemmas into local cache | |
93 int localHashTableSize = forms.size(); | |
23
e845310098ba
diverse Korrekturen
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
20
diff
changeset
|
94 Date now = new Date(); |
e845310098ba
diverse Korrekturen
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
20
diff
changeset
|
95 if (now.getTime() - touchTimer.getTime() > 900000) { // is true each 0,25 hours: then free memory is fetched (needs some time) |
e845310098ba
diverse Korrekturen
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
20
diff
changeset
|
96 touchTimer = new Date(); |
e845310098ba
diverse Korrekturen
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
20
diff
changeset
|
97 long freeMemory = Runtime.getRuntime().freeMemory(); |
e845310098ba
diverse Korrekturen
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
20
diff
changeset
|
98 LOGGER.info(touchTimer + ": Morphology cache: free memory in heap space: " + freeMemory + " bytes"); |
e845310098ba
diverse Korrekturen
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
20
diff
changeset
|
99 if (freeMemory < MIN_RAM || localHashTableSize >= MAX_HASHTABLE_SIZE) { // if freeMemory is less then MIN_RAM then clear cache to get some new memory |
e845310098ba
diverse Korrekturen
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
20
diff
changeset
|
100 clearCache(); |
e845310098ba
diverse Korrekturen
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
20
diff
changeset
|
101 freeMemory = Runtime.getRuntime().freeMemory(); |
e845310098ba
diverse Korrekturen
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
20
diff
changeset
|
102 LOGGER.info(touchTimer + ": Morphology cache: cache cleared, free memory in heap space: " + freeMemory + " bytes"); |
e845310098ba
diverse Korrekturen
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
20
diff
changeset
|
103 } |
19 | 104 } |
105 if (dbFormLemmas != null && ! dbFormLemmas.isEmpty()) { | |
106 formLemmasHashtable = new Hashtable<String, Lemma>(); | |
107 for (int i=0; i<dbFormLemmas.size(); i++) { | |
108 Lemma lemma = dbFormLemmas.get(i); | |
109 String lemmaName = lemma.getLemmaName(); | |
110 String lemmaKey = language + "###" + lemmaName; | |
111 Lemma localLemma = lemmas.get(lemmaKey); | |
112 if (localLemma == null) { | |
113 ArrayList<Form> lemmaForms = readFormsByLemmaName(language, lemmaName); | |
114 lemma.setForms(lemmaForms); | |
115 lemmas.put(lemmaKey, lemma); | |
116 } else { | |
117 lemma = localLemma; | |
118 } | |
119 formLemmasHashtable.put(lemmaKey, lemma); | |
120 } | |
121 forms.put(key, formLemmasHashtable); | |
122 } | |
123 } | |
124 retFormLemmas = new ArrayList<Lemma>(); | |
125 if (formLemmasHashtable != null) { | |
126 Enumeration<String> formLemmasKeys = formLemmasHashtable.keys(); | |
127 while(formLemmasKeys.hasMoreElements()) { | |
128 String lemmaKey = formLemmasKeys.nextElement(); | |
129 Lemma l = formLemmasHashtable.get(lemmaKey); | |
130 retFormLemmas.add(l); | |
131 } | |
132 } | |
133 Collections.sort(retFormLemmas); | |
134 return retFormLemmas; | |
135 } | |
136 | |
20
7d6d969b10cf
little corrections
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
19
diff
changeset
|
137 public Lemma getLemma(String lang, String lemmaNameArg, int normMode) throws ApplicationException { |
19 | 138 String language = Language.getInstance().getLanguageId(lang); |
139 String lemmaName = lemmaNameArg; | |
20
7d6d969b10cf
little corrections
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
19
diff
changeset
|
140 Normalizer normalizer = new Normalizer(language); |
7d6d969b10cf
little corrections
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
19
diff
changeset
|
141 normalizer.setNormMode(normMode); |
7d6d969b10cf
little corrections
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
19
diff
changeset
|
142 lemmaName = normalizer.normalize(lemmaNameArg); |
19 | 143 // first look in local cache |
144 String key = language + "###" + lemmaName; | |
145 Lemma lemma = lemmas.get(key); | |
146 if (lemma == null) { | |
147 ArrayList<Form> dbLemmaForms = readFormsByLemmaName(language, lemmaName); | |
148 if (dbLemmaForms != null && dbLemmaForms.size() > 0) { | |
149 lemma = new Lemma(); | |
150 lemma.setLemmaName(lemmaName); | |
151 lemma.setLanguage(language); | |
152 lemma.setProvider(dbLemmaForms.get(0).getProvider()); | |
153 lemma.setForms(dbLemmaForms); | |
154 lemmas.put(lemmaName, lemma); | |
155 } | |
156 } | |
157 return lemma; | |
158 } | |
159 | |
20
7d6d969b10cf
little corrections
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
19
diff
changeset
|
160 public ArrayList<Form> getFormsByLuceneQuery(String lang, String luceneQueryString, int normMode) throws ApplicationException { |
19 | 161 String language = Language.getInstance().getLanguageId(lang); |
162 ArrayList<Form> result = new ArrayList<Form>(); | |
163 luceneQueryString = luceneQueryString.toLowerCase(); | |
164 ArrayList<String> formsFromQuery = getVariantsFromLuceneQuery(luceneQueryString); | |
165 if (! (formsFromQuery == null || formsFromQuery.isEmpty())) { | |
166 for (int i=0; i<formsFromQuery.size(); i++) { | |
167 String formStr = formsFromQuery.get(i); | |
20
7d6d969b10cf
little corrections
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
19
diff
changeset
|
168 Normalizer normalizer = new Normalizer(language); |
7d6d969b10cf
little corrections
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
19
diff
changeset
|
169 normalizer.setNormMode(normMode); |
7d6d969b10cf
little corrections
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
19
diff
changeset
|
170 formStr = normalizer.normalize(formStr); |
19 | 171 ArrayList<Lemma> formLemmas = null; |
172 // lemma mode: if formName contains "lemmalemma" then the lemma itself is fetched | |
173 if (formStr.startsWith("lemmalemma")) { | |
174 formLemmas = new ArrayList<Lemma>(); | |
175 String lemmaName = formStr.substring(10); | |
20
7d6d969b10cf
little corrections
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
19
diff
changeset
|
176 Lemma lemma = getLemma(language, lemmaName, Normalizer.NONE); |
19 | 177 formLemmas.add(lemma); |
178 } else { | |
20
7d6d969b10cf
little corrections
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
19
diff
changeset
|
179 formLemmas = getLemmasByFormName(language, formStr, normMode); |
19 | 180 } |
181 if (formLemmas != null && ! formLemmas.isEmpty()) { | |
182 for (int j=0; j<formLemmas.size(); j++) { | |
183 Lemma l = formLemmas.get(j); | |
184 ArrayList<Form> lemmaForms = l.getFormsList(); | |
185 result.addAll(lemmaForms); | |
186 } | |
187 } | |
188 } | |
189 } | |
190 return result; | |
191 } | |
192 | |
20
7d6d969b10cf
little corrections
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
19
diff
changeset
|
193 public ArrayList<Lemma> getLemmasByLuceneQuery(String lang, String luceneQueryString, int normMode) throws ApplicationException { |
19 | 194 String language = Language.getInstance().getLanguageId(lang); |
195 Hashtable<String, Lemma> lemmas = new Hashtable<String, Lemma>(); | |
196 luceneQueryString = luceneQueryString.toLowerCase(); | |
197 ArrayList<String> formsFromQuery = getVariantsFromLuceneQuery(luceneQueryString); | |
198 if (! (formsFromQuery == null || formsFromQuery.isEmpty())) { | |
199 for (int i=0; i<formsFromQuery.size(); i++) { | |
200 String formStr = formsFromQuery.get(i); | |
20
7d6d969b10cf
little corrections
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
19
diff
changeset
|
201 Normalizer normalizer = new Normalizer(language); |
7d6d969b10cf
little corrections
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
19
diff
changeset
|
202 normalizer.setNormMode(normMode); |
7d6d969b10cf
little corrections
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
19
diff
changeset
|
203 formStr = normalizer.normalize(formStr); |
19 | 204 ArrayList<Lemma> formLemmas = null; |
205 // lemma mode: if formName starts with "lemmalemma" then the lemma itself is fetched | |
206 if (formStr.startsWith("lemmalemma")) { | |
207 formLemmas = new ArrayList<Lemma>(); | |
208 String lemmaName = formStr.substring(10); | |
20
7d6d969b10cf
little corrections
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
19
diff
changeset
|
209 Lemma lemma = getLemma(language, lemmaName, Normalizer.NONE); |
19 | 210 formLemmas.add(lemma); |
211 } else { | |
20
7d6d969b10cf
little corrections
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
19
diff
changeset
|
212 formLemmas = getLemmasByFormName(language, formStr, normMode); |
19 | 213 } |
214 if (formLemmas != null) { | |
215 for (int j=0; j<formLemmas.size(); j++) { | |
216 Lemma lemma = formLemmas.get(j); | |
217 lemmas.put(lemma.getLemmaName(), lemma); | |
218 } | |
219 } | |
220 } | |
221 } | |
222 ArrayList<Lemma> result = new ArrayList<Lemma>(); | |
223 if (lemmas != null) { | |
224 Enumeration<String> formLemmasKeys = lemmas.keys(); | |
225 while(formLemmasKeys.hasMoreElements()) { | |
226 String lemmaKey = formLemmasKeys.nextElement(); | |
227 Lemma l = lemmas.get(lemmaKey); | |
228 result.add(l); | |
229 } | |
230 } | |
231 Collections.sort(result); | |
232 if (result.isEmpty()) | |
233 return null; | |
234 else | |
235 return result; | |
236 } | |
237 | |
238 public ArrayList<String> getIndexKeysByLemmaNames(String lang, ArrayList<String> lemmaNames) throws ApplicationException { | |
239 String language = Language.getInstance().getLanguageId(lang); | |
240 Hashtable<String, String> indexKeys = new Hashtable<String, String>(); | |
241 for (int j=0; j<lemmaNames.size(); j++) { | |
242 String lemmaName = lemmaNames.get(j); | |
20
7d6d969b10cf
little corrections
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
19
diff
changeset
|
243 Lemma lemma = getLemma(language, lemmaName, Normalizer.NONE); |
19 | 244 indexKeys.put(lemmaName, lemmaName); |
245 if (lemma != null) { | |
246 ArrayList<Form> lemmaForms = lemma.getFormsList(); | |
247 for (int k=0; k<lemmaForms.size(); k++) { | |
248 Form form = lemmaForms.get(k); | |
20
7d6d969b10cf
little corrections
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
19
diff
changeset
|
249 ArrayList<Lemma> fLemmas = getLemmasByFormName(language, form.getFormName(), Normalizer.NONE); |
19 | 250 if (fLemmas != null) { |
251 String indexKey = ""; | |
252 if (fLemmas.size() == 1) { | |
253 indexKey = fLemmas.get(0).getLemmaName(); | |
254 } else { | |
255 for (int l=0; l<fLemmas.size(); l++) { | |
256 Lemma lem = fLemmas.get(l); | |
257 indexKey = indexKey + "+++" + lem.getLemmaName(); | |
258 } | |
259 indexKeys.put(indexKey, indexKey); | |
260 } | |
261 } | |
262 } | |
263 } | |
264 } | |
265 ArrayList<String> result = new ArrayList<String>(); | |
266 if (indexKeys != null) { | |
267 Enumeration<String> indexKeysKeys = indexKeys.keys(); | |
268 while(indexKeysKeys.hasMoreElements()) { | |
269 String indexKey = indexKeysKeys.nextElement(); | |
270 result.add(indexKey); | |
271 } | |
272 } | |
273 Collections.sort(result); | |
274 if (result.isEmpty()) | |
275 return null; | |
276 else | |
277 return result; | |
278 } | |
279 | |
280 private void clearCache() { | |
281 forms = null; | |
282 lemmas = null; | |
283 forms = new Hashtable<String, Hashtable<String, Lemma>>(); | |
284 lemmas = new Hashtable<String, Lemma>(); | |
285 } | |
286 | |
287 private ArrayList<Lemma> readLemmasByFormName(String lang, String formName) throws ApplicationException { | |
288 String language = Language.getInstance().getLanguageId(lang); | |
23
e845310098ba
diverse Korrekturen
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
20
diff
changeset
|
289 ArrayList<Lemma> lemmasStatic = dbMorphHandler.readLemmas(language, formName); |
19 | 290 return lemmasStatic; |
291 } | |
292 | |
293 private ArrayList<Form> readFormsByLemmaName(String lang, String lemmaName) throws ApplicationException { | |
294 String language = Language.getInstance().getLanguageId(lang); | |
23
e845310098ba
diverse Korrekturen
Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
parents:
20
diff
changeset
|
295 ArrayList<Form> formsStatic = dbMorphHandler.readForms(language, lemmaName); |
19 | 296 return formsStatic; |
297 } | |
298 | |
299 private ArrayList<String> getVariantsFromLuceneQuery(String queryString) { | |
300 LuceneUtil luceneUtil = LuceneUtil.getInstance(); | |
301 ArrayList<String> variants = luceneUtil.getVariantsFromLuceneQuery(queryString); | |
302 return variants; | |
303 } | |
304 | |
305 private void beginOperation() { | |
306 beginOfOperation = new Date(); | |
307 } | |
308 | |
309 private void endOperation() { | |
310 endOfOperation = new Date(); | |
311 } | |
312 } |