Search in sources :

Example 21 with ORecordId

use of com.orientechnologies.orient.core.id.ORecordId in project orientdb by orientechnologies.

the class OPaginatedCluster method deleteRecord.

public boolean deleteRecord(long clusterPosition) throws IOException {
    startOperation();
    OSessionStoragePerformanceStatistic statistic = performanceStatisticManager.getSessionPerformanceStatistic();
    if (statistic != null)
        statistic.startRecordDeletionTimer();
    try {
        OAtomicOperation atomicOperation = startAtomicOperation(true);
        acquireExclusiveLock();
        try {
            OClusterPositionMapBucket.PositionEntry positionEntry = clusterPositionMap.get(clusterPosition, 1);
            if (positionEntry == null) {
                endAtomicOperation(false, null);
                return false;
            }
            long pageIndex = positionEntry.getPageIndex();
            int recordPosition = positionEntry.getRecordPosition();
            if (getFilledUpTo(atomicOperation, fileId) <= pageIndex) {
                endAtomicOperation(false, null);
                return false;
            }
            long nextPagePointer;
            int removedContentSize = 0;
            do {
                boolean cacheEntryReleased = false;
                OCacheEntry cacheEntry = loadPage(atomicOperation, fileId, pageIndex, false);
                cacheEntry.acquireExclusiveLock();
                int initialFreePageIndex;
                try {
                    OClusterPage localPage = new OClusterPage(cacheEntry, false, getChanges(atomicOperation, cacheEntry));
                    initialFreePageIndex = calculateFreePageIndex(localPage);
                    if (localPage.isDeleted(recordPosition)) {
                        if (removedContentSize == 0) {
                            cacheEntryReleased = true;
                            try {
                                cacheEntry.releaseExclusiveLock();
                                releasePage(atomicOperation, cacheEntry);
                            } finally {
                                endAtomicOperation(false, null);
                            }
                            return false;
                        } else
                            throw new OPaginatedClusterException("Content of record " + new ORecordId(id, clusterPosition) + " was broken", this);
                    } else if (removedContentSize == 0) {
                        cacheEntry.releaseExclusiveLock();
                        releasePage(atomicOperation, cacheEntry);
                        cacheEntry = loadPage(atomicOperation, fileId, pageIndex, false);
                        cacheEntry.acquireExclusiveLock();
                        localPage = new OClusterPage(cacheEntry, false, getChanges(atomicOperation, cacheEntry));
                    }
                    byte[] content = localPage.getRecordBinaryValue(recordPosition, 0, localPage.getRecordSize(recordPosition));
                    int initialFreeSpace = localPage.getFreeSpace();
                    localPage.deleteRecord(recordPosition);
                    removedContentSize += localPage.getFreeSpace() - initialFreeSpace;
                    nextPagePointer = OLongSerializer.INSTANCE.deserializeNative(content, content.length - OLongSerializer.LONG_SIZE);
                } finally {
                    if (!cacheEntryReleased) {
                        cacheEntry.releaseExclusiveLock();
                        releasePage(atomicOperation, cacheEntry);
                    }
                }
                updateFreePagesIndex(fileId, pinnedStateEntryIndex, initialFreePageIndex, pageIndex, atomicOperation);
                pageIndex = getPageIndex(nextPagePointer);
                recordPosition = getRecordPosition(nextPagePointer);
            } while (nextPagePointer >= 0);
            updateClusterState(fileId, pinnedStateEntryIndex, -1, -removedContentSize, atomicOperation);
            clusterPositionMap.remove(clusterPosition);
            addAtomicOperationMetadata(new ORecordId(id, clusterPosition), atomicOperation);
            endAtomicOperation(false, null);
            return true;
        } catch (IOException e) {
            endAtomicOperation(true, e);
            throw OException.wrapException(new OPaginatedClusterException("Error during record deletion", this), e);
        } catch (RuntimeException e) {
            endAtomicOperation(true, e);
            throw OException.wrapException(new OPaginatedClusterException("Error during record deletion", this), e);
        } finally {
            releaseExclusiveLock();
        }
    } finally {
        if (statistic != null)
            statistic.stopRecordDeletionTimer();
        completeOperation();
    }
}
Also used : OAtomicOperation(com.orientechnologies.orient.core.storage.impl.local.paginated.atomicoperations.OAtomicOperation) IOException(java.io.IOException) OPaginatedClusterException(com.orientechnologies.orient.core.exception.OPaginatedClusterException) ORecordId(com.orientechnologies.orient.core.id.ORecordId) OCacheEntry(com.orientechnologies.orient.core.storage.cache.OCacheEntry) OSessionStoragePerformanceStatistic(com.orientechnologies.orient.core.storage.impl.local.statistic.OSessionStoragePerformanceStatistic)

