/** * Lock file IDs participating in the transaction.<br/> * * @param fileIds file IDs to lock. * @return Locked file details. Resulting map doesn't contain details for not-existent files. * @throws IgniteCheckedException If failed. */ private Map<IgniteUuid, IgfsEntryInfo> lockIds(IgniteUuid... fileIds) throws IgniteCheckedException { validTxState(true); assert fileIds != null && fileIds.length > 0; Arrays.sort(fileIds); return lockIds(Arrays.asList(fileIds)); }
/** * Invoke some processor and return new value. * * @param id ID. * @param proc Processor. * @return New file info. * @throws IgniteCheckedException If failed. */ private IgfsEntryInfo invokeAndGet(IgniteUuid id, EntryProcessor<IgniteUuid, IgfsEntryInfo, IgfsEntryInfo> proc) throws IgniteCheckedException { validTxState(true); EntryProcessorResult<IgfsEntryInfo> res = id2InfoPrj.invoke(id, proc); assert res != null; return res.get(); }
/** * Gets file ID for specified path. * * @param path Path. * @return File ID for specified path or {@code null} if such file doesn't exist. * @throws IgniteCheckedException If failed. */ @Nullable public IgniteUuid fileId(IgfsPath path) throws IgniteCheckedException { if (busyLock.enterBusy()) { try { validTxState(false); return fileId(path, false); } finally { busyLock.leaveBusy(); } } else throw new IllegalStateException("Failed to get file ID because Grid is stopping: " + path); }
/** * 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 List<IgniteUuid> fileIds(IgfsPath path) throws IgniteCheckedException { if (busyLock.enterBusy()) { try { validTxState(false); return fileIds(path, false); } finally { busyLock.leaveBusy(); } } else throw new IllegalStateException("Failed to get file IDS because Grid is stopping: " + path); }
/** * Get sampling flag state. * * @return {@code True} in case sampling is enabled, {@code false} otherwise or {@code null} in case sampling * is not set. * @throws IgniteCheckedException If failed. */ public Boolean sampling() throws IgniteCheckedException { if (busyLock.enterBusy()) { try { validTxState(false); Object val = metaCache.get(sampling); return (val == null || !(val instanceof Boolean)) ? null : (Boolean)val; } finally { busyLock.leaveBusy(); } } else throw new IllegalStateException("Failed to get sampling flag because Grid is stopping."); }
/** * Gets files details by their IDs. * * @param fileIds file IDs to get details for. * @return Files details. * @throws IgniteCheckedException If failed. */ public Map<IgniteUuid, IgfsEntryInfo> infos(Collection<IgniteUuid> fileIds) throws IgniteCheckedException { if (busyLock.enterBusy()) { try { validTxState(false); assert fileIds != null; if (F.isEmpty(fileIds)) return Collections.emptyMap(); Map<IgniteUuid, IgfsEntryInfo> map = getInfos(fileIds); // Force root ID always exist in cache. if (fileIds.contains(IgfsUtils.ROOT_ID) && !map.containsKey(IgfsUtils.ROOT_ID)) { map = new GridLeanMap<>(map); map.put(IgfsUtils.ROOT_ID, createSystemDirectoryIfAbsent(IgfsUtils.ROOT_ID)); } return map; } finally { busyLock.leaveBusy(); } } else throw new IllegalStateException("Failed to get file infos because Grid is stopping: " + fileIds); }
/** * Transfer entry from one directory to another. * * @param entry Entry to be transferred. * @param srcId Source ID. * @param srcName Source name. * @param destId Destination ID. * @param destName Destination name. * @throws IgniteCheckedException If failed. */ private void transferEntry(IgfsListingEntry entry, IgniteUuid srcId, String srcName, IgniteUuid destId, String destName) throws IgniteCheckedException { validTxState(true); if (F.eq(srcId, destId)) id2InfoPrj.invoke(srcId, new IgfsMetaDirectoryListingRenameProcessor(srcName, destName)); else { Map<IgniteUuid, EntryProcessor<IgniteUuid, IgfsEntryInfo, Void>> procMap = new HashMap<>(); procMap.put(srcId, new IgfsMetaDirectoryListingRemoveProcessor(srcName, entry.fileId())); procMap.put(destId, new IgfsMetaDirectoryListingAddProcessor(destName, entry)); id2InfoPrj.invokeAll(procMap); } }
/** * Update file info (file properties) in cache. * * @param fileId File ID to update information for. * @param props Properties to set for the file. * @return Updated file info or {@code null} if such file ID not found. * @throws IgniteCheckedException If operation failed. */ @Nullable public IgfsEntryInfo updateProperties(IgniteUuid fileId, Map<String, String> props) throws IgniteCheckedException { if (busyLock.enterBusy()) { try { validTxState(false); try (GridNearTxLocal tx = startTx()) { IgfsEntryInfo info = updatePropertiesNonTx(fileId, props); tx.commit(); return info; } } finally { busyLock.leaveBusy(); } } else throw new IllegalStateException("Failed to update properties because Grid is stopping [fileId=" + fileId + ", props=" + props + ']'); }
/** * Lock file IDs. * * @param fileIds File IDs (sorted). * @return Map with lock info. * @throws IgniteCheckedException If failed. */ private Map<IgniteUuid, IgfsEntryInfo> lockIds(Collection<IgniteUuid> fileIds) throws IgniteCheckedException { assert isSorted(fileIds); validTxState(true); if (log.isDebugEnabled()) log.debug("Locking file ids: " + fileIds); // Lock files and get their infos. Map<IgniteUuid, IgfsEntryInfo> map = getInfos(fileIds); if (log.isDebugEnabled()) log.debug("Locked file ids: " + fileIds); for (IgniteUuid fileId : fileIds) { if (IgfsUtils.isRootOrTrashId(fileId)) { if (!map.containsKey(fileId)) map.put(fileId, createSystemDirectoryIfAbsent(fileId)); } } // Returns detail's map for locked IDs. return map; }
/** * Update file info (file properties) in cache in existing transaction. * * @param fileId File ID to update information for. * @param props Properties to set for the file. * @return Updated file info or {@code null} if such file ID not found. * @throws IgniteCheckedException If operation failed. */ @Nullable private IgfsEntryInfo updatePropertiesNonTx(final IgniteUuid fileId, Map<String, String> props) throws IgniteCheckedException { assert fileId != null; assert !F.isEmpty(props) : "Expects not-empty file's properties"; validTxState(true); if (log.isDebugEnabled()) log.debug("Update file properties [fileId=" + fileId + ", props=" + props + ']'); try { final IgfsEntryInfo oldInfo = info(fileId); if (oldInfo == null) return null; return invokeAndGet(fileId, new IgfsMetaUpdatePropertiesProcessor(props)); } catch (GridClosureException e) { throw U.cast(e); } }
if (busyLock.enterBusy()) { try { validTxState(false);
if (busyLock.enterBusy()) { try { validTxState(false);
/** * Set sampling flag. * * @param val Sampling flag state or {@code null} to clear sampling state and mark it as "not set". * @return {@code True} if sampling mode was actually changed by this call. * @throws IgniteCheckedException If failed. */ public boolean sampling(Boolean val) throws IgniteCheckedException { if (busyLock.enterBusy()) { try { validTxState(false); try (GridNearTxLocal tx = startTx()) { Object prev = val != null ? metaCache.getAndPut(sampling, val) : metaCache.getAndRemove(sampling); tx.commit(); return !F.eq(prev, val); } } finally { busyLock.leaveBusy(); } } else throw new IllegalStateException("Failed to set sampling flag because Grid is stopping."); }
if (busyLock.enterBusy()) { try { validTxState(false);
/** * Put new entry to meta cache immediately linking it to parent. * * @param info Info to put. * @param parentId Parent ID. * @param name Name in parent. * @throws IgniteCheckedException If failed. */ private void createNewEntry(IgfsEntryInfo info, IgniteUuid parentId, String name) throws IgniteCheckedException { validTxState(true); if (!id2InfoPrj.putIfAbsent(info.id(), info)) throw fsException("Failed to create new metadata entry due to ID conflict: " + info.id()); if (parentId != null) id2InfoPrj.invoke(parentId, new IgfsMetaDirectoryListingAddProcessor(name, new IgfsListingEntry(info))); }
if (busyLock.enterBusy()) { try { validTxState(false);
/** * Add file into file system structure. Do not create new transaction expecting that the one already exists. * * @param parentId Parent file ID. * @param fileName File name in the parent's listing. * @param newFileInfo File info to store in the parent's listing. * @return File id already stored in meta cache or {@code null} if passed file info was stored. * @throws IgniteCheckedException If failed. */ private IgniteUuid putIfAbsentNonTx(IgniteUuid parentId, String fileName, IgfsEntryInfo newFileInfo) throws IgniteCheckedException { if (log.isDebugEnabled()) log.debug("Locking parent id [parentId=" + parentId + ", fileName=" + fileName + ", newFileInfo=" + newFileInfo + ']'); validTxState(true); // Lock only parent file ID. IgfsEntryInfo parentInfo = info(parentId); if (parentInfo == null) throw fsException(new IgfsPathNotFoundException("Failed to lock parent directory (not found): " + parentId)); if (!parentInfo.isDirectory()) throw fsException(new IgfsPathIsNotDirectoryException("Parent file is not a directory: " + parentInfo)); IgfsListingEntry childEntry = parentInfo.listing().get(fileName); if (childEntry != null) return childEntry.fileId(); createNewEntry(newFileInfo, parentId, fileName); return null; }
validTxState(false); assert fileId != null; assert proc != null;