1   package eu.fbk.dh.tint.inverse.digimorph.annotator;
2   
3   import com.google.common.collect.Lists;
4   import com.google.common.io.Resources;
5   import org.mapdb.Serializer;
6   import org.mapdb.SortedTableMap;
7   import org.mapdb.volume.MappedFileVol;
8   import org.mapdb.volume.Volume;
9   import org.slf4j.Logger;
10  import org.slf4j.LoggerFactory;
11  
12  import java.io.File;
13  import java.io.IOException;
14  import java.nio.file.Files;
15  import java.util.*;
16  import java.util.concurrent.*;
17  
18  /**
19   * Created by giovannimoretti on 31/01/17.
20   */
21  
22  public class InverseDigiMorph {
23  
24      String model_path = "";
25      ExecutorService executor = null;
26      List<Future<List<String>>> futures = null;
27  
28      Set<Callable<List<String>>> callables = new HashSet<Callable<List<String>>>();
29      Volume volume = null;
30      SortedTableMap<String, String> map = null;
31  
32      private static final Logger LOGGER = LoggerFactory
33              .getLogger(eu.fbk.dh.tint.inverse.digimorph.annotator.InverseDigiMorph.class);
34  
35      public InverseDigiMorph() {
36          this(null);
37      }
38  
39      public InverseDigiMorph(String model_path) {
40          if (model_path == null) {
41              try {
42                  File file = File.createTempFile("mapdb", "mapdb");
43                  file.deleteOnExit();
44                  byte[] bytes = Resources.toByteArray(Resources.getResource("inverse-italian.db"));
45                  Files.write(file.toPath(), bytes);
46                  model_path = file.getAbsolutePath();
47              } catch (IOException e) {
48                  e.printStackTrace();
49              }
50          }
51  
52          this.model_path = model_path;
53          volume = MappedFileVol.FACTORY.makeVolume(model_path, true);
54          this.map = SortedTableMap.open(volume, Serializer.STRING, Serializer.STRING);
55  
56      }
57  
58      /**
59       * @param morphology string containing morphologies in EAGLE format.
60       * @return result of the Inverse Morphological analyzer.
61       * @author Giovanni Moretti
62       * @version 0.42a
63       */
64  
65      synchronized public String getInverseMorphology(String morphology) {
66          List token_list = new ArrayList();
67          token_list.add(morphology);
68          List<String> inverseMorphology = getInverseMorphology(token_list);
69          return inverseMorphology.get(0);
70      }
71  
72      /**
73       * @param morpho_list list of string containing morphologies in EAGLE format.
74       * @return list of string containing the results of the Inverse Morphological analyzer.
75       * @author Giovanni Moretti
76       * @version 0.42a
77       */
78  
79      synchronized public List<String> getInverseMorphology(List morpho_list) {
80          List<String> results = new LinkedList<String>();
81          List<List<String>> parts;
82          int threadsNumber = Runtime.getRuntime().availableProcessors();
83          //int threadsNumber = 1;
84          parts = Lists.partition(morpho_list, (morpho_list.size() / threadsNumber) + 1);
85  
86          if (morpho_list.size() > 0) {
87              executor = Executors.newFixedThreadPool(parts.size());
88          } else {
89              LOGGER.warn("No tokens to the morphological analyzer");
90              return results;
91          }
92  
93          callables = new LinkedHashSet<Callable<List<String>>>();
94  
95          for (int pts = 0; pts < parts.size(); pts++) {
96              callables.add(new InverseDigiMorph_Analizer(parts.get(pts), map));
97          }
98  
99          try {
100             futures = executor.invokeAll(callables);
101             executor.shutdown();
102             executor.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS);
103             executor.shutdownNow();
104         } catch (Exception e) {
105             e.printStackTrace();
106         }
107 
108         try {
109             for (int i = 0; i < futures.size(); i++) {
110                 List<String> stringList = futures.get(i).get();
111                 results.addAll(stringList);
112             }
113         } catch (Exception e) {
114             e.printStackTrace();
115         }
116         for (int pts = 0; pts < parts.size(); pts++) {
117             parts.get(pts).clear();
118         }
119 
120         return results;
121     }
122 
123 }