View Javadoc

1   package net.obsearch.storage.bdb;
2   /*
3    OBSearch: a distributed similarity search engine This project is to
4    similarity search what 'bit-torrent' is to downloads. 
5    Copyright (C) 2008 Arnoldo Jose Muller Molina
6   
7    This program is free software: you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation, either version 3 of the License, or
10   (at your option) any later version.
11  
12   This program is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16  
17   You should have received a copy of the GNU General Public License
18   along with this program.  If not, see <http://www.gnu.org/licenses/>.
19   */
20  import java.io.File;
21  import java.io.IOException;
22  import java.io.FileNotFoundException;
23  import java.math.BigInteger;
24  
25  import net.obsearch.asserts.OBAsserts;
26  import net.obsearch.exception.OBStorageException;
27  import net.obsearch.exception.OBException;
28  import net.obsearch.storage.OBStorageConfig.IndexType;
29  import net.obsearch.storage.OBStore;
30  import net.obsearch.storage.OBStorageConfig;
31  import net.obsearch.constants.OBSearchProperties;
32  
33  
34  
35  import net.obsearch.storage.OBStoreByte;
36  
37  import net.obsearch.storage.OBStoreShort;
38  
39  import net.obsearch.storage.OBStoreInt;
40  
41  import net.obsearch.storage.OBStoreLong;
42  
43  import net.obsearch.storage.OBStoreFloat;
44  
45  import net.obsearch.storage.OBStoreDouble;
46  
47  
48  
49  import net.obsearch.storage.TupleBytes;
50  import net.obsearch.storage.OBStoreFactory;
51  
52  import com.sleepycat.je.Database;
53  import com.sleepycat.je.DatabaseConfig;
54  import com.sleepycat.je.DatabaseException;
55  import com.sleepycat.je.Environment;
56  import com.sleepycat.je.EnvironmentConfig;
57  import com.sleepycat.bind.tuple.*;
58  import com.sleepycat.je.DatabaseEntry;
59  
60  
61  
62  import java.io.File;
63  import org.apache.log4j.Logger;
64  
65  /**
66   * BDBFactory generates an environment in the given directory, and creates
67   * databases as OBSearch requests.
68   * @author Arnoldo Jose Muller Molina
69   */
70  
71  public final class BDBFactoryJe implements OBStoreFactory {
72  		/*
73  			  je
74       */
75  		/**
76  		 * Logger.
77  		 */
78  		private static final transient Logger logger = Logger
79  			.getLogger(BDBFactoryJe.class);
80  
81  		private String directory;
82  
83      /**
84       * The environment.
85       */
86      private Environment env;
87  
88      /**
89       * Creates a new factory that will be based in the given directory.
90       * @param directory
91       *                The directory where the Berkeley DB files will be stored.
92       * @throws IOException
93       *                 If the given directory does not exist.
94       */
95      public BDBFactoryJe(File directory) throws IOException, DatabaseException, OBStorageException 	 {
96  				this.directory = directory.getAbsolutePath();
97  				logger.debug("Factory created on dir: " + directory);
98          directory.mkdirs();
99          OBAsserts.chkFileExists(directory);
100         EnvironmentConfig envConfig = createEnvConfig();
101         env = new Environment(directory, envConfig);
102 				if(logger.isDebugEnabled()){
103 								logger.debug("Environment config: \n" + env.getConfig().toString());
104 								logger.debug("Buffer size " + env.getConfig().getConfigParam("je.log.bufferSize"));
105 								logger.debug("Cache % " + env.getConfig().getConfigParam("je.maxMemoryPercent"));
106 								
107 				}
108     }
109 
110 		public String getFactoryLocation(){
111 				return directory;
112 		}
113     
114     /**
115      * Creates the default environment configuration.
116      * @return Default environment configuration.
117      */
118     private EnvironmentConfig createEnvConfig() 	{
119         /* Open a transactional Oracle Berkeley DB Environment. */
120         EnvironmentConfig envConfig = new EnvironmentConfig();
121         envConfig.setAllowCreate(true);
122         envConfig.setTransactional(false);
123         envConfig.setConfigParam("java.util.logging.DbLogHandler.on", "false");
124 				envConfig.setLocking(false);
125 				envConfig.setTxnNoSync(true);
126         //envConfig.setTxnWriteNoSync(true);
127 				// envConfig.setCachePercent(20);
128 				// 100 k gave the best performance in one thread and for 30 pivots of
129         // shorts
130 				
131 				//						envConfig.setConfigParam("je.log.faultReadSize", "140000");	 
132 				//    envConfig.setConfigParam("je.evictor.lruOnly", "false");
133         //    envConfig.setConfigParam("je.evictor.nodesPerScan", "100");
134         return envConfig;
135     }
136 
137     public void close() throws OBStorageException {
138         try {
139             env.cleanLog();
140             env.compress();
141             env.checkpoint(null);
142  
143             env.close();
144         } catch (DatabaseException e) {
145             throw new OBStorageException(e);
146         }
147     }
148 
149     public OBStore<TupleBytes> createOBStore(String name, OBStorageConfig config) throws OBStorageException{       
150 
151         OBStore res = null;
152 				
153        
154         try{
155 
156 DatabaseConfig dbConfig = createDefaultDatabaseConfig();
157 				boolean temp = config.isTemp();
158 				boolean bulkMode = config.isBulkMode();
159 				boolean duplicates = config.isDuplicates();							 
160 								
161 								// bulk mode has priority over deferred write.
162 										 dbConfig.setSortedDuplicates(duplicates);
163 								if(bulkMode){
164 										dbConfig.setDeferredWrite(bulkMode);										
165 								}else{
166 //										dbConfig.setTemporary(temp);
167 								}
168 								
169 											Database seq = null;
170 						if(!duplicates){
171 								seq = env.openDatabase(null,  sequentialDatabaseName(name), dbConfig)
172 ;
173 						}
174         
175 						res = new BDBOBStoreJeByteArray(name, env.openDatabase(null, name, dbConfig)
176  , seq, this, duplicates);
177 					
178         }catch(DatabaseException e){
179             throw new OBStorageException(e);
180         }
181        return res;
182     }
183 
184 		/**
185 	 * Generate the name of the sequential database based on name.
186 	 * @param name The name of the database.
187 	 * @return The sequential database name.
188 	 */
189 	private String sequentialDatabaseName(String name){
190 		return name + "seq";
191 	}
192 
193     
194     /**
195      * Creates a default database configuration.
196      * @return default database configuration.
197      */
198     protected DatabaseConfig createDefaultDatabaseConfig() {
199         DatabaseConfig dbConfig = new DatabaseConfig();
200         dbConfig = new DatabaseConfig();
201         dbConfig.setTransactional(false);
202         dbConfig.setAllowCreate(true);
203 						 
204         return dbConfig;
205     }
206 
207 		public void removeOBStore(OBStore storage) throws OBStorageException{
208 						storage.close();
209 						try{
210 						env.removeDatabase(null, storage.getName());
211 						env.removeDatabase(null, sequentialDatabaseName(storage.getName()));
212 						}catch(DatabaseException e){
213 								throw new OBStorageException(e);
214 						}
215 				}
216 
217 
218 				
219 				
220 
221 				public OBStoreByte createOBStoreByte(String name, OBStorageConfig config) throws OBStorageException{
222         
223         OBStoreByte res = null;
224         try{
225             
226 DatabaseConfig dbConfig = createDefaultDatabaseConfig();
227 				boolean temp = config.isTemp();
228 				boolean bulkMode = config.isBulkMode();
229 				boolean duplicates = config.isDuplicates();							 
230 								
231 								// bulk mode has priority over deferred write.
232 										 dbConfig.setSortedDuplicates(duplicates);
233 								if(bulkMode){
234 										dbConfig.setDeferredWrite(bulkMode);										
235 								}else{
236 //										dbConfig.setTemporary(temp);
237 								}
238 								
239 											Database seq = null;
240 						if(!duplicates){
241 								seq = env.openDatabase(null,  sequentialDatabaseName(name), dbConfig)
242 ;
243 						}
244         
245 						res = new BDBOBStoreJeByte(name, env.openDatabase(null, name, dbConfig)
246  , seq, this, duplicates);
247 								
248         }catch(DatabaseException e){
249             throw new OBStorageException(e);
250         }
251        return res;
252     }
253 
254 		
255 		public  byte[] serializeByte(byte value){
256 				return BDBFactoryJe.byteToBytes(value);
257 		}
258 
259 
260 		public byte deSerializeByte(byte[] value){
261 				DatabaseEntry entry = new DatabaseEntry(value);
262 				return ByteBinding.entryToByte(entry);
263 		}
264 
265 		public static byte[] byteToBytes(byte value){
266 				DatabaseEntry entry = new DatabaseEntry();
267 				ByteBinding.byteToEntry(value, entry);
268 				assert entry.getData().length == net.obsearch.constants.ByteConstants.Byte.getSize();
269 				return entry.getData();
270 		}
271 
272 		public static byte bytesToByte(byte[] value){
273 				DatabaseEntry entry = new DatabaseEntry(value);
274 				return ByteBinding.entryToByte(entry);
275 		}
276 
277 
278 				
279 				
280 
281 				public OBStoreShort createOBStoreShort(String name, OBStorageConfig config) throws OBStorageException{
282         
283         OBStoreShort res = null;
284         try{
285             
286 DatabaseConfig dbConfig = createDefaultDatabaseConfig();
287 				boolean temp = config.isTemp();
288 				boolean bulkMode = config.isBulkMode();
289 				boolean duplicates = config.isDuplicates();							 
290 								
291 								// bulk mode has priority over deferred write.
292 										 dbConfig.setSortedDuplicates(duplicates);
293 								if(bulkMode){
294 										dbConfig.setDeferredWrite(bulkMode);										
295 								}else{
296 //										dbConfig.setTemporary(temp);
297 								}
298 								
299 											Database seq = null;
300 						if(!duplicates){
301 								seq = env.openDatabase(null,  sequentialDatabaseName(name), dbConfig)
302 ;
303 						}
304         
305 						res = new BDBOBStoreJeShort(name, env.openDatabase(null, name, dbConfig)
306  , seq, this, duplicates);
307 								
308         }catch(DatabaseException e){
309             throw new OBStorageException(e);
310         }
311        return res;
312     }
313 
314 		
315 		public  byte[] serializeShort(short value){
316 				return BDBFactoryJe.shortToBytes(value);
317 		}
318 
319 
320 		public short deSerializeShort(byte[] value){
321 				DatabaseEntry entry = new DatabaseEntry(value);
322 				return ShortBinding.entryToShort(entry);
323 		}
324 
325 		public static byte[] shortToBytes(short value){
326 				DatabaseEntry entry = new DatabaseEntry();
327 				ShortBinding.shortToEntry(value, entry);
328 				assert entry.getData().length == net.obsearch.constants.ByteConstants.Short.getSize();
329 				return entry.getData();
330 		}
331 
332 		public static short bytesToShort(byte[] value){
333 				DatabaseEntry entry = new DatabaseEntry(value);
334 				return ShortBinding.entryToShort(entry);
335 		}
336 
337 
338 				
339 				
340 
341 				public OBStoreInt createOBStoreInt(String name, OBStorageConfig config) throws OBStorageException{
342         
343         OBStoreInt res = null;
344         try{
345             
346 DatabaseConfig dbConfig = createDefaultDatabaseConfig();
347 				boolean temp = config.isTemp();
348 				boolean bulkMode = config.isBulkMode();
349 				boolean duplicates = config.isDuplicates();							 
350 								
351 								// bulk mode has priority over deferred write.
352 										 dbConfig.setSortedDuplicates(duplicates);
353 								if(bulkMode){
354 										dbConfig.setDeferredWrite(bulkMode);										
355 								}else{
356 //										dbConfig.setTemporary(temp);
357 								}
358 								
359 											Database seq = null;
360 						if(!duplicates){
361 								seq = env.openDatabase(null,  sequentialDatabaseName(name), dbConfig)
362 ;
363 						}
364         
365 						res = new BDBOBStoreJeInt(name, env.openDatabase(null, name, dbConfig)
366  , seq, this, duplicates);
367 								
368         }catch(DatabaseException e){
369             throw new OBStorageException(e);
370         }
371        return res;
372     }
373 
374 		
375 		public  byte[] serializeInt(int value){
376 				return BDBFactoryJe.intToBytes(value);
377 		}
378 
379 
380 		public int deSerializeInt(byte[] value){
381 				DatabaseEntry entry = new DatabaseEntry(value);
382 				return IntegerBinding.entryToInt(entry);
383 		}
384 
385 		public static byte[] intToBytes(int value){
386 				DatabaseEntry entry = new DatabaseEntry();
387 				IntegerBinding.intToEntry(value, entry);
388 				assert entry.getData().length == net.obsearch.constants.ByteConstants.Int.getSize();
389 				return entry.getData();
390 		}
391 
392 		public static int bytesToInt(byte[] value){
393 				DatabaseEntry entry = new DatabaseEntry(value);
394 				return IntegerBinding.entryToInt(entry);
395 		}
396 
397 
398 				
399 				
400 
401 				public OBStoreLong createOBStoreLong(String name, OBStorageConfig config) throws OBStorageException{
402         
403         OBStoreLong res = null;
404         try{
405             
406 DatabaseConfig dbConfig = createDefaultDatabaseConfig();
407 				boolean temp = config.isTemp();
408 				boolean bulkMode = config.isBulkMode();
409 				boolean duplicates = config.isDuplicates();							 
410 								
411 								// bulk mode has priority over deferred write.
412 										 dbConfig.setSortedDuplicates(duplicates);
413 								if(bulkMode){
414 										dbConfig.setDeferredWrite(bulkMode);										
415 								}else{
416 //										dbConfig.setTemporary(temp);
417 								}
418 								
419 											Database seq = null;
420 						if(!duplicates){
421 								seq = env.openDatabase(null,  sequentialDatabaseName(name), dbConfig)
422 ;
423 						}
424         
425 						res = new BDBOBStoreJeLong(name, env.openDatabase(null, name, dbConfig)
426  , seq, this, duplicates);
427 								
428         }catch(DatabaseException e){
429             throw new OBStorageException(e);
430         }
431        return res;
432     }
433 
434 		
435 		public  byte[] serializeLong(long value){
436 				return BDBFactoryJe.longToBytes(value);
437 		}
438 
439 
440 		public long deSerializeLong(byte[] value){
441 				DatabaseEntry entry = new DatabaseEntry(value);
442 				return LongBinding.entryToLong(entry);
443 		}
444 
445 		public static byte[] longToBytes(long value){
446 				DatabaseEntry entry = new DatabaseEntry();
447 				LongBinding.longToEntry(value, entry);
448 				assert entry.getData().length == net.obsearch.constants.ByteConstants.Long.getSize();
449 				return entry.getData();
450 		}
451 
452 		public static long bytesToLong(byte[] value){
453 				DatabaseEntry entry = new DatabaseEntry(value);
454 				return LongBinding.entryToLong(entry);
455 		}
456 
457 
458 				
459 				
460 
461 				public OBStoreFloat createOBStoreFloat(String name, OBStorageConfig config) throws OBStorageException{
462         
463         OBStoreFloat res = null;
464         try{
465             
466 DatabaseConfig dbConfig = createDefaultDatabaseConfig();
467 				boolean temp = config.isTemp();
468 				boolean bulkMode = config.isBulkMode();
469 				boolean duplicates = config.isDuplicates();							 
470 								
471 								// bulk mode has priority over deferred write.
472 										 dbConfig.setSortedDuplicates(duplicates);
473 								if(bulkMode){
474 										dbConfig.setDeferredWrite(bulkMode);										
475 								}else{
476 //										dbConfig.setTemporary(temp);
477 								}
478 								
479 											Database seq = null;
480 						if(!duplicates){
481 								seq = env.openDatabase(null,  sequentialDatabaseName(name), dbConfig)
482 ;
483 						}
484         
485 						res = new BDBOBStoreJeFloat(name, env.openDatabase(null, name, dbConfig)
486  , seq, this, duplicates);
487 								
488         }catch(DatabaseException e){
489             throw new OBStorageException(e);
490         }
491        return res;
492     }
493 
494 		
495 		public  byte[] serializeFloat(float value){
496 				return BDBFactoryJe.floatToBytes(value);
497 		}
498 
499 
500 		public float deSerializeFloat(byte[] value){
501 				DatabaseEntry entry = new DatabaseEntry(value);
502 				return SortedFloatBinding.entryToFloat(entry);
503 		}
504 
505 		public static byte[] floatToBytes(float value){
506 				DatabaseEntry entry = new DatabaseEntry();
507 				SortedFloatBinding.floatToEntry(value, entry);
508 				assert entry.getData().length == net.obsearch.constants.ByteConstants.Float.getSize();
509 				return entry.getData();
510 		}
511 
512 		public static float bytesToFloat(byte[] value){
513 				DatabaseEntry entry = new DatabaseEntry(value);
514 				return SortedFloatBinding.entryToFloat(entry);
515 		}
516 
517 
518 				
519 				
520 
521 				public OBStoreDouble createOBStoreDouble(String name, OBStorageConfig config) throws OBStorageException{
522         
523         OBStoreDouble res = null;
524         try{
525             
526 DatabaseConfig dbConfig = createDefaultDatabaseConfig();
527 				boolean temp = config.isTemp();
528 				boolean bulkMode = config.isBulkMode();
529 				boolean duplicates = config.isDuplicates();							 
530 								
531 								// bulk mode has priority over deferred write.
532 										 dbConfig.setSortedDuplicates(duplicates);
533 								if(bulkMode){
534 										dbConfig.setDeferredWrite(bulkMode);										
535 								}else{
536 //										dbConfig.setTemporary(temp);
537 								}
538 								
539 											Database seq = null;
540 						if(!duplicates){
541 								seq = env.openDatabase(null,  sequentialDatabaseName(name), dbConfig)
542 ;
543 						}
544         
545 						res = new BDBOBStoreJeDouble(name, env.openDatabase(null, name, dbConfig)
546  , seq, this, duplicates);
547 								
548         }catch(DatabaseException e){
549             throw new OBStorageException(e);
550         }
551        return res;
552     }
553 
554 		
555 		public  byte[] serializeDouble(double value){
556 				return BDBFactoryJe.doubleToBytes(value);
557 		}
558 
559 
560 		public double deSerializeDouble(byte[] value){
561 				DatabaseEntry entry = new DatabaseEntry(value);
562 				return SortedDoubleBinding.entryToDouble(entry);
563 		}
564 
565 		public static byte[] doubleToBytes(double value){
566 				DatabaseEntry entry = new DatabaseEntry();
567 				SortedDoubleBinding.doubleToEntry(value, entry);
568 				assert entry.getData().length == net.obsearch.constants.ByteConstants.Double.getSize();
569 				return entry.getData();
570 		}
571 
572 		public static double bytesToDouble(byte[] value){
573 				DatabaseEntry entry = new DatabaseEntry(value);
574 				return SortedDoubleBinding.entryToDouble(entry);
575 		}
576 
577 
578 		public byte[] serializeBigInteger(BigInteger value){
579 				DatabaseEntry entry = new DatabaseEntry();
580 				BigIntegerBinding.bigIntegerToEntry(value, entry);
581 				return entry.getData();
582 		}
583 
584 		public BigInteger deSerializeBigInteger(byte[] value){
585 				DatabaseEntry entry = new DatabaseEntry(value);
586 				return BigIntegerBinding.entryToBigInteger(entry);
587 		}
588 		
589 		public Object stats() throws OBStorageException{
590 		try{
591 				return	env.getStats(null);
592 		}catch(DatabaseException d){
593 				throw new OBStorageException(d);    
594     }
595 }
596 }
597