6161
6262import static org .apache .hadoop .ozone .OzoneConsts .QUOTA_RESET ;
6363import static org .apache .hadoop .ozone .OzoneConsts .OZONE_URI_DELIMITER ;
64+ import static org .apache .hadoop .ozone .om .exceptions .OMException .ResultCodes .FILE_NOT_FOUND ;
6465
6566/**
6667 * A class that encapsulates OzoneBucket.
@@ -1107,7 +1108,8 @@ private void getSeekPathsBetweenKeyPrefixAndStartKey(String keyPrefix,
11071108
11081109 String parentStartKeyPath = OzoneFSUtils .getParentDir (startKey );
11091110
1110- if (StringUtils .compare (parentStartKeyPath , keyPrefix ) >= 0 ) {
1111+ if (StringUtils .isNotBlank (startKey ) &&
1112+ StringUtils .compare (parentStartKeyPath , keyPrefix ) >= 0 ) {
11111113 seekPaths .add (new ImmutablePair <>(parentStartKeyPath , startKey ));
11121114
11131115 // recursively fetch all the sub-paths between keyPrefix and prevKey
@@ -1132,46 +1134,65 @@ List<OzoneKey> getNextListOfKeys(String prevKey) throws IOException {
11321134 }
11331135 setKeyPrefix (keyPrefixName );
11341136
1135- if (StringUtils .isNotBlank (prevKey ) &&
1136- StringUtils .startsWith (prevKey , getKeyPrefix ())) {
1137- // 1. Prepare all the seekKeys after the prefixKey.
1138- // Example case: prefixKey="a1", startKey="a1/b2/d2/f3/f31.tx"
1139- // Now, stack should be build with all the levels after prefixKey
1140- // Stack format => <keyPrefix and startKey>, startKey should be an
1141- // immediate child of keyPrefix.
1142- // _______________________________________
1143- // Stack=> top | < a1/b2/d2/f3, a1/b2/d2/f3/f31.tx > |
1144- // |-------------------------------------|
1145- // | < a1/b2/d2, a1/b2/d2/f3 > |
1146- // |-------------------------------------|
1147- // | < a1/b2, a1/b2/d2 > |
1148- // |-------------------------------------|
1149- // bottom | < a1, a1/b2 > |
1150- // --------------------------------------|
1151- List <Pair <String , String >> seekPaths = new ArrayList <>();
1152-
1153- if (StringUtils .isNotBlank (getKeyPrefix ())) {
1154- String parentStartKeyPath = OzoneFSUtils .getParentDir (prevKey );
1155- if (StringUtils .compare (parentStartKeyPath , getKeyPrefix ()) >= 0 ) {
1156- // Add the leaf node to the seek path. The idea is to search for
1157- // sub-paths if the given start key is a directory.
1137+ if (StringUtils .isNotBlank (prevKey )) {
1138+ if (StringUtils .startsWith (prevKey , getKeyPrefix ())) {
1139+ // 1. Prepare all the seekKeys after the prefixKey.
1140+ // Example case: prefixKey="a1", startKey="a1/b2/d2/f3/f31.tx"
1141+ // Now, stack should be build with all the levels after prefixKey
1142+ // Stack format => <keyPrefix and startKey>, startKey should be an
1143+ // immediate child of keyPrefix.
1144+ // _______________________________________
1145+ // Stack=> top | < a1/b2/d2/f3, a1/b2/d2/f3/f31.tx > |
1146+ // |-------------------------------------|
1147+ // | < a1/b2/d2, a1/b2/d2/f3 > |
1148+ // |-------------------------------------|
1149+ // | < a1/b2, a1/b2/d2 > |
1150+ // |-------------------------------------|
1151+ // bottom | < a1, a1/b2 > |
1152+ // --------------------------------------|
1153+ List <Pair <String , String >> seekPaths = new ArrayList <>();
1154+
1155+ if (StringUtils .isNotBlank (getKeyPrefix ())) {
1156+ String parentStartKeyPath = OzoneFSUtils .getParentDir (prevKey );
1157+ if (StringUtils .compare (parentStartKeyPath , getKeyPrefix ()) >=
1158+ 0 ) {
1159+ // Add the leaf node to the seek path. The idea is to search for
1160+ // sub-paths if the given start key is a directory.
1161+ seekPaths .add (new ImmutablePair <>(prevKey , "" ));
1162+ removeStartKey = prevKey ;
1163+ getSeekPathsBetweenKeyPrefixAndStartKey (getKeyPrefix (), prevKey ,
1164+ seekPaths );
1165+ } else if (StringUtils .compare (prevKey , getKeyPrefix ()) >= 0 ) {
1166+ // Add the leaf node to the seek path. The idea is to search for
1167+ // sub-paths if the given start key is a directory.
1168+ seekPaths .add (new ImmutablePair <>(prevKey , "" ));
1169+ removeStartKey = prevKey ;
1170+ }
1171+ } else {
1172+ // Key Prefix is Blank. The seek all the keys with startKey.
11581173 seekPaths .add (new ImmutablePair <>(prevKey , "" ));
11591174 removeStartKey = prevKey ;
11601175 getSeekPathsBetweenKeyPrefixAndStartKey (getKeyPrefix (), prevKey ,
11611176 seekPaths );
1162- } else if (StringUtils .compare (prevKey , getKeyPrefix ()) >= 0 ) {
1163- // Add the leaf node to the seek path. The idea is to search for
1164- // sub-paths if the given start key is a directory.
1165- seekPaths .add (new ImmutablePair <>(prevKey , "" ));
1166- removeStartKey = prevKey ;
11671177 }
1168- }
11691178
1170- // 2. Push elements in reverse order so that the FS tree traversal
1171- // will occur in left-to-right fashion[Depth-First Search]
1172- for (int index = seekPaths .size () - 1 ; index >= 0 ; index --) {
1173- Pair <String , String > seekDirPath = seekPaths .get (index );
1174- stack .push (seekDirPath );
1179+ // 2. Push elements in reverse order so that the FS tree traversal
1180+ // will occur in left-to-right fashion[Depth-First Search]
1181+ for (int index = seekPaths .size () - 1 ; index >= 0 ; index --) {
1182+ Pair <String , String > seekDirPath = seekPaths .get (index );
1183+ stack .push (seekDirPath );
1184+ }
1185+ } else if (StringUtils .isNotBlank (getKeyPrefix ())) {
1186+ if (!OzoneFSUtils .isSibling (prevKey , getKeyPrefix ())) {
1187+ // Case-1 - sibling: keyPrefix="a1/b2", startKey="a0/b123Invalid"
1188+ // Skip traversing, if the startKey is not a sibling.
1189+ return new ArrayList <>();
1190+ } else if (StringUtils .compare (prevKey , getKeyPrefix ()) < 0 ) {
1191+ // Case-2 - compare: keyPrefix="a1/b2", startKey="a1/b123Invalid"
1192+ // Since startKey is lexographically behind keyPrefix,
1193+ // the seek precedence goes to keyPrefix.
1194+ stack .push (new ImmutablePair <>(getKeyPrefix (), "" ));
1195+ }
11751196 }
11761197 }
11771198 }
@@ -1374,28 +1395,33 @@ private void addKeyPrefixInfoToResultList(String keyPrefix,
13741395 return ;
13751396 }
13761397
1377- // TODO: HDDS-4859 will fix the case where startKey not started with
1378- // keyPrefix.
1379-
1380- OzoneFileStatus status = proxy .getOzoneFileStatus (volumeName , name ,
1381- keyPrefix );
1398+ OzoneFileStatus status = null ;
1399+ try {
1400+ status = proxy .getOzoneFileStatus (volumeName , name ,
1401+ keyPrefix );
1402+ } catch (OMException ome ) {
1403+ if (ome .getResult () == FILE_NOT_FOUND ) {
1404+ // keyPrefix path can't be found and skip adding it to result list
1405+ return ;
1406+ }
1407+ }
13821408
13831409 if (status != null ) {
13841410 OmKeyInfo keyInfo = status .getKeyInfo ();
13851411 String keyName = keyInfo .getKeyName ();
13861412
1387- // removeStartKey - as the startKey is a placeholder, which is
1388- // managed internally to traverse leaf node's sub-paths.
1389- if (StringUtils .equals (keyName , removeStartKey )) {
1390- return ;
1391- }
1392-
13931413 if (status .isDirectory ()) {
13941414 // add trailing slash to represent directory
13951415 keyName =
13961416 OzoneFSUtils .addTrailingSlashIfNeeded (keyInfo .getKeyName ());
13971417 }
13981418
1419+ // removeStartKey - as the startKey is a placeholder, which is
1420+ // managed internally to traverse leaf node's sub-paths.
1421+ if (StringUtils .equals (keyName , removeStartKey )) {
1422+ return ;
1423+ }
1424+
13991425 OzoneKey ozoneKey = new OzoneKey (keyInfo .getVolumeName (),
14001426 keyInfo .getBucketName (), keyName ,
14011427 keyInfo .getDataSize (), keyInfo .getCreationTime (),
0 commit comments