@@ -69,23 +69,28 @@ public class MkdirOperation extends ExecutingStoreOperation<Boolean> {
6969
7070 private final boolean performanceCreation ;
7171
72+ private final boolean isMagicPath ;
73+
7274 /**
7375 * Initialize Mkdir Operation context for S3A.
7476 *
7577 * @param storeContext Store context.
7678 * @param dir Dir path of the directory.
7779 * @param callbacks MkdirCallbacks object used by the Mkdir operation.
80+ * @param isMagicPath True if the path is magic commit path.
7881 * @param performanceCreation If true, skip validation of the parent directory
7982 * structure.
8083 */
8184 public MkdirOperation (
8285 final StoreContext storeContext ,
8386 final Path dir ,
8487 final MkdirCallbacks callbacks ,
88+ final boolean isMagicPath ,
8589 final boolean performanceCreation ) {
8690 super (storeContext );
8791 this .dir = dir ;
8892 this .callbacks = callbacks ;
93+ this .isMagicPath = isMagicPath ;
8994 this .performanceCreation = performanceCreation ;
9095 }
9196
@@ -107,13 +112,14 @@ public Boolean execute() throws IOException {
107112 }
108113
109114 // get the file status of the path.
110- // this is not done for magic path i.e. performanceCreation mode.
111- // For performanceCreation mode, we would probe for HEAD only.
112- // For non-performance or regular mode, the probe for both HEAD and LIST would
113- // be done.
114- S3AFileStatus fileStatus = performanceCreation
115- ? probePathStatusOrNull (dir , StatusProbeEnum .HEAD_ONLY )
116- : getPathStatusExpectingDir (dir );
115+ // this is done even for a magic path, to avoid always issuing PUT
116+ // requests. Doing that without a check wouild seem to be an
117+ // optimization, but it is not because
118+ // 1. PUT is slower than HEAD
119+ // 2. Write capacity is less than read capacity on a shard
120+ // 3. It adds needless entries in versioned buckets, slowing
121+ // down subsequent operations.
122+ FileStatus fileStatus = getPathStatusExpectingDir (dir );
117123 if (fileStatus != null ) {
118124 if (fileStatus .isDirectory ()) {
119125 return true ;
@@ -123,6 +129,15 @@ public Boolean execute() throws IOException {
123129 }
124130 // file status was null
125131
132+ // is the path magic?
133+ // If so, we declare success without looking any further
134+ if (isMagicPath ) {
135+ // Create the marker file immediately,
136+ // and don't delete markers
137+ callbacks .createFakeDirectory (dir , true );
138+ return true ;
139+ }
140+
126141 // if performance creation mode is set, no need to check
127142 // whether the closest ancestor is dir.
128143 if (!performanceCreation ) {
@@ -134,8 +149,7 @@ public Boolean execute() throws IOException {
134149
135150 // Create the marker file, delete the parent entries
136151 // if the filesystem isn't configured to retain them
137- callbacks .createFakeDirectory (dir ,
138- performanceCreation );
152+ callbacks .createFakeDirectory (dir , false );
139153 return true ;
140154 }
141155
@@ -212,7 +226,7 @@ private S3AFileStatus getPathStatusExpectingDir(final Path path)
212226 throws IOException {
213227 S3AFileStatus status = probePathStatusOrNull (path ,
214228 StatusProbeEnum .DIRECTORIES );
215- if (status == null && !performanceCreation ) {
229+ if (status == null && !isMagicPath ) {
216230 status = probePathStatusOrNull (path ,
217231 StatusProbeEnum .FILE );
218232 }
0 commit comments