3a70b7e505a27fe660c4452d03e9ff6042797187
[debian/openrocket] / core / src / net / sf / openrocket / startup / ConcurrentComponentPresetDatabaseLoader.java
1 package net.sf.openrocket.startup;
2
3 import java.io.InputStream;
4 import java.util.Collection;
5 import java.util.concurrent.CountDownLatch;
6 import java.util.concurrent.ExecutorService;
7 import java.util.concurrent.Executors;
8 import java.util.concurrent.ThreadFactory;
9 import java.util.concurrent.TimeUnit;
10
11 import net.sf.openrocket.database.ComponentPresetDatabase;
12 import net.sf.openrocket.file.iterator.DirectoryIterator;
13 import net.sf.openrocket.file.iterator.FileIterator;
14 import net.sf.openrocket.gui.util.SimpleFileFilter;
15 import net.sf.openrocket.logging.LogHelper;
16 import net.sf.openrocket.preset.ComponentPreset;
17 import net.sf.openrocket.preset.xml.OpenRocketComponentLoader;
18 import net.sf.openrocket.util.Pair;
19
20 public class ConcurrentComponentPresetDatabaseLoader {
21
22         private static final LogHelper log = Application.getLogger();
23         private static final String SYSTEM_PRESET_DIR = "datafiles/presets";
24
25         private final CountDownLatch latch = new CountDownLatch(1);
26
27         private final ComponentPresetDatabase componentPresetDao;
28
29         private final ExecutorService writerPool;
30
31         private final ExecutorService loaderPool;
32
33         private final Thread workGenerator;
34
35         private FileIterator iterator;
36
37         private long startTime;
38         private long fileCount = 0;
39         private long presetCount = 0;
40
41         ConcurrentComponentPresetDatabaseLoader( ComponentPresetDatabase componentPresetDao ) {
42                 this.componentPresetDao = componentPresetDao;
43
44                 writerPool = Executors.newSingleThreadExecutor(new ThreadFactory() {
45                         @Override
46                         public Thread newThread(Runnable r) {
47                                 Thread t = new Thread(r,"PresetWriterThread");
48                                 return t;
49                         }
50                 });
51
52                 loaderPool = Executors.newFixedThreadPool(3, new ThreadFactory() {
53                         int threadCount = 0;
54                         @Override
55                         public Thread newThread(Runnable r) {
56                                 Thread t = new Thread(r,"PresetLoaderPool-" + threadCount++);
57                                 return t;
58                         }
59
60                 });
61
62                 workGenerator = new Thread( new WorkGenerator(),"PresetGeneratorThread");
63         }
64
65         public void load() {
66                 startTime = System.currentTimeMillis();
67                 workGenerator.start();
68         }
69
70         public void await() throws InterruptedException {
71                 latch.await();
72                 loaderPool.shutdown();
73                 loaderPool.awaitTermination(90, TimeUnit.SECONDS);
74                 writerPool.shutdown();
75                 writerPool.awaitTermination(90, TimeUnit.SECONDS);
76                 if ( iterator != null ) {
77                         iterator.close();
78                 }
79                 long end = System.currentTimeMillis();
80                 log.debug("Time to load presets: " + (end-startTime) + "ms " + presetCount + " loaded from " + fileCount + " files");
81         }
82
83
84         private class WorkGenerator implements Runnable {
85                 @Override
86                 public void run() {
87                         // Start loading
88                         log.info("Loading component presets from " + SYSTEM_PRESET_DIR);
89
90                         iterator = DirectoryIterator.findDirectory(SYSTEM_PRESET_DIR,
91                                         new SimpleFileFilter("", false, "orc"));
92
93                         if (iterator != null) {
94                                 while( iterator.hasNext() ) {
95                                         Pair<String,InputStream> f = iterator.next();
96                                         FileLoader loader = new FileLoader( f.getV(), f.getU() );
97                                         loaderPool.execute(loader);
98                                         fileCount ++;
99                                 }
100                         }
101                         latch.countDown();
102                 }
103         }
104
105         private class FileLoader implements Runnable {
106                 private final InputStream is;
107                 private final String fileName;
108
109                 public FileLoader(InputStream is, String fileName) {
110                         super();
111                         this.is = is;
112                         this.fileName = fileName;
113                 }
114
115                 @Override
116                 public void run() {
117                         OpenRocketComponentLoader loader = new OpenRocketComponentLoader();
118                         Collection<ComponentPreset> presets = loader.load(is, fileName);
119                         PresetWriter writer = new PresetWriter(presets);
120                         writerPool.execute(writer);
121                 }               
122         }
123
124         private class PresetWriter implements Runnable {
125                 private final Collection<ComponentPreset> presets;
126
127                 public PresetWriter(Collection<ComponentPreset> presets) {
128                         super();
129                         this.presets = presets;
130                 }
131
132                 @Override
133                 public void run() {
134                         presetCount += presets.size();
135                         componentPresetDao.addAll(presets);
136                 }
137
138         }
139 }