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