Example 22 with ORecordId

use of com.orientechnologies.orient.core.id.ORecordId in project orientdb by orientechnologies.

the class OPaginatedCluster method updateRecord.

public void updateRecord(final long clusterPosition, byte[] content, final int recordVersion, final byte recordType) throws IOException {
    startOperation();
    OSessionStoragePerformanceStatistic statistic = performanceStatisticManager.getSessionPerformanceStatistic();
    if (statistic != null)
        statistic.startRecordUpdateTimer();
    try {
        content = compression.compress(content);
        content = encryption.encrypt(content);
        OAtomicOperation atomicOperation = startAtomicOperation(true);
        acquireExclusiveLock();
        try {
            final OClusterPositionMapBucket.PositionEntry positionEntry = clusterPositionMap.get(clusterPosition, 1);
            if (positionEntry == null) {
                endAtomicOperation(false, null);
                return;
            }
            int nextRecordPosition = positionEntry.getRecordPosition();
            long nextPageIndex = positionEntry.getPageIndex();
            int newRecordPosition = -1;
            long newPageIndex = -1;
            long prevPageIndex = -1;
            int prevRecordPosition = -1;
            long nextEntryPointer = -1;
            int from = 0;
            int to;
            long sizeDiff = 0;
            byte[] updateEntry = null;
            do {
                final int entrySize;
                final int updatedEntryPosition;
                if (updateEntry == null) {
                    if (from == 0) {
                        entrySize = Math.min(getEntryContentLength(content.length), OClusterPage.MAX_RECORD_SIZE);
                        to = entrySize - (2 * OByteSerializer.BYTE_SIZE + OIntegerSerializer.INT_SIZE + OLongSerializer.LONG_SIZE);
                    } else {
                        entrySize = Math.min(content.length - from + OByteSerializer.BYTE_SIZE + OLongSerializer.LONG_SIZE, OClusterPage.MAX_RECORD_SIZE);
                        to = from + entrySize - (OByteSerializer.BYTE_SIZE + OLongSerializer.LONG_SIZE);
                    }
                    updateEntry = new byte[entrySize];
                    int entryPosition = 0;
                    if (from == 0) {
                        updateEntry[entryPosition] = recordType;
                        entryPosition++;
                        OIntegerSerializer.INSTANCE.serializeNative(content.length, updateEntry, entryPosition);
                        entryPosition += OIntegerSerializer.INT_SIZE;
                    }
                    System.arraycopy(content, from, updateEntry, entryPosition, to - from);
                    entryPosition += to - from;
                    if (nextPageIndex == positionEntry.getPageIndex())
                        updateEntry[entryPosition] = 1;
                    entryPosition++;
                    OLongSerializer.INSTANCE.serializeNative(-1, updateEntry, entryPosition);
                    if (to < content.length) {
                        assert entrySize == OClusterPage.MAX_RECORD_SIZE;
                    }
                } else {
                    entrySize = updateEntry.length;
                    if (from == 0) {
                        to = entrySize - (2 * OByteSerializer.BYTE_SIZE + OIntegerSerializer.INT_SIZE + OLongSerializer.LONG_SIZE);
                    } else {
                        to = from + entrySize - (OByteSerializer.BYTE_SIZE + OLongSerializer.LONG_SIZE);
                    }
                }
                int freePageIndex = -1;
                if (nextPageIndex < 0) {
                    FindFreePageResult findFreePageResult = findFreePage(fileId, pinnedStateEntryIndex, entrySize, atomicOperation);
                    nextPageIndex = findFreePageResult.pageIndex;
                    freePageIndex = findFreePageResult.freePageIndex;
                }
                boolean isNew = false;
                OCacheEntry cacheEntry = loadPage(atomicOperation, fileId, nextPageIndex, false);
                if (cacheEntry == null) {
                    cacheEntry = addPage(atomicOperation, fileId);
                    isNew = true;
                }
                cacheEntry.acquireExclusiveLock();
                try {
                    final OClusterPage localPage = new OClusterPage(cacheEntry, isNew, getChanges(atomicOperation, cacheEntry));
                    final int pageFreeSpace = localPage.getFreeSpace();
                    if (freePageIndex < 0)
                        freePageIndex = calculateFreePageIndex(localPage);
                    else
                        assert isNew || freePageIndex == calculateFreePageIndex(localPage);
                    if (nextRecordPosition >= 0) {
                        if (localPage.isDeleted(nextRecordPosition))
                            throw new OPaginatedClusterException("Record with rid " + new ORecordId(id, clusterPosition) + " was deleted", this);
                        int currentEntrySize = localPage.getRecordSize(nextRecordPosition);
                        nextEntryPointer = localPage.getRecordLongValue(nextRecordPosition, currentEntrySize - OLongSerializer.LONG_SIZE);
                        if (currentEntrySize == entrySize) {
                            localPage.replaceRecord(nextRecordPosition, updateEntry, recordVersion);
                            updatedEntryPosition = nextRecordPosition;
                        } else {
                            localPage.deleteRecord(nextRecordPosition);
                            if (localPage.getMaxRecordSize() >= entrySize) {
                                updatedEntryPosition = localPage.appendRecord(recordVersion, updateEntry);
                                if (updatedEntryPosition < 0) {
                                    throw new IllegalStateException("Page " + cacheEntry.getPageIndex() + " does not have enough free space to add record content");
                                }
                            } else {
                                updatedEntryPosition = -1;
                            }
                        }
                        if (nextEntryPointer >= 0) {
                            nextRecordPosition = getRecordPosition(nextEntryPointer);
                            nextPageIndex = getPageIndex(nextEntryPointer);
                        } else {
                            nextPageIndex = -1;
                            nextRecordPosition = -1;
                        }
                    } else {
                        assert localPage.getFreeSpace() >= entrySize;
                        updatedEntryPosition = localPage.appendRecord(recordVersion, updateEntry);
                        if (updatedEntryPosition < 0) {
                            throw new IllegalStateException("Page " + cacheEntry.getPageIndex() + " does not have enough free space to add record content");
                        }
                        nextPageIndex = -1;
                        nextRecordPosition = -1;
                    }
                    sizeDiff += pageFreeSpace - localPage.getFreeSpace();
                } finally {
                    cacheEntry.releaseExclusiveLock();
                    releasePage(atomicOperation, cacheEntry);
                }
                updateFreePagesIndex(fileId, pinnedStateEntryIndex, freePageIndex, cacheEntry.getPageIndex(), atomicOperation);
                if (updatedEntryPosition >= 0) {
                    if (from == 0) {
                        newPageIndex = cacheEntry.getPageIndex();
                        newRecordPosition = updatedEntryPosition;
                    }
                    from = to;
                    if (prevPageIndex >= 0) {
                        OCacheEntry prevCacheEntry = loadPage(atomicOperation, fileId, prevPageIndex, false);
                        prevCacheEntry.acquireExclusiveLock();
                        try {
                            OClusterPage prevPage = new OClusterPage(prevCacheEntry, false, getChanges(atomicOperation, prevCacheEntry));
                            prevPage.setRecordLongValue(prevRecordPosition, -OLongSerializer.LONG_SIZE, createPagePointer(cacheEntry.getPageIndex(), updatedEntryPosition));
                        } finally {
                            prevCacheEntry.releaseExclusiveLock();
                            releasePage(atomicOperation, prevCacheEntry);
                        }
                    }
                    prevPageIndex = cacheEntry.getPageIndex();
                    prevRecordPosition = updatedEntryPosition;
                    updateEntry = null;
                }
            } while (to < content.length || updateEntry != null);
            // clear unneeded pages
            while (nextEntryPointer >= 0) {
                nextPageIndex = getPageIndex(nextEntryPointer);
                nextRecordPosition = getRecordPosition(nextEntryPointer);
                final int freePagesIndex;
                final int freeSpace;
                OCacheEntry cacheEntry = loadPage(atomicOperation, fileId, nextPageIndex, false);
                cacheEntry.acquireExclusiveLock();
                try {
                    final OClusterPage localPage = new OClusterPage(cacheEntry, false, getChanges(atomicOperation, cacheEntry));
                    freeSpace = localPage.getFreeSpace();
                    freePagesIndex = calculateFreePageIndex(localPage);
                    nextEntryPointer = localPage.getRecordLongValue(nextRecordPosition, -OLongSerializer.LONG_SIZE);
                    localPage.deleteRecord(nextRecordPosition);
                    sizeDiff += freeSpace - localPage.getFreeSpace();
                } finally {
                    cacheEntry.releaseExclusiveLock();
                    releasePage(atomicOperation, cacheEntry);
                }
                updateFreePagesIndex(fileId, pinnedStateEntryIndex, freePagesIndex, nextPageIndex, atomicOperation);
            }
            assert newPageIndex >= 0;
            assert newRecordPosition >= 0;
            if (newPageIndex != positionEntry.getPageIndex() || newRecordPosition != positionEntry.getRecordPosition()) {
                clusterPositionMap.update(clusterPosition, new OClusterPositionMapBucket.PositionEntry(newPageIndex, newRecordPosition));
            }
            updateClusterState(fileId, pinnedStateEntryIndex, 0, sizeDiff, atomicOperation);
            addAtomicOperationMetadata(new ORecordId(id, clusterPosition), atomicOperation);
            endAtomicOperation(false, null);
        } catch (RuntimeException e) {
            endAtomicOperation(true, e);
            throw OException.wrapException(new OPaginatedClusterException("Error during record update", this), e);
        } finally {
            releaseExclusiveLock();
        }
    } finally {
        if (statistic != null)
            statistic.stopRecordUpdateTimer();
        completeOperation();
    }
}
Also used : OAtomicOperation(com.orientechnologies.orient.core.storage.impl.local.paginated.atomicoperations.OAtomicOperation) OPaginatedClusterException(com.orientechnologies.orient.core.exception.OPaginatedClusterException) ORecordId(com.orientechnologies.orient.core.id.ORecordId) OCacheEntry(com.orientechnologies.orient.core.storage.cache.OCacheEntry) OSessionStoragePerformanceStatistic(com.orientechnologies.orient.core.storage.impl.local.statistic.OSessionStoragePerformanceStatistic)

