public synchronized <E> Queue<E> createCircularQueue( String name, Serializer<E> serializer, long size) { checkNameNotExists(name); if (serializer == null) serializer = getDefaultSerializer(); // long headerRecid = engine.put(0L, Serializer.LONG); // insert N Nodes empty nodes into a circle long prevRecid = 0; long firstRecid = 0; Serializer<Queues.SimpleQueue.Node> nodeSer = new Queues.SimpleQueue.NodeSerializer(serializer); for (long i = 0; i < size; i++) { Queues.SimpleQueue.Node n = new Queues.SimpleQueue.Node(prevRecid, null); prevRecid = engine.put(n, nodeSer); if (firstRecid == 0) firstRecid = prevRecid; } // update first node to point to last recid engine.update(firstRecid, new Queues.SimpleQueue.Node(prevRecid, null), nodeSer); long headRecid = engine.put(prevRecid, Serializer.LONG); long headInsertRecid = engine.put(prevRecid, Serializer.LONG); Queues.CircularQueue<E> ret = new Queues.CircularQueue<E>( engine, catPut(name + ".serializer", serializer), catPut(name + ".headRecid", headRecid), catPut(name + ".headInsertRecid", headInsertRecid), catPut(name + ".size", size)); catalog.put(name + ".type", "CircularQueue"); collections.put(name, new WeakReference<Object>(ret)); return ret; }
/** constructs Engine using current settings */ public Engine makeEngine() { final boolean readOnly = propsGetBool(Keys.readOnly); final File file = props.containsKey(Keys.file) ? new File(props.getProperty(Keys.file)) : null; final String volume = props.getProperty(Keys.volume); final String store = props.getProperty(Keys.store); if (readOnly && file == null) throw new UnsupportedOperationException("Can not open in-memory DB in read-only mode."); if (readOnly && !file.exists() && !Keys.store_append.equals(store)) { throw new UnsupportedOperationException("Can not open non-existing file in read-only mode."); } if (propsGetLong(Keys.sizeLimit, 0) > 0 && Keys.store_append.equals(store)) throw new UnsupportedOperationException("Append-Only store does not support Size Limit"); extendArgumentCheck(); Engine engine; if (!Keys.store_append.equals(store)) { Volume.Factory folFac = extendStoreVolumeFactory(); engine = propsGetBool(Keys.transactionDisable) ? extendStoreDirect(folFac) : extendStoreWAL(folFac); } else { if (Keys.volume_heap.equals(volume) || Keys.volume_offheap.equals(volume)) throw new UnsupportedOperationException( "Append Storage format is not supported with in-memory dbs"); engine = extendStoreAppend(); } engine = extendWrapStore(engine); if (propsGetBool(Keys.asyncWrite) && !readOnly) { engine = extendAsyncWriteEngine(engine); } final String cache = props.getProperty(Keys.cache, CC.DEFAULT_CACHE); if (Keys.cache_disable.equals(cache)) { // do not wrap engine in cache } else if (Keys.cache_hashTable.equals(cache)) { engine = extendCacheHashTable(engine); } else if (Keys.cache_hardRef.equals(cache)) { engine = extendCacheHardRef(engine); } else if (Keys.cache_weakRef.equals(cache)) { engine = extendCacheWeakRef(engine); } else if (Keys.cache_softRef.equals(cache)) { engine = extendCacheSoftRef(engine); } else if (Keys.cache_lru.equals(cache)) { engine = extendCacheLRU(engine); } else { throw new IllegalArgumentException("unknown cache type: " + cache); } engine = extendWrapCache(engine); if (propsGetBool(Keys.snapshots)) engine = extendSnapshotEngine(engine); engine = extendWrapSnapshotEngine(engine); if (readOnly) engine = new ReadOnlyEngine(engine); if (propsGetBool(Keys.closeOnJvmShutdown)) { engine = new EngineWrapper.CloseOnJVMShutdown(engine); } // try to read one record from DB, to make sure encryption and compression are correctly set. Fun.Tuple2<Integer, byte[]> check = null; try { check = (Fun.Tuple2<Integer, byte[]>) engine.get(Engine.CHECK_RECORD, Serializer.BASIC); if (check != null) { if (check.a.intValue() != Arrays.hashCode(check.b)) throw new RuntimeException("invalid checksum"); } } catch (Throwable e) { throw new IllegalArgumentException( "Error while opening store. Make sure you have right password, compression or encryption is well configured.", e); } if (check == null && !engine.isReadOnly()) { // new db, so insert testing record byte[] b = new byte[127]; new Random().nextBytes(b); check = Fun.t2(Arrays.hashCode(b), b); engine.update(Engine.CHECK_RECORD, check, Serializer.BASIC); engine.commit(); } return engine; }