Package com.orientechnologies.orient.core.tx

Source Code of com.orientechnologies.orient.core.tx.OTransactionRealAbstract

/*
* Copyright 1999-2010 Luca Garulli (l.garulli--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.
*/
package com.orientechnologies.orient.core.tx;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.orientechnologies.orient.core.db.record.ODatabaseRecordTx;
import com.orientechnologies.orient.core.db.record.OIdentifiable;
import com.orientechnologies.orient.core.exception.OTransactionException;
import com.orientechnologies.orient.core.id.ORID;
import com.orientechnologies.orient.core.index.OIndex;
import com.orientechnologies.orient.core.metadata.schema.OType;
import com.orientechnologies.orient.core.record.ORecord;
import com.orientechnologies.orient.core.record.ORecordInternal;
import com.orientechnologies.orient.core.record.impl.ODocument;
import com.orientechnologies.orient.core.serialization.serializer.OStringSerializerHelper;
import com.orientechnologies.orient.core.serialization.serializer.record.string.ORecordSerializerStringAbstract;
import com.orientechnologies.orient.core.tx.OTransactionIndexChanges.OPERATION;
import com.orientechnologies.orient.core.tx.OTransactionIndexChangesPerKey.OTransactionIndexEntry;

public abstract class OTransactionRealAbstract extends OTransactionAbstract {
  protected Map<ORID, OTransactionRecordEntry>    allEntries        = new HashMap<ORID, OTransactionRecordEntry>();
  protected Map<ORID, OTransactionRecordEntry>    recordEntries      = new HashMap<ORID, OTransactionRecordEntry>();
  protected Map<String, OTransactionIndexChanges>  indexEntries      = new HashMap<String, OTransactionIndexChanges>();
  protected int                                    id;
  protected int                                    newObjectCounter  = -2;

  protected OTransactionRealAbstract(ODatabaseRecordTx iDatabase, int iId) {
    super(iDatabase);
    id = iId;
  }

  public void close() {
    allEntries.clear();
    recordEntries.clear();
    indexEntries.clear();
    newObjectCounter = -2;
    status = TXSTATUS.INVALID;

    database.setDefaultTransactionMode();
  }

  public int getId() {
    return id;
  }

  public void clearRecordEntries() {
    allEntries.putAll(recordEntries);
    recordEntries.clear();
  }

  public Collection<OTransactionRecordEntry> getCurrentRecordEntries() {
    return recordEntries.values();
  }

  public Collection<OTransactionRecordEntry> getAllRecordEntries() {
    return allEntries.values();
  }

  public OTransactionRecordEntry getRecordEntry(final ORID rid) {
    OTransactionRecordEntry e = recordEntries.get(rid);
    if (e != null)
      return e;

    e = allEntries.get(rid);
    if (e != null)
      return e;

    return null;
  }

  public ORecordInternal<?> getRecord(final ORID rid) {
    final OTransactionRecordEntry e = getRecordEntry(rid);
    if (e != null && e.status != OTransactionRecordEntry.DELETED)
      return e.record;
    return null;
  }

  /**
   * Called by class iterator.
   */
  public List<OTransactionRecordEntry> getRecordEntriesByClass(final String iClassName) {
    final List<OTransactionRecordEntry> result = new ArrayList<OTransactionRecordEntry>();

    if (iClassName == null || iClassName.length() == 0)
      // RETURN ALL THE RECORDS
      for (OTransactionRecordEntry entry : recordEntries.values()) {
        result.add(entry);
      }
    else
      // FILTER RECORDS BY CLASSNAME
      for (OTransactionRecordEntry entry : recordEntries.values()) {
        if (entry.getRecord() != null && entry.getRecord() instanceof ODocument
            && iClassName.equals(((ODocument) entry.getRecord()).getClassName()))
          result.add(entry);
      }

    return result;
  }