Example 23 with ORecordId

use of com.orientechnologies.orient.core.id.ORecordId in project orientdb by orientechnologies.

the class OCommandExecutorSQLSetAware method extractClassFromTarget.

protected OClass extractClassFromTarget(String iTarget) {
    // CLASS
    if (!iTarget.toUpperCase().startsWith(OCommandExecutorSQLAbstract.CLUSTER_PREFIX) && !iTarget.startsWith(OCommandExecutorSQLAbstract.INDEX_PREFIX)) {
        if (iTarget.toUpperCase().startsWith(OCommandExecutorSQLAbstract.CLASS_PREFIX))
            // REMOVE CLASS PREFIX
            iTarget = iTarget.substring(OCommandExecutorSQLAbstract.CLASS_PREFIX.length());
        if (iTarget.charAt(0) == ORID.PREFIX)
            return getDatabase().getMetadata().getSchema().getClassByClusterId(new ORecordId(iTarget).getClusterId());
        return getDatabase().getMetadata().getSchema().getClass(iTarget);
    }
    //CLUSTER
    if (iTarget.toUpperCase().startsWith(OCommandExecutorSQLAbstract.CLUSTER_PREFIX)) {
        String clusterName = iTarget.substring(OCommandExecutorSQLAbstract.CLUSTER_PREFIX.length()).trim();
        ODatabaseDocumentInternal db = getDatabase();
        if (clusterName.startsWith("[") && clusterName.endsWith("]")) {
            String[] clusterNames = clusterName.substring(1, clusterName.length() - 1).split(",");
            OClass candidateClass = null;
            for (String cName : clusterNames) {
                OCluster aCluster = db.getStorage().getClusterByName(cName.trim());
                if (aCluster == null) {
                    return null;
                }
                OClass aClass = db.getMetadata().getSchema().getClassByClusterId(aCluster.getId());
                if (aClass == null) {
                    return null;
                }
                if (candidateClass == null || candidateClass.equals(aClass) || candidateClass.isSubClassOf(aClass)) {
                    candidateClass = aClass;
                } else if (!candidateClass.isSuperClassOf(aClass)) {
                    return null;
                }
            }
            return candidateClass;
        } else {
            OCluster cluster = db.getStorage().getClusterByName(clusterName);
            if (cluster != null) {
                return db.getMetadata().getSchema().getClassByClusterId(cluster.getId());
            }
        }
    }
    return null;
}
Also used : OClass(com.orientechnologies.orient.core.metadata.schema.OClass) OCluster(com.orientechnologies.orient.core.storage.OCluster) ORecordId(com.orientechnologies.orient.core.id.ORecordId) ODatabaseDocumentInternal(com.orientechnologies.orient.core.db.ODatabaseDocumentInternal)

