You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2016/06/17 08:54:15 UTC
[06/41] ignite git commit: IGNITE-3294: IGFS: Improved "create"
performance in DUAL mode.
IGNITE-3294: IGFS: Improved "create" performance in DUAL mode.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/40e6614f
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/40e6614f
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/40e6614f
Branch: refs/heads/ignite-3331
Commit: 40e6614f2426912aaec4220b8f720c12c3e5214a
Parents: 7f878c5
Author: vozerov-gridgain <vo...@gridgain.com>
Authored: Tue Jun 14 11:09:01 2016 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Tue Jun 14 11:09:01 2016 +0300
----------------------------------------------------------------------
.../processors/igfs/IgfsCreateResult.java | 66 ++
.../internal/processors/igfs/IgfsImpl.java | 53 +-
.../processors/igfs/IgfsMetaManager.java | 612 +++++++++----------
.../IgfsSecondaryFileSystemCreateContext.java | 111 ++++
.../IgfsSecondaryOutputStreamDescriptor.java | 59 --
.../meta/IgfsMetaDirectoryCreateProcessor.java | 40 +-
.../igfs/meta/IgfsMetaFileCreateProcessor.java | 46 +-
.../igfs/IgfsMetaManagerSelfTest.java | 4 +-
8 files changed, 538 insertions(+), 453 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/40e6614f/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsCreateResult.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsCreateResult.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsCreateResult.java
new file mode 100644
index 0000000..0b09e02
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsCreateResult.java
@@ -0,0 +1,66 @@
+/*
+ * 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.ignite.internal.processors.igfs;
+
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.OutputStream;
+
+/**
+ * IGFS file create result.
+ */
+public class IgfsCreateResult {
+ /** File info in the primary file system. */
+ private final IgfsEntryInfo info;
+
+ /** Output stream to the secondary file system. */
+ private final OutputStream secondaryOut;
+
+ /**
+ * Constructor.
+ *
+ * @param info File info in the primary file system.
+ * @param secondaryOut Output stream to the secondary file system.
+ */
+ public IgfsCreateResult(IgfsEntryInfo info, @Nullable OutputStream secondaryOut) {
+ assert info != null;
+
+ this.info = info;
+ this.secondaryOut = secondaryOut;
+ }
+
+ /**
+ * @return File info in the primary file system.
+ */
+ public IgfsEntryInfo info() {
+ return info;
+ }
+
+ /**
+ * @return Output stream to the secondary file system.
+ */
+ @Nullable public OutputStream secondaryOutputStream() {
+ return secondaryOut;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(IgfsCreateResult.class, this);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/40e6614f/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsImpl.java
index 0808619..7234e52 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsImpl.java
@@ -106,7 +106,6 @@ import static org.apache.ignite.events.EventType.EVT_IGFS_DIR_DELETED;
import static org.apache.ignite.events.EventType.EVT_IGFS_FILE_CLOSED_READ;
import static org.apache.ignite.events.EventType.EVT_IGFS_FILE_DELETED;
import static org.apache.ignite.events.EventType.EVT_IGFS_FILE_OPENED_READ;
-import static org.apache.ignite.events.EventType.EVT_IGFS_FILE_OPENED_WRITE;
import static org.apache.ignite.events.EventType.EVT_IGFS_META_UPDATED;
import static org.apache.ignite.igfs.IgfsMode.DUAL_ASYNC;
import static org.apache.ignite.igfs.IgfsMode.DUAL_SYNC;
@@ -1019,28 +1018,10 @@ public final class IgfsImpl implements IgfsEx {
log.debug("Open file for writing [path=" + path + ", bufSize=" + bufSize + ", overwrite=" +
overwrite + ", props=" + props + ']');
+ // Resolve mode.
final IgfsMode mode = resolveMode(path);
- IgfsFileWorkerBatch batch;
-
- if (mode != PRIMARY) {
- assert mode == DUAL_SYNC || mode == DUAL_ASYNC;
-
- await(path);
-
- IgfsSecondaryOutputStreamDescriptor desc = meta.createDual(secondaryFs, path, simpleCreate,
- props, overwrite, bufSize, (short) replication, groupBlockSize(), affKey);
-
- batch = newBatch(path, desc.out());
-
- IgfsOutputStreamImpl os = new IgfsOutputStreamImpl(igfsCtx, path, desc.info(),
- bufferSize(bufSize), mode, batch);
-
- IgfsUtils.sendEvents(igfsCtx.kernalContext(), path, EVT_IGFS_FILE_OPENED_WRITE);
-
- return os;
- }
-
+ // Prepare properties.
final Map<String, String> dirProps, fileProps;
if (props == null) {
@@ -1051,19 +1032,37 @@ public final class IgfsImpl implements IgfsEx {
else
dirProps = fileProps = new HashMap<>(props);
- IgfsEntryInfo res = meta.create(
+ // Prepare context for DUAL mode.
+ IgfsSecondaryFileSystemCreateContext secondaryCtx = null;
+
+ if (mode != PRIMARY)
+ secondaryCtx = new IgfsSecondaryFileSystemCreateContext(secondaryFs, path, overwrite, simpleCreate,
+ fileProps, (short)replication, groupBlockSize(), bufSize);
+
+ // Await for async ops completion if in DUAL mode.
+ if (mode != PRIMARY)
+ await(path);
+
+ // Perform create.
+ IgfsCreateResult res = meta.create(
path,
dirProps,
overwrite,
cfg.getBlockSize(),
affKey,
- evictExclude(path, true),
- fileProps
+ evictExclude(path, mode == PRIMARY),
+ fileProps,
+ secondaryCtx
);
assert res != null;
- return new IgfsOutputStreamImpl(igfsCtx, path, res, bufferSize(bufSize), mode, null);
+ // Create secondary file system batch.
+ OutputStream secondaryStream = res.secondaryOutputStream();
+
+ IgfsFileWorkerBatch batch = secondaryStream != null ? newBatch(path, secondaryStream) : null;
+
+ return new IgfsOutputStreamImpl(igfsCtx, path, res.info(), bufferSize(bufSize), mode, batch);
}
});
}
@@ -1094,9 +1093,9 @@ public final class IgfsImpl implements IgfsEx {
await(path);
- IgfsSecondaryOutputStreamDescriptor desc = meta.appendDual(secondaryFs, path, bufSize);
+ IgfsCreateResult desc = meta.appendDual(secondaryFs, path, bufSize);
- batch = newBatch(path, desc.out());
+ batch = newBatch(path, desc.secondaryOutputStream());
return new IgfsOutputStreamImpl(igfsCtx, path, desc.info(), bufferSize(bufSize), mode, batch);
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/40e6614f/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsMetaManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsMetaManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsMetaManager.java
index 2fb6066..c08d6a0 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsMetaManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsMetaManager.java
@@ -393,40 +393,47 @@ public class IgfsMetaManager extends IgfsManager {
* @throws IgniteCheckedException If failed.
*/
public IgfsPathIds pathIds(IgfsPath path) throws IgniteCheckedException {
- if (busyLock.enterBusy()) {
- try {
- validTxState(false);
+ // Prepare parts.
+ String[] components = path.componentsArray();
- // Prepare parts.
- String[] components = path.componentsArray();
+ String[] parts = new String[components.length + 1];
- String[] parts = new String[components.length + 1];
+ System.arraycopy(components, 0, parts, 1, components.length);
- System.arraycopy(components, 0, parts, 1, components.length);
+ // Get IDs.
+ if (client) {
+ List<IgniteUuid> ids = runClientTask(new IgfsClientMetaIdsForPathCallable(cfg.getName(), path));
- // Prepare IDs.
- IgniteUuid[] ids = new IgniteUuid[parts.length];
+ return new IgfsPathIds(path, parts, ids.toArray(new IgniteUuid[ids.size()]));
+ }
+ else {
+ if (busyLock.enterBusy()) {
+ try {
+ validTxState(false);
- ids[0] = IgfsUtils.ROOT_ID;
+ IgniteUuid[] ids = new IgniteUuid[parts.length];
- for (int i = 1; i < ids.length; i++) {
- IgniteUuid id = fileId(ids[i - 1], parts[i], false);
+ ids[0] = IgfsUtils.ROOT_ID;
- if (id != null)
- ids[i] = id;
- else
- break;
- }
+ for (int i = 1; i < ids.length; i++) {
+ IgniteUuid id = fileId(ids[i - 1], parts[i], false);
- // Return.
- return new IgfsPathIds(path, parts, ids);
- }
- finally {
- busyLock.leaveBusy();
+ 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);
}
- else
- throw new IllegalStateException("Failed to get file IDS because Grid is stopping: " + path);
}
/**
@@ -1146,6 +1153,46 @@ public class IgfsMetaManager extends IgfsManager {
}
/**
+ * Wheter operation must be re-tries because we have suspicious links which may broke secondary file system
+ * consistency.
+ *
+ * @param pathIds Path IDs.
+ * @param lockInfos Lock infos.
+ * @return Whether to re-try.
+ */
+ private boolean isRetryForSecondary(IgfsPathIds pathIds, Map<IgniteUuid, IgfsEntryInfo> lockInfos) {
+ // We need to ensure that the last locked info is not linked with expected child.
+ // Otherwise there was some concurrent file system update and we have to re-try.
+ if (!pathIds.allExists()) {
+ // Find the last locked index
+ IgfsEntryInfo lastLockedInfo = null;
+ int lastLockedIdx = -1;
+
+ while (lastLockedIdx < pathIds.lastExistingIndex()) {
+ IgfsEntryInfo nextInfo = lockInfos.get(pathIds.id(lastLockedIdx + 1));
+
+ if (nextInfo != null) {
+ lastLockedInfo = nextInfo;
+ lastLockedIdx++;
+ }
+ else
+ break;
+ }
+
+ assert lastLockedIdx < pathIds.count();
+
+ if (lastLockedInfo != null) {
+ String part = pathIds.part(lastLockedIdx + 1);
+
+ if (lastLockedInfo.listing().containsKey(part))
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
* Move path to the trash directory.
*
* @param path Path.
@@ -1154,8 +1201,8 @@ public class IgfsMetaManager extends IgfsManager {
* @return ID of an entry located directly under the trash directory.
* @throws IgniteCheckedException If failed.
*/
- IgfsDeleteResult softDelete(final IgfsPath path, final boolean recursive, @Nullable IgfsSecondaryFileSystem secondaryFs)
- throws IgniteCheckedException {
+ IgfsDeleteResult softDelete(final IgfsPath path, final boolean recursive,
+ @Nullable IgfsSecondaryFileSystem secondaryFs) throws IgniteCheckedException {
while (true) {
if (busyLock.enterBusy()) {
try {
@@ -1163,16 +1210,8 @@ public class IgfsMetaManager extends IgfsManager {
IgfsPathIds pathIds = pathIds(path);
- boolean relaxed0 = relaxed;
-
- if (!pathIds.allExists()) {
- if (secondaryFs == null)
- // Return early if target path doesn't exist and we do not have secondary file system.
- return new IgfsDeleteResult(false, null);
- else
- // If path is missing partially, we need more serious locking for DUAL mode.
- relaxed0 = false;
- }
+ if (!pathIds.allExists() && secondaryFs == null)
+ return new IgfsDeleteResult(false, null);
IgniteUuid victimId = pathIds.lastId();
String victimName = pathIds.lastPart();
@@ -1183,7 +1222,7 @@ public class IgfsMetaManager extends IgfsManager {
// Prepare IDs to lock.
SortedSet<IgniteUuid> allIds = new TreeSet<>(PATH_ID_SORTING_COMPARATOR);
- pathIds.addExistingIds(allIds, relaxed0);
+ pathIds.addExistingIds(allIds, relaxed);
IgniteUuid trashId = IgfsUtils.randomTrashId();
@@ -1193,38 +1232,11 @@ public class IgfsMetaManager extends IgfsManager {
// Lock participants.
Map<IgniteUuid, IgfsEntryInfo> lockInfos = lockIds(allIds);
- if (!pathIds.allExists()) {
- // We need to ensure that the last locked info is not linked with expected child.
- // Otherwise there was some ocncurrent file system update and we have to re-try.
- assert secondaryFs != null;
-
- // Find the last locked index
- IgfsEntryInfo lastLockedInfo = null;
- int lastLockedIdx = -1;
-
- while (lastLockedIdx < pathIds.lastExistingIndex()) {
- IgfsEntryInfo nextInfo = lockInfos.get(pathIds.id(lastLockedIdx + 1));
-
- if (nextInfo != null) {
- lastLockedInfo = nextInfo;
- lastLockedIdx++;
- }
- else
- break;
- }
-
- assert lastLockedIdx < pathIds.count();
-
- if (lastLockedInfo != null) {
- String part = pathIds.part(lastLockedIdx + 1);
-
- if (lastLockedInfo.listing().containsKey(part))
- continue;
- }
- }
+ if (secondaryFs != null && isRetryForSecondary(pathIds, lockInfos))
+ continue;
// Ensure that all participants are still in place.
- if (!pathIds.allExists() || !pathIds.verifyIntegrity(lockInfos, relaxed0)) {
+ if (!pathIds.allExists() || !pathIds.verifyIntegrity(lockInfos, relaxed)) {
// For DUAL mode we will try to update the underlying FS still. Note we do that inside TX.
if (secondaryFs != null) {
boolean res = secondaryFs.delete(path, recursive);
@@ -1717,7 +1729,7 @@ public class IgfsMetaManager extends IgfsManager {
/**
* Transfer entry from one directory to another.
*
- * @param entry Entry to be transfered.
+ * @param entry Entry to be transferred.
* @param srcId Source ID.
* @param srcName Source name.
* @param destId Destination ID.
@@ -1728,8 +1740,19 @@ public class IgfsMetaManager extends IgfsManager {
IgniteUuid destId, String destName) throws IgniteCheckedException {
validTxState(true);
- id2InfoPrj.invoke(srcId, new IgfsMetaDirectoryListingRemoveProcessor(srcName, entry.fileId()));
- id2InfoPrj.invoke(destId, new IgfsMetaDirectoryListingAddProcessor(destName, entry));
+ if (F.eq(srcId, destId)) {
+ id2InfoPrj.invoke(srcId, new IgfsMetaDirectoryListingRemoveProcessor(srcName, entry.fileId()));
+ id2InfoPrj.invoke(destId, new IgfsMetaDirectoryListingAddProcessor(destName, entry));
+ }
+ 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);
+ }
}
/**
@@ -1786,59 +1809,6 @@ public class IgfsMetaManager extends IgfsManager {
}
/**
- * Create the file in DUAL mode.
- *
- * @param fs File system.
- * @param path Path.
- * @param simpleCreate "Simple create" flag.
- * @param props Properties..
- * @param overwrite Overwrite flag.
- * @param bufSize Buffer size.
- * @param replication Replication factor.
- * @param blockSize Block size.
- * @param affKey Affinity key.
- * @return Output stream descriptor.
- * @throws IgniteCheckedException If file creation failed.
- */
- public IgfsSecondaryOutputStreamDescriptor createDual(final IgfsSecondaryFileSystem fs,
- final IgfsPath path,
- final boolean simpleCreate,
- @Nullable final Map<String, String> props,
- final boolean overwrite,
- final int bufSize,
- final short replication,
- final long blockSize,
- final IgniteUuid affKey)
- throws IgniteCheckedException
- {
- if (busyLock.enterBusy()) {
- try {
- assert fs != null;
- assert path != null;
-
- // Events to fire (can be done outside of a transaction).
- final Deque<IgfsEvent> pendingEvts = new LinkedList<>();
-
- CreateFileSynchronizationTask task = new CreateFileSynchronizationTask(fs, path, simpleCreate, props,
- overwrite, bufSize, replication, blockSize, affKey, pendingEvts);
-
- try {
- return synchronizeAndExecute(task, fs, false, path.parent());
- }
- finally {
- for (IgfsEvent evt : pendingEvts)
- evts.record(evt);
- }
- }
- finally {
- busyLock.leaveBusy();
- }
- }
- else
- throw new IllegalStateException("Failed to create file in DUAL mode because Grid is stopping: " + path);
- }
-
- /**
* Append to a file in DUAL mode.
*
* @param fs File system.
@@ -1847,19 +1817,19 @@ public class IgfsMetaManager extends IgfsManager {
* @return Output stream descriptor.
* @throws IgniteCheckedException If output stream open for append has failed.
*/
- public IgfsSecondaryOutputStreamDescriptor appendDual(final IgfsSecondaryFileSystem fs, final IgfsPath path,
+ public IgfsCreateResult appendDual(final IgfsSecondaryFileSystem fs, final IgfsPath path,
final int bufSize) throws IgniteCheckedException {
if (busyLock.enterBusy()) {
try {
assert fs != null;
assert path != null;
- SynchronizationTask<IgfsSecondaryOutputStreamDescriptor> task =
- new SynchronizationTask<IgfsSecondaryOutputStreamDescriptor>() {
+ SynchronizationTask<IgfsCreateResult> task =
+ new SynchronizationTask<IgfsCreateResult>() {
/** Output stream to the secondary file system. */
private OutputStream out;
- @Override public IgfsSecondaryOutputStreamDescriptor onSuccess(Map<IgfsPath,
+ @Override public IgfsCreateResult onSuccess(Map<IgfsPath,
IgfsEntryInfo> infos) throws Exception {
validTxState(true);
@@ -1898,10 +1868,10 @@ public class IgfsMetaManager extends IgfsManager {
// Set lock and return.
IgfsEntryInfo lockedInfo = invokeLock(info.id(), false);
- return new IgfsSecondaryOutputStreamDescriptor(lockedInfo, out);
+ return new IgfsCreateResult(lockedInfo, out);
}
- @Override public IgfsSecondaryOutputStreamDescriptor onFailure(@Nullable Exception err)
+ @Override public IgfsCreateResult onFailure(@Nullable Exception err)
throws IgniteCheckedException {
U.closeQuiet(out);
@@ -2784,8 +2754,8 @@ public class IgfsMetaManager extends IgfsManager {
}
else {
// Create file and parent folders.
- IgfsPathsCreateResult res =
- createFile(pathIds, lockInfos, dirProps, fileProps, blockSize, affKey, evictExclude);
+ IgfsPathsCreateResult res = createFile(pathIds, lockInfos, dirProps, fileProps, blockSize,
+ affKey, evictExclude, null);
if (res == null)
continue;
@@ -2819,21 +2789,25 @@ public class IgfsMetaManager extends IgfsManager {
* @param affKey Affinity key.
* @param evictExclude Evict exclude flag.
* @param fileProps File properties.
- * @return @return Resulting info.
+ * @param secondaryCtx Secondary file system create context.
+ * @return @return Operation result.
* @throws IgniteCheckedException If failed.
*/
- IgfsEntryInfo create(
+ IgfsCreateResult create(
final IgfsPath path,
Map<String, String> dirProps,
final boolean overwrite,
final int blockSize,
final @Nullable IgniteUuid affKey,
final boolean evictExclude,
- @Nullable Map<String, String> fileProps) throws IgniteCheckedException {
+ @Nullable Map<String, String> fileProps,
+ @Nullable IgfsSecondaryFileSystemCreateContext secondaryCtx) throws IgniteCheckedException {
validTxState(false);
while (true) {
if (busyLock.enterBusy()) {
+ OutputStream secondaryOut = null;
+
try {
// Prepare path IDs.
IgfsPathIds pathIds = pathIds(path);
@@ -2860,6 +2834,9 @@ public class IgfsMetaManager extends IgfsManager {
try (IgniteInternalTx tx = startTx()) {
Map<IgniteUuid, IgfsEntryInfo> lockInfos = lockIds(lockIds);
+ if (secondaryCtx != null && isRetryForSecondary(pathIds, lockInfos))
+ continue;
+
if (!pathIds.verifyIntegrity(lockInfos, relaxed))
// Directory structure changed concurrently. So we simply re-try.
continue;
@@ -2882,35 +2859,71 @@ public class IgfsMetaManager extends IgfsManager {
// At this point file can be re-created safely.
- // First step: add existing to trash listing.
+ // Add existing to trash listing.
IgniteUuid oldId = pathIds.lastId();
id2InfoPrj.invoke(trashId, new IgfsMetaDirectoryListingAddProcessor(oldId.toString(),
new IgfsListingEntry(oldInfo)));
- // Second step: replace ID in parent directory.
+ // Replace ID in parent directory.
String name = pathIds.lastPart();
IgniteUuid parentId = pathIds.lastParentId();
id2InfoPrj.invoke(parentId, new IgfsMetaDirectoryListingReplaceProcessor(name, overwriteId));
- // Third step: create the file.
- long createTime = System.currentTimeMillis();
+ // Create the file.
+ IgniteUuid newLockId = createFileLockId(false);
+
+ long newAccessTime;
+ long newModificationTime;
+ Map<String, String> newProps;
+ long newLen;
+ int newBlockSize;
+
+ if (secondaryCtx != null) {
+ secondaryOut = secondaryCtx.create();
- IgfsEntryInfo newInfo = invokeAndGet(overwriteId, new IgfsMetaFileCreateProcessor(createTime,
- fileProps, blockSize, affKey, createFileLockId(false), evictExclude));
+ IgfsFile secondaryFile = secondaryCtx.info();
+
+ if (secondaryFile == null)
+ throw fsException("Failed to open output stream to the file created in " +
+ "the secondary file system because it no longer exists: " + path);
+ else if (secondaryFile.isDirectory())
+ throw fsException("Failed to open output stream to the file created in " +
+ "the secondary file system because the path points to a directory: " + path);
+
+ newAccessTime = secondaryFile.accessTime();
+ newModificationTime = secondaryFile.modificationTime();
+ newProps = secondaryFile.properties();
+ newLen = secondaryFile.length();
+ newBlockSize = secondaryFile.blockSize();
+ }
+ else {
+ newAccessTime = System.currentTimeMillis();
+ newModificationTime = newAccessTime;
+ newProps = fileProps;
+ newLen = 0L;
+ newBlockSize = blockSize;
+ }
+
+ IgfsEntryInfo newInfo = invokeAndGet(overwriteId,
+ new IgfsMetaFileCreateProcessor(newAccessTime, newModificationTime, newProps,
+ newBlockSize, affKey, newLockId, evictExclude, newLen));
// Prepare result and commit.
tx.commit();
IgfsUtils.sendEvents(igfsCtx.kernalContext(), path, EventType.EVT_IGFS_FILE_OPENED_WRITE);
- return newInfo;
+ return new IgfsCreateResult(newInfo, secondaryOut);
}
else {
// Create file and parent folders.
- IgfsPathsCreateResult res =
- createFile(pathIds, lockInfos, dirProps, fileProps, blockSize, affKey, evictExclude);
+ if (secondaryCtx != null)
+ secondaryOut = secondaryCtx.create();
+
+ IgfsPathsCreateResult res = createFile(pathIds, lockInfos, dirProps, fileProps, blockSize,
+ affKey, evictExclude, secondaryCtx);
if (res == null)
continue;
@@ -2921,10 +2934,20 @@ public class IgfsMetaManager extends IgfsManager {
// Generate events.
generateCreateEvents(res.createdPaths(), true);
- return res.info();
+ return new IgfsCreateResult(res.info(), secondaryOut);
}
}
}
+ catch (IgniteException | IgniteCheckedException e) {
+ U.closeQuiet(secondaryOut);
+
+ throw e;
+ }
+ catch (Exception e) {
+ U.closeQuiet(secondaryOut);
+
+ throw new IgniteCheckedException("Create failed due to unexpected exception: " + path, e);
+ }
finally {
busyLock.leaveBusy();
}
@@ -2950,7 +2973,7 @@ public class IgfsMetaManager extends IgfsManager {
throw new IgfsParentNotDirectoryException("Failed to create directory (parent " +
"element is not a directory)");
- return createFileOrDirectory(true, pathIds, lockInfos, dirProps, null, 0, null, false);
+ return createFileOrDirectory(true, pathIds, lockInfos, dirProps, null, 0, null, false, null);
}
/**
@@ -2963,22 +2986,25 @@ public class IgfsMetaManager extends IgfsManager {
* @param blockSize Block size.
* @param affKey Affinity key (optional)
* @param evictExclude Evict exclude flag.
+ * @param secondaryCtx Secondary file system create context.
* @return Result or {@code} if the first parent already contained child with the same name.
* @throws IgniteCheckedException If failed.
*/
@Nullable private IgfsPathsCreateResult createFile(IgfsPathIds pathIds, Map<IgniteUuid, IgfsEntryInfo> lockInfos,
Map<String, String> dirProps, Map<String, String> fileProps, int blockSize, @Nullable IgniteUuid affKey,
- boolean evictExclude) throws IgniteCheckedException{
+ boolean evictExclude, @Nullable IgfsSecondaryFileSystemCreateContext secondaryCtx)
+ throws IgniteCheckedException{
// Check if entry we are going to write to is directory.
if (lockInfos.get(pathIds.lastExistingId()).isFile())
throw new IgfsParentNotDirectoryException("Failed to open file for write " +
"(parent element is not a directory): " + pathIds.path());
- return createFileOrDirectory(false, pathIds, lockInfos, dirProps, fileProps, blockSize, affKey, evictExclude);
+ return createFileOrDirectory(false, pathIds, lockInfos, dirProps, fileProps, blockSize, affKey, evictExclude,
+ secondaryCtx);
}
/**
- * Ceate file or directory.
+ * Create file or directory.
*
* @param dir Directory flag.
* @param pathIds Path IDs.
@@ -2988,12 +3014,15 @@ public class IgfsMetaManager extends IgfsManager {
* @param blockSize Block size.
* @param affKey Affinity key.
* @param evictExclude Evict exclude flag.
+ * @param secondaryCtx Secondary file system create context.
* @return Result.
* @throws IgniteCheckedException If failed.
*/
+ @SuppressWarnings("unchecked")
private IgfsPathsCreateResult createFileOrDirectory(boolean dir, IgfsPathIds pathIds,
Map<IgniteUuid, IgfsEntryInfo> lockInfos, Map<String, String> dirProps, Map<String, String> fileProps,
- int blockSize, @Nullable IgniteUuid affKey, boolean evictExclude) throws IgniteCheckedException {
+ int blockSize, @Nullable IgniteUuid affKey, boolean evictExclude,
+ @Nullable IgfsSecondaryFileSystemCreateContext secondaryCtx) throws IgniteCheckedException {
// This is our starting point.
int lastExistingIdx = pathIds.lastExistingIndex();
IgfsEntryInfo lastExistingInfo = lockInfos.get(pathIds.lastExistingId());
@@ -3009,8 +3038,10 @@ public class IgfsMetaManager extends IgfsManager {
if (lastExistingInfo.hasChild(curPart))
return null;
+ Map<IgniteUuid, EntryProcessor> procMap = new HashMap<>();
+
// First step: add new entry to the last existing element.
- id2InfoPrj.invoke(lastExistingInfo.id(), new IgfsMetaDirectoryListingAddProcessor(curPart,
+ procMap.put(lastExistingInfo.id(), new IgfsMetaDirectoryListingAddProcessor(curPart,
new IgfsListingEntry(curId, dir || !pathIds.isLastIndex(curIdx))));
// Events support.
@@ -3019,20 +3050,44 @@ public class IgfsMetaManager extends IgfsManager {
List<IgfsPath> createdPaths = new ArrayList<>(pathIds.count() - curIdx);
// Second step: create middle directories.
- long createTime = System.currentTimeMillis();
+ long curTime = System.currentTimeMillis();
while (curIdx < pathIds.count() - 1) {
+ lastCreatedPath = new IgfsPath(lastCreatedPath, curPart);
+
int nextIdx = curIdx + 1;
String nextPart = pathIds.part(nextIdx);
IgniteUuid nextId = pathIds.surrogateId(nextIdx);
- id2InfoPrj.invoke(curId, new IgfsMetaDirectoryCreateProcessor(createTime, dirProps,
+ long accessTime;
+ long modificationTime;
+ Map<String, String> props;
+
+ if (secondaryCtx != null) {
+ IgfsFile secondaryInfo = secondaryCtx.fileSystem().info(lastCreatedPath);
+
+ if (secondaryInfo == null)
+ throw new IgfsException("Failed to perform operation because secondary file system path was " +
+ "modified concurrnetly: " + lastCreatedPath);
+ else if (secondaryInfo.isFile())
+ throw new IgfsException("Failed to perform operation because secondary file system entity is " +
+ "not directory: " + lastCreatedPath);
+
+ accessTime = secondaryInfo.accessTime();
+ modificationTime = secondaryInfo.modificationTime();
+ props = secondaryInfo.properties();
+ }
+ else {
+ accessTime = curTime;
+ modificationTime = curTime;
+ props = dirProps;
+ }
+
+ procMap.put(curId, new IgfsMetaDirectoryCreateProcessor(accessTime, modificationTime, props,
nextPart, new IgfsListingEntry(nextId, dir || !pathIds.isLastIndex(nextIdx))));
// Save event.
- lastCreatedPath = new IgfsPath(lastCreatedPath, curPart);
-
createdPaths.add(lastCreatedPath);
// Advance things further.
@@ -3043,16 +3098,75 @@ public class IgfsMetaManager extends IgfsManager {
}
// Third step: create leaf.
- IgfsEntryInfo info;
+ if (dir) {
+ long accessTime;
+ long modificationTime;
+ Map<String, String> props;
- if (dir)
- info = invokeAndGet(curId, new IgfsMetaDirectoryCreateProcessor(createTime, dirProps));
- else
- info = invokeAndGet(curId, new IgfsMetaFileCreateProcessor(createTime, fileProps,
- blockSize, affKey, createFileLockId(false), evictExclude));
+ if (secondaryCtx != null) {
+ IgfsFile secondaryInfo = secondaryCtx.fileSystem().info(pathIds.path());
+
+ if (secondaryInfo == null)
+ throw new IgfsException("Failed to perform operation because secondary file system path was " +
+ "modified concurrnetly: " + pathIds.path());
+ else if (secondaryInfo.isFile())
+ throw new IgfsException("Failed to perform operation because secondary file system entity is " +
+ "not directory: " + lastCreatedPath);
+
+ accessTime = secondaryInfo.accessTime();
+ modificationTime = secondaryInfo.modificationTime();
+ props = secondaryInfo.properties();
+ }
+ else {
+ accessTime = curTime;
+ modificationTime = curTime;
+ props = dirProps;
+ }
+
+ procMap.put(curId, new IgfsMetaDirectoryCreateProcessor(accessTime, modificationTime, props));
+ }
+ else {
+ long newAccessTime;
+ long newModificationTime;
+ Map<String, String> newProps;
+ long newLen;
+ int newBlockSize;
+
+ if (secondaryCtx != null) {
+ IgfsFile secondaryFile = secondaryCtx.info();
+
+ if (secondaryFile == null)
+ throw fsException("Failed to open output stream to the file created in " +
+ "the secondary file system because it no longer exists: " + pathIds.path());
+ else if (secondaryFile.isDirectory())
+ throw fsException("Failed to open output stream to the file created in " +
+ "the secondary file system because the path points to a directory: " + pathIds.path());
+
+ newAccessTime = secondaryFile.accessTime();
+ newModificationTime = secondaryFile.modificationTime();
+ newProps = secondaryFile.properties();
+ newLen = secondaryFile.length();
+ newBlockSize = secondaryFile.blockSize();
+ }
+ else {
+ newAccessTime = curTime;
+ newModificationTime = curTime;
+ newProps = fileProps;
+ newLen = 0L;
+ newBlockSize = blockSize;
+ }
+
+ procMap.put(curId, new IgfsMetaFileCreateProcessor(newAccessTime, newModificationTime, newProps,
+ newBlockSize, affKey, createFileLockId(false), evictExclude, newLen));
+ }
createdPaths.add(pathIds.path());
+ // Execute cache operations.
+ Map<Object, EntryProcessorResult> invokeRes = ((IgniteInternalCache)id2InfoPrj).invokeAll(procMap);
+
+ IgfsEntryInfo info = (IgfsEntryInfo)invokeRes.get(curId).get();
+
return new IgfsPathsCreateResult(createdPaths, info);
}
@@ -3111,182 +3225,4 @@ public class IgfsMetaManager extends IgfsManager {
*/
public T onFailure(Exception err) throws IgniteCheckedException;
}
-
- /**
- * Synchronization task to create a file.
- */
- private class CreateFileSynchronizationTask implements SynchronizationTask<IgfsSecondaryOutputStreamDescriptor> {
- /** Secondary file system. */
- private IgfsSecondaryFileSystem fs;
-
- /** Path. */
- private IgfsPath path;
-
- /** Simple create flag. */
- private boolean simpleCreate;
-
- /** Properties. */
- private Map<String, String> props;
-
- /** Overwrite flag. */
- private boolean overwrite;
-
- /** Buffer size. */
- private int bufSize;
-
- /** Replication factor. */
- private short replication;
-
- /** Block size. */
- private long blockSize;
-
- /** Affinity key. */
- private IgniteUuid affKey;
-
- /** Pending events. */
- private Deque<IgfsEvent> pendingEvts;
-
- /** Output stream to the secondary file system. */
- private OutputStream out;
-
- /**
- * Constructor.
- *
- * @param fs Secondary file system.
- * @param path Path.
- * @param simpleCreate Simple create flag.
- * @param props Properties.
- * @param overwrite Overwrite flag.
- * @param bufSize Buffer size.
- * @param replication Replication factor.
- * @param blockSize Block size.
- * @param affKey Affinity key.
- * @param pendingEvts Pending events.
- */
- public CreateFileSynchronizationTask(IgfsSecondaryFileSystem fs, IgfsPath path, boolean simpleCreate,
- @Nullable Map<String, String> props, boolean overwrite, int bufSize, short replication, long blockSize,
- IgniteUuid affKey, Deque<IgfsEvent> pendingEvts) {
- this.fs = fs;
- this.path = path;
- this.simpleCreate = simpleCreate;
- this.props = props;
- this.overwrite = overwrite;
- this.bufSize = bufSize;
- this.replication = replication;
- this.blockSize = blockSize;
- this.affKey = affKey;
- this.pendingEvts = pendingEvts;
- }
-
- /** {@inheritDoc} */
- @Override public IgfsSecondaryOutputStreamDescriptor onSuccess(Map<IgfsPath, IgfsEntryInfo> infos)
- throws Exception {
- validTxState(true);
-
- assert !infos.isEmpty();
-
- // Determine the first existing parent.
- IgfsPath parentPath = null;
-
- for (IgfsPath curPath : infos.keySet()) {
- if (parentPath == null || curPath.isSubDirectoryOf(parentPath))
- parentPath = curPath;
- }
-
- assert parentPath != null;
-
- IgfsEntryInfo parentInfo = infos.get(parentPath);
-
- // Delegate to the secondary file system.
- out = simpleCreate ? fs.create(path, overwrite) :
- fs.create(path, bufSize, overwrite, replication, blockSize, props);
-
- IgfsPath parent0 = path.parent();
-
- assert parent0 != null : "path.parent() is null (are we creating ROOT?): " + path;
-
- // If some of the parent directories were missing, synchronize again.
- if (!parentPath.equals(parent0)) {
- parentInfo = synchronize(fs, parentPath, parentInfo, parent0, true, null);
-
- // Fire notification about missing directories creation.
- if (evts.isRecordable(EventType.EVT_IGFS_DIR_CREATED)) {
- IgfsPath evtPath = parent0;
-
- while (!parentPath.equals(evtPath)) {
- pendingEvts.addFirst(new IgfsEvent(evtPath, locNode,
- EventType.EVT_IGFS_DIR_CREATED));
-
- evtPath = evtPath.parent();
-
- assert evtPath != null; // If this fails, then ROOT does not exist.
- }
- }
- }
-
- // Get created file info.
- IgfsFile status = fs.info(path);
-
- if (status == null)
- throw fsException("Failed to open output stream to the file created in " +
- "the secondary file system because it no longer exists: " + path);
- else if (status.isDirectory())
- throw fsException("Failed to open output stream to the file created in " +
- "the secondary file system because the path points to a directory: " + path);
-
- IgfsEntryInfo newInfo = IgfsUtils.createFile(
- IgniteUuid.randomUuid(),
- status.blockSize(),
- status.length(),
- affKey,
- createFileLockId(false),
- igfsCtx.igfs().evictExclude(path, false),
- status.properties(),
- status.accessTime(),
- status.modificationTime()
- );
-
- // Add new file info to the listing optionally removing the previous one.
- assert parentInfo != null;
-
- IgniteUuid oldId = putIfAbsentNonTx(parentInfo.id(), path.name(), newInfo);
-
- if (oldId != null) {
- IgfsEntryInfo oldInfo = info(oldId);
-
- assert oldInfo != null; // Otherwise cache is in inconsistent state.
-
- // The contact is that we cannot overwrite a file locked for writing:
- if (oldInfo.lockId() != null)
- throw fsException("Failed to overwrite file (file is opened for writing) [path=" +
- path + ", fileId=" + oldId + ", lockId=" + oldInfo.lockId() + ']');
-
- id2InfoPrj.remove(oldId); // Remove the old one.
- id2InfoPrj.invoke(parentInfo.id(), new IgfsMetaDirectoryListingRemoveProcessor(
- path.name(), parentInfo.listing().get(path.name()).fileId()));
-
- createNewEntry(newInfo, parentInfo.id(), path.name()); // Put new one.
-
- igfsCtx.data().delete(oldInfo);
- }
-
- // Record CREATE event if needed.
- if (oldId == null && evts.isRecordable(EventType.EVT_IGFS_FILE_CREATED))
- pendingEvts.add(new IgfsEvent(path, locNode, EventType.EVT_IGFS_FILE_CREATED));
-
- return new IgfsSecondaryOutputStreamDescriptor(newInfo, out);
- }
-
- /** {@inheritDoc} */
- @Override public IgfsSecondaryOutputStreamDescriptor onFailure(Exception err) throws IgniteCheckedException {
- U.closeQuiet(out);
-
- U.error(log, "File create in DUAL mode failed [path=" + path + ", simpleCreate=" +
- simpleCreate + ", props=" + props + ", overwrite=" + overwrite + ", bufferSize=" +
- bufSize + ", replication=" + replication + ", blockSize=" + blockSize + ']', err);
-
- throw new IgniteCheckedException("Failed to create the file due to secondary file system " +
- "exception: " + path, err);
- }
- }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/40e6614f/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsSecondaryFileSystemCreateContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsSecondaryFileSystemCreateContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsSecondaryFileSystemCreateContext.java
new file mode 100644
index 0000000..1c0efd6
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsSecondaryFileSystemCreateContext.java
@@ -0,0 +1,111 @@
+/*
+ * 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.ignite.internal.processors.igfs;
+
+import org.apache.ignite.igfs.IgfsFile;
+import org.apache.ignite.igfs.IgfsPath;
+import org.apache.ignite.igfs.secondary.IgfsSecondaryFileSystem;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.OutputStream;
+import java.util.Map;
+
+/**
+ * Context for secondary file system create request.
+ */
+public class IgfsSecondaryFileSystemCreateContext {
+ /** File system. */
+ private final IgfsSecondaryFileSystem fs;
+
+ /** Path. */
+ private final IgfsPath path;
+
+ /** Overwrite flag. */
+ private final boolean overwrite;
+
+ /** Simple create flag. */
+ private final boolean simpleCreate;
+
+ /** Properties. */
+ private final Map<String, String> props;
+
+ /** Replication. */
+ private final short replication;
+
+ /** Block size. */
+ private final long blockSize;
+
+ /** Buffer size. */
+ private final int bufSize;
+
+ /**
+ * Constructor.
+ *
+ * @param fs File system.
+ * @param path Path.
+ * @param overwrite Overwrite flag.
+ * @param simpleCreate Simple create flag.
+ * @param props Properties.
+ * @param replication Replication.
+ * @param blockSize Block size.
+ * @param bufSize Buffer size.
+ */
+ public IgfsSecondaryFileSystemCreateContext(IgfsSecondaryFileSystem fs, IgfsPath path, boolean overwrite,
+ boolean simpleCreate, @Nullable Map<String, String> props, short replication, long blockSize, int bufSize) {
+ this.fs = fs;
+ this.path = path;
+ this.overwrite = overwrite;
+ this.simpleCreate = simpleCreate;
+ this.props = props;
+ this.replication = replication;
+ this.blockSize = blockSize;
+ this.bufSize = bufSize;
+ }
+
+ /**
+ * Create file in the secondary file system.
+ *
+ * @return Output stream.
+ */
+ public OutputStream create() {
+ return simpleCreate ? fs.create(path, overwrite) :
+ fs.create(path, bufSize, overwrite, replication, blockSize, props);
+ }
+
+ /**
+ * Get file info.
+ *
+ * @return File.
+ */
+ public IgfsFile info() {
+ return fs.info(path);
+ }
+
+ /**
+ * @return Secondary file system.
+ */
+ public IgfsSecondaryFileSystem fileSystem() {
+ return fs;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(IgfsSecondaryFileSystemCreateContext.class, this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/40e6614f/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsSecondaryOutputStreamDescriptor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsSecondaryOutputStreamDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsSecondaryOutputStreamDescriptor.java
deleted file mode 100644
index 6bbc2c0..0000000
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/IgfsSecondaryOutputStreamDescriptor.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.ignite.internal.processors.igfs;
-
-import java.io.OutputStream;
-
-/**
- * Descriptor of an output stream opened to the secondary file system.
- */
-public class IgfsSecondaryOutputStreamDescriptor {
- /** File info in the primary file system. */
- private final IgfsEntryInfo info;
-
- /** Output stream to the secondary file system. */
- private final OutputStream out;
-
- /**
- * Constructor.
- *
- * @param info File info in the primary file system.
- * @param out Output stream to the secondary file system.
- */
- IgfsSecondaryOutputStreamDescriptor(IgfsEntryInfo info, OutputStream out) {
- assert info != null;
- assert out != null;
-
- this.info = info;
- this.out = out;
- }
-
- /**
- * @return File info in the primary file system.
- */
- IgfsEntryInfo info() {
- return info;
- }
-
- /**
- * @return Output stream to the secondary file system.
- */
- OutputStream out() {
- return out;
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/40e6614f/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/meta/IgfsMetaDirectoryCreateProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/meta/IgfsMetaDirectoryCreateProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/meta/IgfsMetaDirectoryCreateProcessor.java
index eee9300..b016633 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/meta/IgfsMetaDirectoryCreateProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/meta/IgfsMetaDirectoryCreateProcessor.java
@@ -48,8 +48,11 @@ public class IgfsMetaDirectoryCreateProcessor implements EntryProcessor<IgniteUu
/** */
private static final long serialVersionUID = 0L;
- /** Create time. */
- private long createTime;
+ /** Access time. */
+ private long accessTime;
+
+ /** Modification time. */
+ private long modificationTime;
/** Properties. */
private Map<String, String> props;
@@ -70,24 +73,27 @@ public class IgfsMetaDirectoryCreateProcessor implements EntryProcessor<IgniteUu
/**
* Constructor.
*
- * @param createTime Create time.
+ * @param accessTime Create time.
+ * @param modificationTime Modification time.
* @param props Properties.
*/
- public IgfsMetaDirectoryCreateProcessor(long createTime, Map<String, String> props) {
- this(createTime, props, null, null);
+ public IgfsMetaDirectoryCreateProcessor(long accessTime, long modificationTime, Map<String, String> props) {
+ this(accessTime, modificationTime, props, null, null);
}
/**
* Constructor.
*
- * @param createTime Create time.
+ * @param accessTime Create time.
+ * @param modificationTime Modification time.
* @param props Properties.
* @param childName Child name.
* @param childEntry Child entry.
*/
- public IgfsMetaDirectoryCreateProcessor(long createTime, Map<String, String> props, String childName,
- IgfsListingEntry childEntry) {
- this.createTime = createTime;
+ public IgfsMetaDirectoryCreateProcessor(long accessTime, long modificationTime, Map<String, String> props,
+ String childName, IgfsListingEntry childEntry) {
+ this.accessTime = accessTime;
+ this.modificationTime = modificationTime;
this.props = props;
this.childName = childName;
this.childEntry = childEntry;
@@ -101,8 +107,8 @@ public class IgfsMetaDirectoryCreateProcessor implements EntryProcessor<IgniteUu
entry.getKey(),
null,
props,
- createTime,
- createTime
+ accessTime,
+ modificationTime
);
if (childName != null)
@@ -115,7 +121,8 @@ public class IgfsMetaDirectoryCreateProcessor implements EntryProcessor<IgniteUu
/** {@inheritDoc} */
@Override public void writeExternal(ObjectOutput out) throws IOException {
- out.writeLong(createTime);
+ out.writeLong(accessTime);
+ out.writeLong(modificationTime);
IgfsUtils.writeProperties(out, props);
@@ -127,7 +134,8 @@ public class IgfsMetaDirectoryCreateProcessor implements EntryProcessor<IgniteUu
/** {@inheritDoc} */
@Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
- createTime = in.readLong();
+ accessTime = in.readLong();
+ modificationTime = in.readLong();
props = IgfsUtils.readProperties(in);
@@ -141,7 +149,8 @@ public class IgfsMetaDirectoryCreateProcessor implements EntryProcessor<IgniteUu
@Override public void writeBinary(BinaryWriter writer) throws BinaryObjectException {
BinaryRawWriter out = writer.rawWriter();
- out.writeLong(createTime);
+ out.writeLong(accessTime);
+ out.writeLong(modificationTime);
IgfsUtils.writeProperties(out, props);
@@ -155,7 +164,8 @@ public class IgfsMetaDirectoryCreateProcessor implements EntryProcessor<IgniteUu
@Override public void readBinary(BinaryReader reader) throws BinaryObjectException {
BinaryRawReader in = reader.rawReader();
- createTime = in.readLong();
+ accessTime = in.readLong();
+ modificationTime = in.readLong();
props = IgfsUtils.readProperties(in);
http://git-wip-us.apache.org/repos/asf/ignite/blob/40e6614f/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/meta/IgfsMetaFileCreateProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/meta/IgfsMetaFileCreateProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/meta/IgfsMetaFileCreateProcessor.java
index 8c4c296..a3e9d48 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/meta/IgfsMetaFileCreateProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/igfs/meta/IgfsMetaFileCreateProcessor.java
@@ -49,7 +49,10 @@ public class IgfsMetaFileCreateProcessor implements EntryProcessor<IgniteUuid, I
private static final long serialVersionUID = 0L;
/** Create time. */
- private long createTime;
+ private long accessTime;
+
+ /** Modification time. */
+ private long modificationTime;
/** Properties. */
private Map<String, String> props;
@@ -66,6 +69,9 @@ public class IgfsMetaFileCreateProcessor implements EntryProcessor<IgniteUuid, I
/** Evict exclude flag. */
private boolean evictExclude;
+ /** File length. */
+ private long len;
+
/**
* Constructor.
*/
@@ -76,21 +82,25 @@ public class IgfsMetaFileCreateProcessor implements EntryProcessor<IgniteUuid, I
/**
* Constructor.
*
- * @param createTime Create time.
+ * @param accessTime Access time.
+ * @param modificationTime Modification time.
* @param props Properties.
* @param blockSize Block size.
* @param affKey Affinity key.
* @param lockId Lock ID.
* @param evictExclude Evict exclude flag.
+ * @param len File length.
*/
- public IgfsMetaFileCreateProcessor(long createTime, Map<String, String> props, int blockSize,
- @Nullable IgniteUuid affKey, IgniteUuid lockId, boolean evictExclude) {
- this.createTime = createTime;
+ public IgfsMetaFileCreateProcessor(long accessTime, long modificationTime, Map<String, String> props,
+ int blockSize, @Nullable IgniteUuid affKey, IgniteUuid lockId, boolean evictExclude, long len) {
+ this.accessTime = accessTime;
+ this.modificationTime = modificationTime;
this.props = props;
this.blockSize = blockSize;
this.affKey = affKey;
this.lockId = lockId;
this.evictExclude = evictExclude;
+ this.len = len;
}
/** {@inheritDoc} */
@@ -99,13 +109,13 @@ public class IgfsMetaFileCreateProcessor implements EntryProcessor<IgniteUuid, I
IgfsEntryInfo info = IgfsUtils.createFile(
entry.getKey(),
blockSize,
- 0L,
+ len,
affKey,
lockId,
evictExclude,
props,
- createTime,
- createTime
+ accessTime,
+ modificationTime
);
entry.setValue(info);
@@ -115,7 +125,8 @@ public class IgfsMetaFileCreateProcessor implements EntryProcessor<IgniteUuid, I
/** {@inheritDoc} */
@Override public void writeExternal(ObjectOutput out) throws IOException {
- out.writeLong(createTime);
+ out.writeLong(accessTime);
+ out.writeLong(modificationTime);
IgfsUtils.writeProperties(out, props);
@@ -123,11 +134,14 @@ public class IgfsMetaFileCreateProcessor implements EntryProcessor<IgniteUuid, I
U.writeGridUuid(out, affKey);
U.writeGridUuid(out, lockId);
out.writeBoolean(evictExclude);
+
+ out.writeLong(len);
}
/** {@inheritDoc} */
@Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
- createTime = in.readLong();
+ accessTime = in.readLong();
+ modificationTime = in.readLong();
props = IgfsUtils.readProperties(in);
@@ -135,13 +149,16 @@ public class IgfsMetaFileCreateProcessor implements EntryProcessor<IgniteUuid, I
affKey = U.readGridUuid(in);
lockId = U.readGridUuid(in);
evictExclude = in.readBoolean();
+
+ len = in.readLong();
}
/** {@inheritDoc} */
@Override public void writeBinary(BinaryWriter writer) throws BinaryObjectException {
BinaryRawWriter out = writer.rawWriter();
- out.writeLong(createTime);
+ out.writeLong(accessTime);
+ out.writeLong(modificationTime);
IgfsUtils.writeProperties(out, props);
@@ -149,13 +166,16 @@ public class IgfsMetaFileCreateProcessor implements EntryProcessor<IgniteUuid, I
BinaryUtils.writeIgniteUuid(out, affKey);
BinaryUtils.writeIgniteUuid(out, lockId);
out.writeBoolean(evictExclude);
+
+ out.writeLong(len);
}
/** {@inheritDoc} */
@Override public void readBinary(BinaryReader reader) throws BinaryObjectException {
BinaryRawReader in = reader.rawReader();
- createTime = in.readLong();
+ accessTime = in.readLong();
+ modificationTime = in.readLong();
props = IgfsUtils.readProperties(in);
@@ -163,6 +183,8 @@ public class IgfsMetaFileCreateProcessor implements EntryProcessor<IgniteUuid, I
affKey = BinaryUtils.readIgniteUuid(in);
lockId = BinaryUtils.readIgniteUuid(in);
evictExclude = in.readBoolean();
+
+ len = in.readLong();
}
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/ignite/blob/40e6614f/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsMetaManagerSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsMetaManagerSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsMetaManagerSelfTest.java
index 8b88157..6053d3b 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsMetaManagerSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsMetaManagerSelfTest.java
@@ -142,7 +142,7 @@ public class IgfsMetaManagerSelfTest extends IgfsCommonAbstractTest {
assertEmpty(mgr.directoryListing(ROOT_ID));
assertTrue(mgr.mkdirs(new IgfsPath("/dir"), IgfsImpl.DFLT_DIR_META));
- assertNotNull(mgr.create(new IgfsPath("/file"), null, false, 400, null, false, null));
+ assertNotNull(mgr.create(new IgfsPath("/file"), null, false, 400, null, false, null, null));
IgfsListingEntry dirEntry = mgr.directoryListing(ROOT_ID).get("dir");
assertNotNull(dirEntry);
@@ -214,7 +214,7 @@ public class IgfsMetaManagerSelfTest extends IgfsCommonAbstractTest {
private IgfsEntryInfo createFileAndGetInfo(String path) throws IgniteCheckedException {
IgfsPath p = path(path);
- IgfsEntryInfo res = mgr.create(p, null, false, 400, null, false, null);
+ IgfsEntryInfo res = mgr.create(p, null, false, 400, null, false, null, null).info();
assert res != null;
assert !res.isDirectory();