Skip to content
Closed
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.hadoop.ozone.util;

/**
*
* Represents a function that accepts one argument and produces a result.
* This is a functional interface whose functional method is apply(Object).
* Type parameters:
* <T> – the type of the input to the function <R> – the type of the result of the function
* <E> - the type of exception thrown.
*/
Comment thread
swamirishi marked this conversation as resolved.
public interface CheckedExceptionOperation<T, R, E extends Exception> {
R apply(T t) throws E;

default <V> CheckedExceptionOperation<T, V, E> andThen(CheckedExceptionOperation<R, V, E> operation) {
Comment thread
swamirishi marked this conversation as resolved.
Outdated
return (T t) -> operation.apply(this.apply(t));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,8 @@ public enum Resource {
S3_SECRET_LOCK((byte) 4, "S3_SECRET_LOCK"), // 31
KEY_PATH_LOCK((byte) 5, "KEY_PATH_LOCK"), //63
PREFIX_LOCK((byte) 6, "PREFIX_LOCK"), //127
SNAPSHOT_LOCK((byte) 7, "SNAPSHOT_LOCK"); // = 255
SNAPSHOT_LOCK((byte) 7, "SNAPSHOT_LOCK"), // = 255
SNAPSHOT_GC_LOCK((byte) 8, "SNAPSHOT_GC_LOCK");

// level of the resource
private byte lockLevel;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,11 @@ default String getOpenFileName(long volumeId, long bucketId, long parentObjectId
*/
String getRenameKey(String volume, String bucket, long objectID);

/**
* Given renameKey, return the volume, bucket and objectID from the key.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is the correct place to keep this function but I'll let you decide it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems ok because metadata manager is the translation layer b/w rocksdb & OM. We also have the function Given a volume name,bucket name & object give the renameTable key corresponding to the entry.

*/
String[] splitRenameKey(String renameKey);

/**
* Returns the DB key name of a multipart upload key in OM metadata store
* for FSO-enabled buckets.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
import static org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.FILE_NOT_FOUND;
import static org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.NO_SUCH_MULTIPART_UPLOAD_ERROR;
import static org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.VOLUME_NOT_FOUND;
import static org.apache.hadoop.ozone.om.service.SnapshotDeletingService.isBlockLocationInfoSame;
import static org.apache.hadoop.ozone.om.snapshot.SnapshotUtils.checkSnapshotDirExist;
import static org.apache.hadoop.ozone.om.snapshot.SnapshotUtils.isBlockLocationInfoSame;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Strings;
Expand Down Expand Up @@ -2122,6 +2122,13 @@ public String getRenameKey(String volumeName, String bucketName,
renameKey.append(OM_KEY_PREFIX).append(objectID);
return renameKey.toString();
}

@Override
public String[] splitRenameKey(String renameKey) {
String[] splitVals = renameKey.split(OM_KEY_PREFIX);
return new String[]{splitVals[1], splitVals[2], splitVals[3]};
}

@Override
public String getMultipartKey(long volumeId, long bucketId,
long parentID, String fileName,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.hadoop.ozone.om.lock;

import java.util.Collection;
import java.util.LinkedList;
import java.util.Queue;
import org.apache.hadoop.ozone.om.exceptions.OMException;

/**
* Class to take multiple locks on a resource.
*/
public class MultiLocks<T> {
Comment thread
swamirishi marked this conversation as resolved.
Outdated
private final Queue<T> objectLocks;
private final IOzoneManagerLock lock;
private final OzoneManagerLock.Resource resource;
private final boolean writeLock;

public MultiLocks(IOzoneManagerLock lock, OzoneManagerLock.Resource resource, boolean writeLock) {
this.writeLock = writeLock;
Comment thread
hemantk-12 marked this conversation as resolved.
Outdated
this.resource = resource;
this.lock = lock;
this.objectLocks = new LinkedList<>();
}

public OMLockDetails acquireLock(Collection<T> objects) throws OMException {
if (!objectLocks.isEmpty()) {
Comment thread
hemantk-12 marked this conversation as resolved.
Outdated
throw new OMException("More locks cannot be acquired when locks have been already acquired. Locks acquired : "
+ objectLocks, OMException.ResultCodes.INTERNAL_ERROR);
}
OMLockDetails omLockDetails = OMLockDetails.EMPTY_DETAILS_LOCK_ACQUIRED;
for (T object : objects) {
if (object != null) {
Comment thread
hemantk-12 marked this conversation as resolved.
Outdated
omLockDetails = this.writeLock ? lock.acquireWriteLock(resource, object.toString())
: lock.acquireReadLock(resource, object.toString());
objectLocks.add(object);
if (!omLockDetails.isLockAcquired()) {
break;
}
}
}
if (!omLockDetails.isLockAcquired()) {
releaseLock();
}
return omLockDetails;
}

public void releaseLock() {
while (!objectLocks.isEmpty()) {
T object = objectLocks.poll();
if (this.writeLock) {
lock.releaseWriteLock(resource, object.toString());
} else {
lock.releaseReadLock(resource, object.toString());
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

import static org.apache.hadoop.ozone.OzoneConsts.OBJECT_ID_RECLAIM_BLOCKS;
import static org.apache.hadoop.ozone.OzoneConsts.OM_KEY_PREFIX;
import static org.apache.hadoop.ozone.om.service.SnapshotDeletingService.isBlockLocationInfoSame;
import static org.apache.hadoop.ozone.om.snapshot.SnapshotUtils.isBlockLocationInfoSame;

import com.google.common.annotations.VisibleForTesting;
import com.google.protobuf.ServiceException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@
import org.apache.hadoop.ozone.om.OzoneManager;
import org.apache.hadoop.ozone.om.SnapshotChainManager;
import org.apache.hadoop.ozone.om.helpers.OmKeyInfo;
import org.apache.hadoop.ozone.om.helpers.OmKeyLocationInfo;
import org.apache.hadoop.ozone.om.helpers.OmKeyLocationInfoGroup;
import org.apache.hadoop.ozone.om.helpers.SnapshotInfo;
import org.apache.hadoop.ozone.om.ratis.utils.OzoneManagerRatisUtils;
import org.apache.hadoop.ozone.om.snapshot.ReferenceCounted;
Expand Down Expand Up @@ -315,60 +313,6 @@ boolean shouldIgnoreSnapshot(SnapshotInfo snapInfo) throws IOException {
!OmSnapshotManager.areSnapshotChangesFlushedToDB(getOzoneManager().getMetadataManager(), snapInfo);
}

// TODO: Move this util class.
public static boolean isBlockLocationInfoSame(OmKeyInfo prevKeyInfo,
OmKeyInfo deletedKeyInfo) {

if (prevKeyInfo == null && deletedKeyInfo == null) {
LOG.debug("Both prevKeyInfo and deletedKeyInfo are null.");
return true;
}
if (prevKeyInfo == null || deletedKeyInfo == null) {
LOG.debug("prevKeyInfo: '{}' or deletedKeyInfo: '{}' is null.",
prevKeyInfo, deletedKeyInfo);
return false;
}
// For hsync, Though the blockLocationInfo of a key may not be same
// at the time of snapshot and key deletion as blocks can be appended.
// If the objectId is same then the key is same.
if (prevKeyInfo.isHsync() && deletedKeyInfo.isHsync()) {
return true;
}

if (prevKeyInfo.getKeyLocationVersions().size() !=
deletedKeyInfo.getKeyLocationVersions().size()) {
return false;
}

OmKeyLocationInfoGroup deletedOmKeyLocation =
deletedKeyInfo.getLatestVersionLocations();
OmKeyLocationInfoGroup prevOmKeyLocation =
prevKeyInfo.getLatestVersionLocations();

if (deletedOmKeyLocation == null || prevOmKeyLocation == null) {
return false;
}

List<OmKeyLocationInfo> deletedLocationList =
deletedOmKeyLocation.getLocationList();
List<OmKeyLocationInfo> prevLocationList =
prevOmKeyLocation.getLocationList();

if (deletedLocationList.size() != prevLocationList.size()) {
return false;
}

for (int idx = 0; idx < deletedLocationList.size(); idx++) {
OmKeyLocationInfo deletedLocationInfo = deletedLocationList.get(idx);
OmKeyLocationInfo prevLocationInfo = prevLocationList.get(idx);
if (!deletedLocationInfo.hasSameBlockAs(prevLocationInfo)) {
return false;
}
}

return true;
}

@Override
public BackgroundTaskQueue getTasks() {
BackgroundTaskQueue queue = new BackgroundTaskQueue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,6 @@
import org.apache.hadoop.ozone.om.helpers.SnapshotInfo;
import org.apache.hadoop.ozone.om.helpers.WithObjectID;
import org.apache.hadoop.ozone.om.helpers.WithParentObjectId;
import org.apache.hadoop.ozone.om.service.SnapshotDeletingService;
import org.apache.hadoop.ozone.snapshot.CancelSnapshotDiffResponse;
import org.apache.hadoop.ozone.snapshot.SnapshotDiffReportOzone;
import org.apache.hadoop.ozone.snapshot.SnapshotDiffResponse;
Expand Down Expand Up @@ -1413,8 +1412,7 @@ long generateDiffReport(
private boolean isKeyModified(OmKeyInfo fromKey, OmKeyInfo toKey) {
return !fromKey.isKeyInfoSame(toKey,
false, false, false, false, true)
|| !SnapshotDeletingService.isBlockLocationInfoSame(
fromKey, toKey);
|| !SnapshotUtils.isBlockLocationInfoSame(fromKey, toKey);
}

private boolean isObjectModified(String fromObjectName, String toObjectName,
Expand Down Expand Up @@ -1462,7 +1460,7 @@ private boolean isBlockLocationSame(
"OmKeyInfo");
}

return SnapshotDeletingService.isBlockLocationInfoSame(
return SnapshotUtils.isBlockLocationInfoSame(
(OmKeyInfo) fromObject, (OmKeyInfo) toObject);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
import org.apache.hadoop.ozone.om.SnapshotChainManager;
import org.apache.hadoop.ozone.om.exceptions.OMException;
import org.apache.hadoop.ozone.om.helpers.OmKeyInfo;
import org.apache.hadoop.ozone.om.helpers.OmKeyLocationInfo;
import org.apache.hadoop.ozone.om.helpers.OmKeyLocationInfoGroup;
import org.apache.hadoop.ozone.om.helpers.RepeatedOmKeyInfo;
import org.apache.hadoop.ozone.om.helpers.SnapshotInfo;
import org.apache.hadoop.ozone.om.helpers.SnapshotInfo.SnapshotStatus;
Expand All @@ -54,8 +56,7 @@
* Util class for snapshot diff APIs.
*/
public final class SnapshotUtils {
private static final Logger LOG =
LoggerFactory.getLogger(SnapshotUtils.class);
private static final Logger LOG = LoggerFactory.getLogger(SnapshotUtils.class);

private SnapshotUtils() {
throw new IllegalStateException("SnapshotUtils should not be initialized.");
Expand Down Expand Up @@ -190,7 +191,7 @@ public static SnapshotInfo getPreviousSnapshot(OzoneManager ozoneManager,
/**
* Get the previous snapshot in the snapshot chain.
*/
private static UUID getPreviousSnapshotId(SnapshotInfo snapInfo, SnapshotChainManager chainManager)
public static UUID getPreviousSnapshotId(SnapshotInfo snapInfo, SnapshotChainManager chainManager)
throws IOException {
// If the snapshot is deleted in the previous run, then the in-memory
// SnapshotChainManager might throw NoSuchElementException as the snapshot
Expand Down Expand Up @@ -345,4 +346,55 @@ public static void validatePreviousSnapshotId(SnapshotInfo snapshotInfo,
OMException.ResultCodes.INVALID_REQUEST);
}
}

public static boolean isBlockLocationInfoSame(OmKeyInfo prevKeyInfo,
OmKeyInfo deletedKeyInfo) {
if (prevKeyInfo == null && deletedKeyInfo == null) {
LOG.debug("Both prevKeyInfo and deletedKeyInfo are null.");
return true;
}
if (prevKeyInfo == null || deletedKeyInfo == null) {
LOG.debug("prevKeyInfo: '{}' or deletedKeyInfo: '{}' is null.",
prevKeyInfo, deletedKeyInfo);
return false;
}
// For hsync, Though the blockLocationInfo of a key may not be same
// at the time of snapshot and key deletion as blocks can be appended.
// If the objectId is same then the key is same.
if (prevKeyInfo.isHsync() && deletedKeyInfo.isHsync()) {
return true;
}

if (prevKeyInfo.getKeyLocationVersions().size() !=
deletedKeyInfo.getKeyLocationVersions().size()) {
return false;
}

OmKeyLocationInfoGroup deletedOmKeyLocation =
deletedKeyInfo.getLatestVersionLocations();
OmKeyLocationInfoGroup prevOmKeyLocation =
prevKeyInfo.getLatestVersionLocations();

if (deletedOmKeyLocation == null || prevOmKeyLocation == null) {
return false;
}

List<OmKeyLocationInfo> deletedLocationList =
deletedOmKeyLocation.getLocationList();
List<OmKeyLocationInfo> prevLocationList =
prevOmKeyLocation.getLocationList();

if (deletedLocationList.size() != prevLocationList.size()) {
return false;
}

for (int idx = 0; idx < deletedLocationList.size(); idx++) {
OmKeyLocationInfo deletedLocationInfo = deletedLocationList.get(idx);
OmKeyLocationInfo prevLocationInfo = prevLocationList.get(idx);
if (!deletedLocationInfo.hasSameBlockAs(prevLocationInfo)) {
return false;
}
}
return true;
}
}
Loading