Example 24 with ORecordId

use of com.orientechnologies.orient.core.id.ORecordId in project orientdb by orientechnologies.

the class OPaginatedCluster method createRecord.

public OPhysicalPosition createRecord(byte[] content, final int recordVersion, final byte recordType, OPhysicalPosition allocatedPosition) throws IOException {
    startOperation();
    OSessionStoragePerformanceStatistic statistic = performanceStatisticManager.getSessionPerformanceStatistic();
    if (statistic != null)
        statistic.startRecordCreationTimer();
    try {
        content = compression.compress(content);
        content = encryption.encrypt(content);
        OAtomicOperation atomicOperation = startAtomicOperation(true);
        acquireExclusiveLock();
        try {
            final RecordCreationResult recordCreationResult = createDataRecord(fileId, pinnedStateEntryIndex, content, recordVersion, recordType, atomicOperation);
            final long clusterPosition;
            if (allocatedPosition != null) {
                clusterPositionMap.update(allocatedPosition.clusterPosition, new OClusterPositionMapBucket.PositionEntry(recordCreationResult.pageIndex, recordCreationResult.recordPosition));
                clusterPosition = allocatedPosition.clusterPosition;
            } else
                clusterPosition = clusterPositionMap.add(recordCreationResult.pageIndex, recordCreationResult.recordPosition);
            addAtomicOperationMetadata(new ORecordId(id, clusterPosition), atomicOperation);
            endAtomicOperation(false, null);
            return createPhysicalPosition(recordType, clusterPosition, recordCreationResult.recordVersion);
        } finally {
            releaseExclusiveLock();
        }
    } finally {
        if (statistic != null)
            statistic.stopRecordCreationTimer();
        completeOperation();
    }
}
Also used : OAtomicOperation(com.orientechnologies.orient.core.storage.impl.local.paginated.atomicoperations.OAtomicOperation) OSessionStoragePerformanceStatistic(com.orientechnologies.orient.core.storage.impl.local.statistic.OSessionStoragePerformanceStatistic) ORecordId(com.orientechnologies.orient.core.id.ORecordId)