  /**
   * Called by cluster iterator.
   */
  public List<OTransactionRecordEntry> getRecordEntriesByClusterIds(final int[] iIds) {
    final List<OTransactionRecordEntry> result = new ArrayList<OTransactionRecordEntry>();

    if (iIds == null)
      // RETURN ALL THE RECORDS
      for (OTransactionRecordEntry entry : recordEntries.values()) {
        result.add(entry);
      }
    else
      // FILTER RECORDS BY ID
      for (OTransactionRecordEntry entry : recordEntries.values()) {
        for (int id : iIds) {
          if (entry.getRecord() != null && entry.getRecord().getIdentity().getClusterId() == id) {
            result.add(entry);
            break;
          }
        }
      }

    return result;
  }

  public void clearIndexEntries() {
    indexEntries.clear();
  }

  public List<String> getInvolvedIndexes() {
    List<String> list = null;
    for (String indexName : indexEntries.keySet()) {
      if (list == null)
        list = new ArrayList<String>();
      list.add(indexName);
    }
    return list;
  }

  public ODocument getIndexChanges() {
    final StringBuilder value = new StringBuilder();

    final ODocument result = new ODocument();

    for (Entry<String, OTransactionIndexChanges> indexEntry : indexEntries.entrySet()) {
      final ODocument indexDoc = new ODocument();
      result.field(indexEntry.getKey(), indexDoc);

      if (indexEntry.getValue().cleared)
        indexDoc.field("clear", Boolean.TRUE);

      final List<ODocument> entries = new ArrayList<ODocument>();
      indexDoc.field("entries", entries);

      // STORE INDEX ENTRIES
      for (OTransactionIndexChangesPerKey entry : indexEntry.getValue().changesPerKey.values()) {
        // SERIALIZE KEY
        value.setLength(0);
        if (entry.key != null)
          ORecordSerializerStringAbstract.fieldTypeToString(value, null, OType.getTypeByClass(entry.key.getClass()), entry.key);
        else
          value.append('*');
        String key = value.toString();

        final List<ODocument> operations = new ArrayList<ODocument>();

        // SERIALIZE VALUES
        if (entry.entries != null && !entry.entries.isEmpty()) {
          for (OTransactionIndexEntry e : entry.entries) {
            final ODocument changeDoc = new ODocument();

            // SERIALIZE OPERATION
            changeDoc.field("o", e.operation.ordinal());

            if (e.value instanceof ORecord<?> && e.value.getIdentity().isNew())
              ((ORecord<?>) e.value).save();

            changeDoc.field("v", e.value.getIdentity());

            operations.add(changeDoc);
          }
        }

        entries.add(new ODocument().field("k", OStringSerializerHelper.encode(key)).field("ops", operations));
      }
    }

    indexEntries.clear();

    return result;
  }

  /**
   * Bufferizes index changes to be flushed at commit time.
   *
   * @return
   */
  public OTransactionIndexChanges getIndexChanges(final String iIndexName) {
    return indexEntries.get(iIndexName);
  }

  /**
   * Bufferizes index changes to be flushed at commit time.
   */
  public void addIndexEntry(final OIndex delegate, final String iIndexName, final OTransactionIndexChanges.OPERATION iOperation,
      final Object iKey, final OIdentifiable iValue) {
    OTransactionIndexChanges indexEntry = indexEntries.get(iIndexName);
    if (indexEntry == null) {
      indexEntry = new OTransactionIndexChanges();
      indexEntries.put(iIndexName, indexEntry);
    }

    if (iOperation == OPERATION.CLEAR)
      indexEntry.setCleared();
    else
      indexEntry.getChangesPerKey(iKey).add(iValue, iOperation);
  }

  protected void checkTransaction() {
    if (status == TXSTATUS.INVALID)
      throw new OTransactionException("Invalid state of the transaction. The transaction must be begun.");
  }
}
TOP

Related Classes of com.orientechnologies.orient.core.tx.OTransactionRealAbstract

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.