5252import org .apache .hadoop .ozone .om .helpers .OmBucketInfo ;
5353import org .apache .hadoop .ozone .om .helpers .OmDirectoryInfo ;
5454import org .apache .hadoop .ozone .om .helpers .OmKeyInfo ;
55+ import org .apache .hadoop .ozone .om .helpers .OmMultipartKeyInfo ;
5556import org .apache .hadoop .ozone .om .helpers .OmVolumeArgs ;
57+ import org .apache .hadoop .ozone .protocol .proto .OzoneManagerProtocolProtos .PartKeyInfo ;
5658import picocli .CommandLine ;
5759
5860/**
@@ -84,12 +86,20 @@ public class ContainerToKeyMapping extends AbstractSubcommand implements Callabl
8486 description = "Only display file names without full path" )
8587 private boolean onlyFileNames ;
8688
89+ @ CommandLine .Option (names = {"--in-progress" },
90+ defaultValue = "false" ,
91+ description = "Includes in-progress open files/keys and multipart uploads" )
92+ private boolean inProgress ;
93+
8794 private DBStore omDbStore ;
8895 private Table <String , OmVolumeArgs > volumeTable ;
8996 private Table <String , OmBucketInfo > bucketTable ;
9097 private Table <String , OmDirectoryInfo > directoryTable ;
9198 private Table <String , OmKeyInfo > fileTable ;
9299 private Table <String , OmKeyInfo > keyTable ;
100+ private Table <String , OmKeyInfo > openFileTable ;
101+ private Table <String , OmKeyInfo > openKeyTable ;
102+ private Table <String , OmMultipartKeyInfo > multipartInfoTable ;
93103 private DBStore dirTreeDbStore ;
94104 private Table <Long , String > dirTreeTable ;
95105 // Cache volume IDs to avoid repeated lookups
@@ -98,7 +108,6 @@ public class ContainerToKeyMapping extends AbstractSubcommand implements Callabl
98108
99109 @ Override
100110 public Void call () throws Exception {
101-
102111 String dbPath = parent .getDbPath ();
103112 // Parse container IDs
104113 Set <Long > containerIDs = Arrays .stream (containers .split ("," ))
@@ -126,6 +135,9 @@ public Void call() throws Exception {
126135 directoryTable = OMDBDefinition .DIRECTORY_TABLE_DEF .getTable (omDbStore , CacheType .NO_CACHE );
127136 fileTable = OMDBDefinition .FILE_TABLE_DEF .getTable (omDbStore , CacheType .NO_CACHE );
128137 keyTable = OMDBDefinition .KEY_TABLE_DEF .getTable (omDbStore , CacheType .NO_CACHE );
138+ openFileTable = OMDBDefinition .OPEN_FILE_TABLE_DEF .getTable (omDbStore , CacheType .NO_CACHE );
139+ openKeyTable = OMDBDefinition .OPEN_KEY_TABLE_DEF .getTable (omDbStore , CacheType .NO_CACHE );
140+ multipartInfoTable = OMDBDefinition .MULTIPART_INFO_TABLE_DEF .getTable (omDbStore , CacheType .NO_CACHE );
129141
130142 retrieve (dbPath , writer , containerIDs );
131143 } catch (Exception e ) {
@@ -181,20 +193,29 @@ private void retrieve(String dbPath, PrintWriter writer, Set<Long> containerIds)
181193
182194 // Map to collect keys per container
183195 Map <Long , List <String >> containerToKeysMap = new HashMap <>();
196+ // Map to collect open keys per container
197+ Map <Long , List <String >> containerToOpenKeysMap = inProgress ? new HashMap <>() : null ;
184198 // Track unreferenced keys count per container (FSO only)
185199 Map <Long , Long > unreferencedCountMap = new HashMap <>();
186200 for (Long containerId : containerIds ) {
187201 containerToKeysMap .put (containerId , new ArrayList <>());
188202 unreferencedCountMap .put (containerId , 0L );
189203 }
190204
205+ // Process open file and open key tables
206+ if (inProgress ) {
207+ for (Long containerId : containerIds ) {
208+ containerToOpenKeysMap .put (containerId , new ArrayList <>());
209+ }
210+ processOpenFiles (containerIds , containerToOpenKeysMap );
211+ processOpenKeys (containerIds , containerToOpenKeysMap );
212+ processMultipartUpload (containerIds , containerToOpenKeysMap );
213+ }
191214 // Process FSO keys (fileTable)
192215 processFSOKeys (containerIds , containerToKeysMap , unreferencedCountMap , bucketVolMap );
193-
194216 // Process OBS keys (keyTable)
195217 processOBSKeys (containerIds , containerToKeysMap );
196-
197- jsonOutput (writer , containerToKeysMap , unreferencedCountMap );
218+ jsonOutput (writer , containerToKeysMap , containerToOpenKeysMap , unreferencedCountMap );
198219 }
199220
200221 private void processFSOKeys (Set <Long > containerIds , Map <Long , List <String >> containerToKeysMap ,
@@ -251,6 +272,69 @@ private void processOBSKeys(Set<Long> containerIds, Map<Long, List<String>> cont
251272 }
252273 }
253274
275+ private void processOpenFiles (Set <Long > containerIds , Map <Long , List <String >> containerToOpenKeysMap ) {
276+ try (TableIterator <String , ? extends Table .KeyValue <String , OmKeyInfo >> fileIterator =
277+ openFileTable .iterator ()) {
278+ while (fileIterator .hasNext ()) {
279+ Table .KeyValue <String , OmKeyInfo > entry = fileIterator .next ();
280+ addOpenKeyToContainerMap (entry .getKey (), entry .getValue (), containerIds , containerToOpenKeysMap );
281+ }
282+ } catch (Exception e ) {
283+ err ().println ("Exception occurred reading openFileTable (FSO keys), " + e );
284+ }
285+ }
286+
287+ private void processOpenKeys (Set <Long > containerIds , Map <Long , List <String >> containerToOpenKeysMap ) {
288+ try (TableIterator <String , ? extends Table .KeyValue <String , OmKeyInfo >> keyIterator =
289+ openKeyTable .iterator ()) {
290+ while (keyIterator .hasNext ()) {
291+ Table .KeyValue <String , OmKeyInfo > entry = keyIterator .next ();
292+ addOpenKeyToContainerMap (entry .getKey (), entry .getValue (), containerIds , containerToOpenKeysMap );
293+ }
294+ } catch (Exception e ) {
295+ err ().println ("Exception occurred reading openKeyTable (OBS keys), " + e );
296+ }
297+ }
298+
299+ private void addOpenKeyToContainerMap (String dbKey , OmKeyInfo keyInfo , Set <Long > containerIds ,
300+ Map <Long , List <String >> containerToOpenKeysMap ) {
301+ // Find which containers this key uses
302+ Set <Long > keyContainers = getKeyContainers (keyInfo , containerIds );
303+
304+ if (!keyContainers .isEmpty ()) {
305+ for (Long containerId : keyContainers ) {
306+ containerToOpenKeysMap .get (containerId ).add (dbKey );
307+ }
308+ }
309+ }
310+
311+ private void processMultipartUpload (Set <Long > containerIds , Map <Long , List <String >> containerToOpenKeysMap ) {
312+ try (TableIterator <String , ? extends Table .KeyValue <String , OmMultipartKeyInfo >> mpuIterator =
313+ multipartInfoTable .iterator ()) {
314+
315+ while (mpuIterator .hasNext ()) {
316+ Table .KeyValue <String , OmMultipartKeyInfo > entry = mpuIterator .next ();
317+ String dbKey = entry .getKey ();
318+ OmMultipartKeyInfo mpuInfo = entry .getValue ();
319+
320+ // Collect all target containers that have parts of this MPU
321+ Set <Long > matchedContainers = new HashSet <>();
322+ for (PartKeyInfo partKeyInfo : mpuInfo .getPartKeyInfoMap ()) {
323+ OmKeyInfo partKey = OmKeyInfo .getFromProtobuf (partKeyInfo .getPartKeyInfo ());
324+ matchedContainers .addAll (getKeyContainers (partKey , containerIds ));
325+ }
326+
327+ if (!matchedContainers .isEmpty ()) {
328+ for (Long containerId : matchedContainers ) {
329+ containerToOpenKeysMap .get (containerId ).add (dbKey );
330+ }
331+ }
332+ }
333+ } catch (Exception e ) {
334+ err ().println ("Exception occurred reading multipartInfoTable, " + e );
335+ }
336+ }
337+
254338 private Set <Long > getKeyContainers (OmKeyInfo keyInfo , Set <Long > targetContainerIds ) {
255339 Set <Long > keyContainers = new HashSet <>();
256340 keyInfo .getKeyLocationVersions ().forEach (
@@ -317,11 +401,11 @@ private String reconstructFullPath(OmKeyInfo keyInfo, Map<Long, Pair<Long, Strin
317401 // Check dir tree
318402 Pair <Long , String > nameParentPair = getFromDirTree (prvParent );
319403 if (nameParentPair == null ) {
320- // If parent is not found, mark the key as unreferenced and increment its count
404+ // If parent is not found (maybe in deletion process), increment unreferenced count
321405 for (Long containerId : keyContainers ) {
322406 unreferencedCountMap .put (containerId , unreferencedCountMap .get (containerId ) + 1 );
323407 }
324- return "[unreferenced] " + keyInfo . getKeyName () ;
408+ return null ;
325409 }
326410 sb .insert (0 , nameParentPair .getValue () + OM_KEY_PREFIX );
327411 prvParent = nameParentPair .getKey ();
@@ -372,7 +456,7 @@ private void addToDirTree(Long objectId, Long parentId, String name) throws IOEx
372456 }
373457
374458 private void jsonOutput (PrintWriter writer , Map <Long , List <String >> containerToKeysMap ,
375- Map <Long , Long > unreferencedCountMap ) {
459+ Map <Long , List < String >> containerToOpenKeysMap , Map < Long , Long > unreferencedCountMap ) {
376460 try {
377461 ObjectMapper mapper = new ObjectMapper ();
378462 ObjectNode root = mapper .createObjectNode ();
@@ -388,13 +472,30 @@ private void jsonOutput(PrintWriter writer, Map<Long, List<String>> containerToK
388472 }
389473
390474 containerNode .set ("keys" , keysArray );
391- containerNode .put ("totalKeys" , entry .getValue ().size ()); // includes unreferenced keys
475+
476+ // Add open keys array only if --in-progress flag is set
477+ long totalKeys = entry .getValue ().size ();
478+ if (containerToOpenKeysMap != null ) {
479+ ArrayNode openKeysArray = mapper .createArrayNode ();
480+ List <String > openKeys = containerToOpenKeysMap .get (containerId );
481+ if (openKeys != null ) {
482+ for (String key : openKeys ) {
483+ openKeysArray .add (key );
484+ }
485+ totalKeys += openKeys .size ();
486+ }
487+ containerNode .set ("openKeys" , openKeysArray );
488+ }
392489
393490 // Add unreferenced count if > 0
394491 long unreferencedCount = unreferencedCountMap .get (containerId );
395492 if (unreferencedCount > 0 ) {
396493 containerNode .put ("unreferencedKeys" , unreferencedCount );
494+ totalKeys += unreferencedCount ;
397495 }
496+
497+ // Total keys = committed keys + open keys + unreferenced keys
498+ containerNode .put ("totalKeys" , totalKeys );
398499
399500 containersNode .set (containerId .toString (), containerNode );
400501 }
@@ -407,4 +508,3 @@ private void jsonOutput(PrintWriter writer, Map<Long, List<String>> containerToK
407508 }
408509 }
409510}
410-
0 commit comments