Example 25 with ORecordId

use of com.orientechnologies.orient.core.id.ORecordId in project orientdb by orientechnologies.

the class OPaginatedCluster method readDebug.

public OPaginatedClusterDebug readDebug(long clusterPosition) throws IOException {
    startOperation();
    try {
        OPaginatedClusterDebug debug = new OPaginatedClusterDebug();
        debug.clusterPosition = clusterPosition;
        debug.fileId = fileId;
        OAtomicOperation atomicOperation = storageLocal.getAtomicOperationsManager().getCurrentOperation();
        OClusterPositionMapBucket.PositionEntry positionEntry = clusterPositionMap.get(clusterPosition, 1);
        if (positionEntry == null) {
            debug.empty = true;
            return debug;
        }
        long pageIndex = positionEntry.getPageIndex();
        int recordPosition = positionEntry.getRecordPosition();
        if (getFilledUpTo(atomicOperation, fileId) <= pageIndex) {
            debug.empty = true;
            return debug;
        }
        debug.pages = new ArrayList<OClusterPageDebug>();
        int contentSize = 0;
        long nextPagePointer;
        boolean firstEntry = true;
        do {
            OClusterPageDebug debugPage = new OClusterPageDebug();
            debugPage.pageIndex = pageIndex;
            OCacheEntry cacheEntry = loadPage(atomicOperation, fileId, pageIndex, false);
            cacheEntry.acquireSharedLock();
            try {
                final OClusterPage localPage = new OClusterPage(cacheEntry, false, getChanges(atomicOperation, cacheEntry));
                if (localPage.isDeleted(recordPosition)) {
                    if (debug.pages.isEmpty()) {
                        debug.empty = true;
                        return debug;
                    } else
                        throw new OPaginatedClusterException("Content of record " + new ORecordId(id, clusterPosition) + " was broken", this);
                }
                debugPage.inPagePosition = recordPosition;
                debugPage.inPageSize = localPage.getRecordSize(recordPosition);
                byte[] content = localPage.getRecordBinaryValue(recordPosition, 0, debugPage.inPageSize);
                debugPage.content = content;
                if (firstEntry && content[content.length - OLongSerializer.LONG_SIZE - OByteSerializer.BYTE_SIZE] == 0) {
                    debug.empty = true;
                    return debug;
                }
                debug.pages.add(debugPage);
                nextPagePointer = OLongSerializer.INSTANCE.deserializeNative(content, content.length - OLongSerializer.LONG_SIZE);
                contentSize += content.length - OLongSerializer.LONG_SIZE - OByteSerializer.BYTE_SIZE;
                firstEntry = false;
            } finally {
                cacheEntry.releaseSharedLock();
                releasePage(atomicOperation, cacheEntry);
            }
            pageIndex = getPageIndex(nextPagePointer);
            recordPosition = getRecordPosition(nextPagePointer);
        } while (nextPagePointer >= 0);
        debug.contentSize = contentSize;
        return debug;
    } finally {
        completeOperation();
    }
}
Also used : OAtomicOperation(com.orientechnologies.orient.core.storage.impl.local.paginated.atomicoperations.OAtomicOperation) OPaginatedClusterException(com.orientechnologies.orient.core.exception.OPaginatedClusterException) ORecordId(com.orientechnologies.orient.core.id.ORecordId) OCacheEntry(com.orientechnologies.orient.core.storage.cache.OCacheEntry)

