use of org.apache.ignite.lang.IgniteUuid in project ignite by apache.
the class IgfsMetaManager method pathIds.
/**
* Gets all file IDs for components of specified path. Result cannot be empty - there is at least root element.
* But each element (except the first) can be {@code null} if such files don't exist.
*
* @param path Path.
* @return Collection of file IDs for components of specified path.
* @throws IgniteCheckedException If failed.
*/
public IgfsPathIds pathIds(IgfsPath path) throws IgniteCheckedException {
// Prepare parts.
String[] components = path.componentsArray();
String[] parts = new String[components.length + 1];
System.arraycopy(components, 0, parts, 1, components.length);
// Get IDs.
if (client) {
List<IgniteUuid> ids = runClientTask(new IgfsClientMetaIdsForPathCallable(cfg.getName(), IgfsUserContext.currentUser(), path));
return new IgfsPathIds(path, parts, ids.toArray(new IgniteUuid[ids.size()]));
} else {
if (busyLock.enterBusy()) {
try {
validTxState(false);
IgniteUuid[] ids = new IgniteUuid[parts.length];
ids[0] = IgfsUtils.ROOT_ID;
for (int i = 1; i < ids.length; i++) {
IgniteUuid id = fileId(ids[i - 1], parts[i], false);
if (id != null)
ids[i] = id;
else
break;
}
// Return.
return new IgfsPathIds(path, parts, ids);
} finally {
busyLock.leaveBusy();
}
} else
throw new IllegalStateException("Failed to get file IDS because Grid is stopping: " + path);
}
}
use of org.apache.ignite.lang.IgniteUuid in project ignite by apache.
the class IgfsMetaManager method delete.
/**
* Remove listing entries of the given parent.
* This operation actually deletes directories from TRASH, is used solely by IgfsDeleteWorker.
*
* @param parentId Parent ID.
* @param listing Listing entries.
* @return Collection of really deleted entries.
* @throws IgniteCheckedException If failed.
*/
Collection<IgniteUuid> delete(IgniteUuid parentId, Map<String, IgfsListingEntry> listing) throws IgniteCheckedException {
if (busyLock.enterBusy()) {
try {
assert parentId != null;
assert listing != null;
validTxState(false);
try (GridNearTxLocal tx = startTx()) {
Collection<IgniteUuid> res = new HashSet<>();
// Obtain all necessary locks in one hop.
IgniteUuid[] allIds = new IgniteUuid[listing.size() + 1];
allIds[0] = parentId;
int i = 1;
for (IgfsListingEntry childEntry : listing.values()) allIds[i++] = childEntry.fileId();
Map<IgniteUuid, IgfsEntryInfo> locks = lockIds(allIds);
IgfsEntryInfo parentInfo = locks.get(parentId);
// Ensure parent is still in place.
if (parentInfo != null) {
Map<String, IgfsListingEntry> parentListing = parentInfo.listing();
Map<String, IgfsListingEntry> newListing = new HashMap<>(parentListing.size(), 1.0f);
newListing.putAll(parentListing);
// Remove child entries if possible.
for (Map.Entry<String, IgfsListingEntry> entry : listing.entrySet()) {
String childName = entry.getKey();
IgniteUuid childId = entry.getValue().fileId();
IgfsEntryInfo entryInfo = locks.get(childId);
if (entryInfo != null) {
// File must be locked for deletion:
assert entryInfo.isDirectory() || IgfsUtils.DELETE_LOCK_ID.equals(entryInfo.lockId());
// Delete only files or empty folders.
if (!entryInfo.hasChildren()) {
id2InfoPrj.remove(childId);
newListing.remove(childName);
res.add(childId);
}
} else {
// Entry was deleted concurrently.
newListing.remove(childName);
res.add(childId);
}
}
// Update parent listing.
id2InfoPrj.put(parentId, parentInfo.listing(newListing));
}
tx.commit();
return res;
}
} finally {
busyLock.leaveBusy();
}
} else
throw new IllegalStateException("Failed to perform delete because Grid is stopping [parentId=" + parentId + ", listing=" + listing + ']');
}
use of org.apache.ignite.lang.IgniteUuid in project ignite by apache.
the class IgfsMetaManager method synchronize.
/**
* Synchronize directory structure with the secondary file system.
*
* @param fs Secondary file system.
* @param startPath Start path.
* @param startPathInfo Start path info.
* @param endPath End path.
* @param strict Whether all paths must exist in the secondary file system.
* @param created Optional map where data about all created values is put.
* @return File info of the end path.
* @throws IgniteCheckedException If failed.
*/
private IgfsEntryInfo synchronize(IgfsSecondaryFileSystem fs, IgfsPath startPath, IgfsEntryInfo startPathInfo, IgfsPath endPath, boolean strict, @Nullable Map<IgfsPath, IgfsEntryInfo> created) throws IgniteCheckedException {
assert fs != null;
assert startPath != null && startPathInfo != null && endPath != null;
validTxState(true);
IgfsEntryInfo parentInfo = startPathInfo;
List<String> components = endPath.components();
IgfsPath curPath = startPath;
for (int i = startPath.components().size(); i < components.size(); i++) {
curPath = new IgfsPath(curPath, components.get(i));
if (created != null && created.containsKey(curPath))
// Re-use already created info.
parentInfo = created.get(curPath);
else {
// Get file status from the secondary file system.
IgfsFile status;
try {
status = fs.info(curPath);
} catch (IgniteException e) {
throw new IgniteCheckedException("Failed to get path information: " + e, e);
}
if (status != null) {
if (!status.isDirectory() && !curPath.equals(endPath))
throw new IgniteCheckedException("Failed to create path the locally because secondary file " + "system directory structure was modified concurrently and the path is not a directory as " + "expected: " + curPath);
} else {
if (strict) {
throw new IgniteCheckedException("Failed to create path locally due to secondary file system " + "exception: " + curPath);
} else if (created != null)
created.put(curPath.parent(), parentInfo);
return null;
}
// Recreate the path locally.
IgfsEntryInfo curInfo = status.isDirectory() ? IgfsUtils.createDirectory(IgniteUuid.randomUuid(), null, status.properties(), status.accessTime(), status.modificationTime()) : IgfsUtils.createFile(IgniteUuid.randomUuid(), igfsCtx.configuration().getBlockSize(), status.length(), null, null, igfsCtx.igfs().evictExclude(curPath, false), status.properties(), status.accessTime(), status.modificationTime());
assert parentInfo != null;
IgniteUuid oldId = putIfAbsentNonTx(parentInfo.id(), components.get(i), curInfo);
if (oldId != null)
curInfo = info(oldId);
if (created != null)
created.put(curPath, curInfo);
parentInfo = curInfo;
}
}
return parentInfo;
}
use of org.apache.ignite.lang.IgniteUuid in project ignite by apache.
the class IgfsMetaManager method move.
/**
* Move routine.
*
* @param srcPath Source path.
* @param dstPath Destination path.
* @throws IgniteCheckedException In case of exception.
*/
public void move(IgfsPath srcPath, IgfsPath dstPath) throws IgniteCheckedException {
if (busyLock.enterBusy()) {
try {
validTxState(false);
// Prepare path IDs.
IgfsPathIds srcPathIds = pathIds(srcPath);
IgfsPathIds dstPathIds = pathIds(dstPath);
// Source path must exists.
if (!srcPathIds.allExists())
throw new IgfsPathNotFoundException("Failed to perform move because source path is not " + "found: " + srcPath);
// At this point we need to understand name of resulting entry. It will be either destination leaf
// or source leaf depending on existence.
String dstName;
if (dstPathIds.lastExists())
// Full destination path exists -> use source name.
dstName = srcPathIds.lastPart();
else {
if (dstPathIds.lastParentExists()) {
// Destination path doesn't exists -> use destination name.
dstName = dstPathIds.lastPart();
dstPathIds = dstPathIds.parent();
} else
// Destination parent is not found either -> exception.
throw new IgfsPathNotFoundException("Failed to perform move because destination path is not " + "found: " + dstPath.parent());
}
// Lock participating IDs.
final Set<IgniteUuid> lockIds = new TreeSet<>(PATH_ID_SORTING_COMPARATOR);
srcPathIds.addExistingIds(lockIds, relaxed);
dstPathIds.addExistingIds(lockIds, relaxed);
try (GridNearTxLocal tx = startTx()) {
// Obtain the locks.
final Map<IgniteUuid, IgfsEntryInfo> lockInfos = lockIds(lockIds);
// Verify integrity of source and destination paths.
if (!srcPathIds.verifyIntegrity(lockInfos, relaxed))
throw new IgfsPathNotFoundException("Failed to perform move because source directory " + "structure changed concurrently [src=" + srcPath + ", dst=" + dstPath + ']');
if (!dstPathIds.verifyIntegrity(lockInfos, relaxed))
throw new IgfsPathNotFoundException("Failed to perform move because destination directory " + "structure changed concurrently [src=" + srcPath + ", dst=" + dstPath + ']');
// Addiional check: is destination directory?
IgfsEntryInfo dstParentInfo = lockInfos.get(dstPathIds.lastId());
if (dstParentInfo.isFile())
throw new IgfsPathAlreadyExistsException("Failed to perform move because destination points " + "to existing file [src=" + srcPath + ", dst=" + dstPath + ']');
// Additional check: does destination already has child with the same name?
if (dstParentInfo.hasChild(dstName))
throw new IgfsPathAlreadyExistsException("Failed to perform move because destination already " + "contains entry with the same name existing file [src=" + srcPath + ", dst=" + dstPath + ']');
// Actual move: remove from source parent and add to destination target.
IgfsEntryInfo srcParentInfo = lockInfos.get(srcPathIds.lastParentId());
IgfsEntryInfo srcInfo = lockInfos.get(srcPathIds.lastId());
String srcName = srcPathIds.lastPart();
IgfsListingEntry srcEntry = srcParentInfo.listing().get(srcName);
transferEntry(srcEntry, srcParentInfo.id(), srcName, dstParentInfo.id(), dstName);
tx.commit();
// Fire events.
IgfsPath newPath = new IgfsPath(dstPathIds.path(), dstName);
IgfsUtils.sendEvents(igfsCtx.kernalContext(), srcPath, newPath, srcInfo.isFile() ? EVT_IGFS_FILE_RENAMED : EVT_IGFS_DIR_RENAMED);
}
} finally {
busyLock.leaveBusy();
}
} else
throw new IllegalStateException("Failed to perform move because Grid is stopping [srcPath=" + srcPath + ", dstPath=" + dstPath + ']');
}
use of org.apache.ignite.lang.IgniteUuid in project ignite by apache.
the class IgfsMetaManager method delete.
/**
* Remove entry from the metadata listing.
* Used solely by IgfsDeleteWorker.
*
* @param parentId Parent ID.
* @param name Name.
* @param id ID.
* @return {@code True} in case the entry really was removed from the cache by this call.
* @throws IgniteCheckedException If failed.
*/
boolean delete(IgniteUuid parentId, String name, IgniteUuid id) throws IgniteCheckedException {
if (busyLock.enterBusy()) {
try {
validTxState(false);
try (GridNearTxLocal tx = startTx()) {
Map<IgniteUuid, IgfsEntryInfo> infos = lockIds(parentId, id);
IgfsEntryInfo victim = infos.get(id);
if (victim == null)
return false;
assert victim.isDirectory() || IgfsUtils.DELETE_LOCK_ID.equals(victim.lockId()) : " isDir: " + victim.isDirectory() + ", lockId: " + victim.lockId();
// Proceed only in case both parent and child exist.
if (infos.containsKey(parentId) && infos.containsKey(id)) {
IgfsEntryInfo parentInfo = infos.get(parentId);
assert parentInfo != null;
IgfsListingEntry childEntry = parentInfo.listing().get(name);
if (childEntry != null)
id2InfoPrj.invoke(parentId, new IgfsMetaDirectoryListingRemoveProcessor(name, id));
id2InfoPrj.remove(id);
tx.commit();
return true;
}
return false;
}
} finally {
busyLock.leaveBusy();
}
} else
throw new IllegalStateException("Failed to perform delete because Grid is stopping [parentId=" + parentId + ", name=" + name + ", id=" + id + ']');
}
Aggregations