OSDN Git Service

Split database into 3 pieces to try and reduce the possibility of database corruption.
[neighbornote/NeighborNote.git] / src / cx / fbn / nevernote / threads / CounterRunner.java
1 /*\r
2  * This file is part of NeverNote \r
3  * Copyright 2009 Randy Baumgarte\r
4  * \r
5  * This file may be licensed under the terms of of the\r
6  * GNU General Public License Version 2 (the ``GPL'').\r
7  *\r
8  * Software distributed under the License is distributed\r
9  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either\r
10  * express or implied. See the GPL for the specific language\r
11  * governing rights and limitations.\r
12  *\r
13  * You should have received a copy of the GPL along with this\r
14  * program. If not, go to http://www.gnu.org/licenses/gpl.html\r
15  * or write to the Free Software Foundation, Inc.,\r
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
17  *\r
18 */\r
19 \r
20 package cx.fbn.nevernote.threads;\r
21 \r
22 import java.util.ArrayList;\r
23 import java.util.List;\r
24 import java.util.Vector;\r
25 import java.util.concurrent.LinkedBlockingQueue;\r
26 \r
27 import com.evernote.edam.type.Note;\r
28 import com.evernote.edam.type.Notebook;\r
29 import com.evernote.edam.type.Tag;\r
30 import com.trolltech.qt.core.QMutex;\r
31 import com.trolltech.qt.core.QObject;\r
32 \r
33 import cx.fbn.nevernote.Global;\r
34 import cx.fbn.nevernote.filters.NotebookCounter;\r
35 import cx.fbn.nevernote.filters.TagCounter;\r
36 import cx.fbn.nevernote.signals.NotebookSignal;\r
37 import cx.fbn.nevernote.signals.TagSignal;\r
38 import cx.fbn.nevernote.signals.TrashSignal;\r
39 import cx.fbn.nevernote.sql.DatabaseConnection;\r
40 import cx.fbn.nevernote.utilities.ApplicationLogger;\r
41 import cx.fbn.nevernote.utilities.Pair;\r
42 \r
43 public class CounterRunner extends QObject implements Runnable {\r
44          \r
45         private final ApplicationLogger         logger;\r
46         private volatile boolean                        keepRunning;\r
47         public int                                                      ID;\r
48         public volatile NotebookSignal          notebookSignal;\r
49         public volatile TrashSignal                     trashSignal;\r
50         public volatile TagSignal                       tagSignal;\r
51         private volatile Vector<String>         notebookIndex;\r
52         private volatile Vector<String>         noteIndex;\r
53         private volatile Vector<Boolean>        activeIndex;\r
54         public int                                                      type;\r
55         public QMutex                                           threadLock;\r
56         \r
57         public static int                                       EXIT=0;\r
58         public static int                                       NOTEBOOK=1;\r
59         public static int                                       TAG=2;\r
60         public static int                                       TRASH=3;\r
61         public static int                                       TAG_ALL = 4;\r
62         public static int                                       NOTEBOOK_ALL = 5;\r
63         \r
64         public boolean                                          ready = false;\r
65         public boolean                                          abortCount = false;\r
66         private final DatabaseConnection                                        conn;\r
67 \r
68         private volatile LinkedBlockingQueue<Integer> readyQueue = new LinkedBlockingQueue<Integer>();\r
69         \r
70         \r
71         //*********************************************\r
72         //* Constructor                               *\r
73         //*********************************************\r
74         public CounterRunner(String logname, int t, String u, String i, String r, String uid, String pswd, String cpswd) {\r
75                 type = t;\r
76 \r
77                 threadLock = new QMutex();\r
78                 logger = new ApplicationLogger(logname);\r
79 //              setAutoDelete(false);   \r
80                 conn = new DatabaseConnection(logger, u, i, r, uid, pswd, cpswd, 300);\r
81                 keepRunning = true;\r
82                 notebookSignal = new NotebookSignal();\r
83                 tagSignal = new TagSignal();\r
84                 trashSignal = new TrashSignal();\r
85                 \r
86                 notebookIndex = new Vector<String>();\r
87                 activeIndex = new Vector<Boolean>();\r
88                 noteIndex = new Vector<String>();\r
89         }\r
90         \r
91         \r
92         \r
93         //*********************************************\r
94         //* Run unit                                  *\r
95         //*********************************************\r
96         @Override\r
97         public void run() {\r
98                 boolean keepRunning = true;\r
99                 \r
100                 thread().setPriority(Thread.MIN_PRIORITY);\r
101                 while(keepRunning) {\r
102                         ready = true;\r
103                         try {\r
104                                 \r
105                                 type = readyQueue.take();\r
106                                 threadLock.lock();\r
107                                 if (type == EXIT)\r
108                                         keepRunning = false;\r
109                                 if (type == NOTEBOOK)\r
110                                         countNotebookResults();\r
111                                 if (type == NOTEBOOK_ALL)\r
112                                         countNotebookResults();\r
113                                 if (type == TAG)\r
114                                         countTagResults();\r
115                                 if (type == TAG_ALL)\r
116                                         countTagResults();\r
117                                 if (type == TRASH)\r
118                                         countTrashResults();\r
119                                 threadLock.unlock();\r
120                         } catch (InterruptedException e) {}\r
121                 }\r
122                 conn.dbShutdown();\r
123         }\r
124         \r
125         \r
126         \r
127         public void setNoteIndex(List<Note> idx) {\r
128                 abortCount = true;\r
129                 threadLock.lock();\r
130                 abortCount = false;\r
131                 notebookIndex.clear();\r
132                 activeIndex.clear();\r
133                 noteIndex.clear();\r
134                 if (idx != null) {\r
135                         for (int i=0; i<idx.size(); i++) {\r
136                                 if (Global.showDeleted && !idx.get(i).isActive()) {\r
137                                         notebookIndex.add(new String(idx.get(i).getNotebookGuid()));\r
138                                         noteIndex.add(new String(idx.get(i).getGuid()));\r
139                                         activeIndex.add(new Boolean(idx.get(i).isActive()));\r
140                                 }  \r
141                                 if (!Global.showDeleted && idx.get(i).isActive()) {\r
142                                         notebookIndex.add(new String(idx.get(i).getNotebookGuid()));\r
143                                         noteIndex.add(new String(idx.get(i).getGuid()));\r
144                                         activeIndex.add(new Boolean(idx.get(i).isActive()));                                    \r
145                                 }\r
146                         }\r
147                 }\r
148                 threadLock.unlock();\r
149         }\r
150         public void release(int type) {\r
151                 readyQueue.add(type);\r
152         }\r
153         \r
154         //*********************************************\r
155         //* Getter & Setter method to tell the thread *\r
156         //* to keep running.                          *\r
157         //*********************************************\r
158         public void setKeepRunning(boolean b) {\r
159                 keepRunning = b;\r
160         }\r
161         public boolean keepRunning() {\r
162                 return keepRunning;\r
163         }\r
164         \r
165         \r
166         //*********************************************\r
167         //* Do the actual counting                    *\r
168         //*********************************************\r
169         private void countNotebookResults() {\r
170                 logger.log(logger.EXTREME, "Entering ListManager.countNotebookResults");                \r
171                 if (abortCount)\r
172                         return;\r
173                 List<NotebookCounter> nCounter = new ArrayList<NotebookCounter>();\r
174                 if (abortCount)\r
175                         return;\r
176                 List<Notebook> books = conn.getNotebookTable().getAll();\r
177                                 \r
178                 if (abortCount)\r
179                         return;\r
180 \r
181                 if (type == NOTEBOOK_ALL) {\r
182                         for (int i=0; i<books.size(); i++) {\r
183                                 if (abortCount)\r
184                                         return;\r
185 \r
186                                 nCounter.add(new NotebookCounter());\r
187                                 nCounter.get(i).setCount(0);\r
188                                 nCounter.get(i).setGuid(books.get(i).getGuid());\r
189                         }\r
190                         if (abortCount)\r
191                                 return;\r
192                         List<Pair<String, Integer>> notebookCounts = conn.getNotebookTable().getNotebookCounts();\r
193                         if (abortCount)\r
194                                 return;\r
195                         for (int i=0; notebookCounts != null && i<notebookCounts.size(); i++) {\r
196                                 if (abortCount)\r
197                                         return;\r
198                                 for (int j=0; j<nCounter.size(); j++) {\r
199                                         if (abortCount)\r
200                                                 return;\r
201 \r
202                                         if (notebookCounts.get(i).getFirst().equals(nCounter.get(j).getGuid())) {\r
203                                                 nCounter.get(j).setCount(notebookCounts.get(i).getSecond());\r
204                                                 j=nCounter.size();\r
205                                         }\r
206                                 }\r
207                         }\r
208                         if (abortCount)\r
209                                 return;\r
210 \r
211                         notebookSignal.countsChanged.emit(nCounter);\r
212                         return;\r
213                 }\r
214                 \r
215                 if (abortCount)\r
216                         return;\r
217                 for (int i=notebookIndex.size()-1; i>=0 && keepRunning; i--) {\r
218                         if (abortCount)\r
219                                 return;\r
220                         boolean notebookFound = false;\r
221                         for (int j=0; j<nCounter.size() && keepRunning; j++) {\r
222                                 if (abortCount)\r
223                                         return;\r
224                                 if (nCounter.get(j).getGuid().equals(notebookIndex.get(i))) {\r
225                                         notebookFound = true;\r
226                                         if (activeIndex.get(i)) {\r
227                                                 int c = nCounter.get(j).getCount()+1;\r
228                                                 nCounter.get(j).setCount(c);\r
229                                         }\r
230                                         j=nCounter.size();\r
231                                 }\r
232                         }\r
233                         if (abortCount)\r
234                                 return;\r
235                         if (!notebookFound) {\r
236                                 NotebookCounter newCounter = new NotebookCounter();\r
237                                 newCounter.setGuid(notebookIndex.get(i));\r
238                                 newCounter.setCount(1);\r
239                                 nCounter.add(newCounter);\r
240                         }\r
241                 }\r
242                 if (abortCount)\r
243                         return;\r
244                 notebookSignal.countsChanged.emit(nCounter);\r
245                 logger.log(logger.EXTREME, "Leaving ListManager.countNotebookResults()");\r
246         }\r
247         \r
248         \r
249         private void countTagResults() {\r
250                 logger.log(logger.EXTREME, "Entering ListManager.countTagResults");             \r
251                 List<TagCounter> counter = new ArrayList<TagCounter>();\r
252                 List<Tag> allTags = conn.getTagTable().getAll();\r
253                 \r
254                 if (abortCount) \r
255                         return;\r
256                 if (allTags == null)\r
257                         return;\r
258                 for (int k=0; k<allTags.size() && keepRunning; k++) {\r
259                         TagCounter newCounter = new TagCounter();\r
260                         newCounter.setGuid(allTags.get(k).getGuid());\r
261                         newCounter.setCount(0);\r
262                         counter.add(newCounter);\r
263                 }\r
264                 \r
265                 if (type == TAG_ALL) {\r
266                         List<Pair<String, Integer>> tagCounts = conn.getNoteTable().noteTagsTable.getTagCounts();\r
267                         if (abortCount)\r
268                                 return;\r
269                         for (int i=0; tagCounts != null &&  i<tagCounts.size(); i++) {\r
270                                 if (abortCount)\r
271                                         return;\r
272                                 for (int j=0; j<counter.size(); j++) {\r
273                                         if (abortCount)\r
274                                                 return;\r
275                                         if (tagCounts.get(i).getFirst().equals(counter.get(j).getGuid())) {\r
276                                                 if (abortCount)\r
277                                                         return;\r
278                                                 counter.get(j).setCount(tagCounts.get(i).getSecond());\r
279                                                 j=counter.size();\r
280                                         }\r
281                                 }\r
282                         }\r
283                         if (abortCount)\r
284                                 return;\r
285                         tagSignal.countsChanged.emit(counter);\r
286                         return;\r
287                 }\r
288                 \r
289                 \r
290                 if (abortCount)\r
291                         return;\r
292                 List<cx.fbn.nevernote.sql.NoteTagsRecord> tags = conn.getNoteTable().noteTagsTable.getAllNoteTags();\r
293                 for (int i=noteIndex.size()-1; i>=0; i--) {\r
294                         if (abortCount)\r
295                                 return;\r
296                         String note = noteIndex.get(i);\r
297                         for (int x=0; tags!= null && x<tags.size() && keepRunning; x++) {\r
298                                 if (abortCount)\r
299                                         return;\r
300                                 String tag = tags.get(x).tagGuid;\r
301                                 for (int j=0; j<counter.size() && keepRunning; j++) {\r
302                                         if (abortCount)\r
303                                                 return;\r
304                                         if (counter.get(j).getGuid().equals(tag) && note.equals(tags.get(x).noteGuid)) {\r
305                                                 int c = counter.get(j).getCount()+1;\r
306                                                 counter.get(j).setCount(c);\r
307                                         }\r
308                                 }\r
309                         }\r
310                 }\r
311                 if (abortCount)\r
312                         return;\r
313                 tagSignal.countsChanged.emit(counter);\r
314                 logger.log(logger.EXTREME, "Leaving ListManager.countTagResults()");\r
315         }\r
316         \r
317         \r
318         private void countTrashResults() {\r
319                 logger.log(logger.EXTREME, "Entering CounterRunner.countTrashResults()");               \r
320                 if (abortCount)\r
321                         return;\r
322 \r
323                 Integer tCounter = conn.getNoteTable().getDeletedCount();\r
324                 \r
325                 if (abortCount)\r
326                         return;\r
327 \r
328                 trashSignal.countChanged.emit(tCounter);\r
329                 logger.log(logger.EXTREME, "Leaving CounterRunner.countTrashResults()");\r
330         }\r
331 \r
332 }\r