Aggregations

ORecordId (com.orientechnologies.orient.core.id.ORecordId)431 Test (org.testng.annotations.Test)153 ODocument (com.orientechnologies.orient.core.record.impl.ODocument)139 OIdentifiable (com.orientechnologies.orient.core.db.record.OIdentifiable)120 ORID (com.orientechnologies.orient.core.id.ORID)71 HashSet (java.util.HashSet)63 OIndexCursor (com.orientechnologies.orient.core.index.OIndexCursor)42 ORidBag (com.orientechnologies.orient.core.db.record.ridbag.ORidBag)37 ORecord (com.orientechnologies.orient.core.record.ORecord)37 ODatabaseDocumentTx (com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx)34 OIndexTxAwareMultiValue (com.orientechnologies.orient.core.index.OIndexTxAwareMultiValue)30 OIndexTxAwareOneValue (com.orientechnologies.orient.core.index.OIndexTxAwareOneValue)30 HashMap (java.util.HashMap)29 OClass (com.orientechnologies.orient.core.metadata.schema.OClass)28 IOException (java.io.IOException)25 Child (com.orientechnologies.orient.test.domain.business.Child)24 OException (com.orientechnologies.common.exception.OException)23 ODatabaseDocument (com.orientechnologies.orient.core.db.document.ODatabaseDocument)23 Map (java.util.Map)22 OCommandSQL (com.orientechnologies.orient.core.sql.OCommandSQL)21