Пример #1
0
 public static Engine createSnapshotFor(Engine engine) {
   if (engine.isReadOnly()) return engine;
   if (engine instanceof TxEngine) return ((TxEngine) engine).snapshot();
   if (engine instanceof EngineWrapper)
     createSnapshotFor(((EngineWrapper) engine).getWrappedEngine());
   throw new UnsupportedOperationException(
       "Snapshots are not enabled, use DBMaker.snapshotEnable()");
 }
Пример #2
0
  /** 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;
  }