Package com.orientechnologies.orient.core.storage

Source Code of com.orientechnologies.orient.core.storage.OStorageAbstract

/*
  *
  *  *  Copyright 2014 Orient Technologies LTD (info(at)orientechnologies.com)
  *  *
  *  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  *  you may not use this file except in compliance with the License.
  *  *  You may obtain a copy of the License at
  *  *
  *  *       http://www.apache.org/licenses/LICENSE-2.0
  *  *
  *  *  Unless required by applicable law or agreed to in writing, software
  *  *  distributed under the License is distributed on an "AS IS" BASIS,
  *  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  *  *  See the License for the specific language governing permissions and
  *  *  limitations under the License.
  *  *
  *  * For more information: http://www.orientechnologies.com
  *
  */
package com.orientechnologies.orient.core.storage;

import com.orientechnologies.common.concur.resource.OCloseable;
import com.orientechnologies.common.concur.resource.OSharedContainerImpl;
import com.orientechnologies.common.concur.resource.OSharedResource;
import com.orientechnologies.common.concur.resource.OSharedResourceAdaptiveExternal;
import com.orientechnologies.common.exception.OException;
import com.orientechnologies.orient.core.cache.OCacheLevelTwoLocator;
import com.orientechnologies.orient.core.config.OGlobalConfiguration;
import com.orientechnologies.orient.core.config.OStorageConfiguration;
import com.orientechnologies.orient.core.db.ODatabaseRecordThreadLocal;
import com.orientechnologies.orient.core.db.record.OCurrentStorageComponentsFactory;
import com.orientechnologies.orient.core.exception.OSecurityException;
import com.orientechnologies.orient.core.metadata.OMetadata;
import com.orientechnologies.orient.core.metadata.schema.OClass;
import com.orientechnologies.orient.core.metadata.security.OSecurityShared;
import com.orientechnologies.orient.core.serialization.serializer.OStringSerializerHelper;

import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicLong;

public abstract class OStorageAbstract extends OSharedContainerImpl implements OStorage {
  protected final String                              url;
  protected final String                              mode;
  protected final OSharedResourceAdaptiveExternal     lock;
  protected volatile OStorageConfiguration            configuration;
  protected volatile OCurrentStorageComponentsFactory componentsFactory;
  protected String                                    name;
  protected AtomicLong                                version = new AtomicLong();
  protected volatile STATUS                           status  = STATUS.CLOSED;

  public OStorageAbstract(final String name, final String iURL, final String mode, final int timeout) {
    if (OStringSerializerHelper.contains(name, '/'))
      this.name = name.substring(name.lastIndexOf("/") + 1);
    else
      this.name = name;

    if (OStringSerializerHelper.contains(name, ','))
      throw new IllegalArgumentException("Invalid character in storage name: " + this.name);

    url = iURL;
    this.mode = mode;

    lock = new OSharedResourceAdaptiveExternal(OGlobalConfiguration.ENVIRONMENT_CONCURRENT.getValueAsBoolean(), timeout, true);
  }

  public abstract OCluster getClusterByName(final String iClusterName);

  public OStorage getUnderlying() {
    return this;
  }

  public OStorageConfiguration getConfiguration() {
    return configuration;
  }

  public boolean isClosed() {
    return status == STATUS.CLOSED;
  }

  public boolean checkForRecordValidity(final OPhysicalPosition ppos) {
    return ppos != null && !ppos.recordVersion.isTombstone();
  }

  public String getName() {
    return name;
  }

  public String getURL() {
    return url;
  }

  public void close() {
    close(false, false);
  }

  public void close(final boolean iForce, boolean onDelete) {
    lock.acquireExclusiveLock();
    try {
      for (Object resource : sharedResources.values()) {
        if (resource instanceof OSharedResource)
          ((OSharedResource) resource).releaseExclusiveLock();

        if (resource instanceof OCloseable)
          ((OCloseable) resource).close(onDelete);
      }
      sharedResources.clear();
    } finally {
      lock.releaseExclusiveLock();
    }
  }

  /**
   * Returns current storage's version as serial.
   */
  public long getVersion() {
    return version.get();
  }

  public boolean dropCluster(final String iClusterName, final boolean iTruncate) {
    return dropCluster(getClusterIdByName(iClusterName), iTruncate);
  }

  public int getUsers() {
    return lock.getUsers();
  }

  public int addUser() {
    return lock.addUser();
  }

  public int removeUser() {
    return lock.removeUser();
  }

  public OSharedResourceAdaptiveExternal getLock() {
    return lock;
  }

  public long countRecords() {
    long tot = 0;

    for (OCluster c : getClusterInstances())
      if (c != null)
        tot += c.getEntries() - c.getTombstonesCount();

    return tot;
  }

  public <V> V callInLock(final Callable<V> iCallable, final boolean iExclusiveLock) {
    if (iExclusiveLock)
      lock.acquireExclusiveLock();
    else
      lock.acquireSharedLock();
    try {
      return iCallable.call();
    } catch (RuntimeException e) {
      throw e;
    } catch (Exception e) {
      throw new OException("Error on nested call in lock", e);
    } finally {
      if (iExclusiveLock)
        lock.releaseExclusiveLock();
      else
        lock.releaseSharedLock();
    }
  }

  @Override
  public String toString() {
    return url != null ? url : "?";
  }

  public STATUS getStatus() {
    return status;
  }

  public void checkForClusterPermissions(final String iClusterName) {
    // CHECK FOR ORESTRICTED
    OMetadata metaData = ODatabaseRecordThreadLocal.INSTANCE.get().getMetadata();
    if (metaData != null) {
      final Set<OClass> classes = metaData.getSchema().getClassesRelyOnCluster(iClusterName);
      for (OClass c : classes) {
        if (c.isSubClassOf(OSecurityShared.RESTRICTED_CLASSNAME))
          throw new OSecurityException("Class " + c.getName()
              + " cannot be truncated because has record level security enabled (extends " + OSecurityShared.RESTRICTED_CLASSNAME
              + ")");
      }
    }
  }

  @Override
  public boolean isDistributed() {
    return false;
  }

  @Override
  public OCurrentStorageComponentsFactory getComponentsFactory() {
    return componentsFactory;
  }

  @Override
  public long getLastOperationId() {
    return 0;
  }

  protected boolean checkForClose(final boolean force) {
    if (status == STATUS.CLOSED)
      return false;

    lock.acquireSharedLock();
    try {
      if (status == STATUS.CLOSED)
        return false;

      final int remainingUsers = getUsers() > 0 ? removeUser() : 0;

      return force
          || (!(OGlobalConfiguration.STORAGE_KEEP_OPEN.getValueAsBoolean() && this instanceof OStorageEmbedded) && remainingUsers == 0);
    } finally {
      lock.releaseSharedLock();
    }
  }
}
TOP

Related Classes of com.orientechnologies.orient.core.storage.OStorageAbstract

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.