public void read(ProcedureWALFile log) throws IOException {
    localTracker = log.getTracker();
    if (localTracker.isPartial()) {
      LOG.info("Rebuilding tracker for {}", log);
    }

    long count = 0;
    FSDataInputStream stream = log.getStream();
    try {
      boolean hasMore = true;
      while (hasMore) {
        ProcedureWALEntry entry = ProcedureWALFormat.readEntry(stream);
        if (entry == null) {
          LOG.warn("Nothing left to decode. Exiting with missing EOF, log={}", log);
          break;
        }
        count++;
        switch (entry.getType()) {
          case PROCEDURE_WAL_INIT:
            readInitEntry(entry);
            break;
          case PROCEDURE_WAL_INSERT:
            readInsertEntry(entry);
            break;
          case PROCEDURE_WAL_UPDATE:
          case PROCEDURE_WAL_COMPACT:
            readUpdateEntry(entry);
            break;
          case PROCEDURE_WAL_DELETE:
            readDeleteEntry(entry);
            break;
          case PROCEDURE_WAL_EOF:
            hasMore = false;
            break;
          default:
            throw new CorruptedWALProcedureStoreException("Invalid entry: " + entry);
        }
      }
      LOG.info("Read {} entries in {}", count, log);
    } catch (InvalidProtocolBufferException e) {
      LOG.error("While reading entry #{} in {}", count, log, e);
      loader.markCorruptedWAL(log, e);
    }

    if (!localProcedureMap.isEmpty()) {
      log.setProcIds(localProcedureMap.getMinModifiedProcId(),
        localProcedureMap.getMaxModifiedProcId());
      if (localTracker.isPartial()) {
        localTracker.setMinMaxModifiedProcIds(localProcedureMap.getMinModifiedProcId(),
          localProcedureMap.getMaxModifiedProcId());
      }
      procedureMap.merge(localProcedureMap);
    }
    // Do not reset the partial flag for local tracker, as here the local tracker only know the
    // procedures which are modified in this file.
  }
If tracker for a log file is partial (see {@link ProcedureStoreTracker#partial}), we re-build
the list of procedures modified in that WAL because we need it for log cleaning purposes. If
all procedures modified in a WAL are found to be obsolete, it can be safely deleted. (see
{@link WALProcedureStore#removeInactiveLogs()}).
<p/>
Notice that, the deleted part for this tracker will not be global valid as we can only count
the deletes in the current file, but it is not big problem as finally, the above tracker will
have the global state of deleted, and it will also be used to build the cleanup tracker.
hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/store/wal/ProcedureWALFormatReader.java