grib/src/main/java/ucar/nc2/grib/collection/GribPartitionBuilder.java
protected boolean writeIndex(PartitionCollectionMutable pc, Formatter f) throws IOException {
    File idxFile = GribIndexCache.getFileOrCache(partitionManager.getIndexFilename(GribCdmIndex.NCX_SUFFIX));
    if (idxFile.exists()) {
      RandomAccessFile.eject(idxFile.getPath());
      if (!idxFile.delete())
        logger.error("gc2tp cant delete " + idxFile.getPath());
    }

    writer = new GribCollectionWriter(null, null);

    try (RandomAccessFile raf = new RandomAccessFile(idxFile.getPath(), "rw")) {
      raf.order(RandomAccessFile.BIG_ENDIAN);

      //// header message
      raf.write(getMagicStart().getBytes(CDM.utf8Charset));
      raf.writeInt(getVersion());
      raf.writeLong(0); // no record section

      /*
      message GribCollection {
        required string name = 1;         // must be unique - index filename is name.ncx
        required string topDir = 2;       // filenames are reletive to this
        repeated MFile mfiles = 3;        // list of grib MFiles
        repeated Dataset dataset = 4;
        repeated Gds gds = 5;             // unique Gds, shared amongst datasets

        required int32 center = 6;      // these 4 fields are to get a GribTable object
        required int32 subcenter = 7;
        required int32 master = 8;
        required int32 local = 9;       // grib1 table Version

        optional int32 genProcessType = 10;
        optional int32 genProcessId = 11;
        optional int32 backProcessId = 12;

        // repeated Parameter params = 20;      // not used
        FcConfig config = 21;
        uint64 startTime = 22; // calendar date, first valid time
        uint64 endTime = 23;   // calendar date, last valid time

        extensions 100 to 199;
      }

      extend GribCollection {
        repeated Partition partitions = 100;
      }
       */

      GribCollectionProto.GribCollection.Builder indexBuilder = GribCollectionProto.GribCollection.newBuilder();
      indexBuilder.setName(pc.getName());
      Path topDir = pc.directory.toPath();
      String pathS = StringUtil2.replace(topDir.toString(), '\\', "/");
      indexBuilder.setTopDir(pathS);

      // mfiles are the partition indexes
      int count = 0;
      for (PartitionCollectionMutable.Partition part : pc.partitions) {
        GribCollectionProto.MFile.Builder b = GribCollectionProto.MFile.newBuilder();
        String pathRS = makeReletiveFilename(pc, part); // reletive to pc.directory
        b.setFilename(pathRS);
        b.setLastModified(part.getLastModified());
        b.setLength(part.fileSize);
        b.setIndex(count++);
        indexBuilder.addMfiles(b.build());
      }

      indexBuilder.setCenter(pc.center);
      indexBuilder.setSubcenter(pc.subcenter);
      indexBuilder.setMaster(pc.master);
      indexBuilder.setLocal(pc.local);

      indexBuilder.setGenProcessId(pc.genProcessId);
      indexBuilder.setGenProcessType(pc.genProcessType);
      indexBuilder.setBackProcessId(pc.backProcessId);

      indexBuilder.setStartTime(pc.dateRange.getStart().getMillis());
      indexBuilder.setEndTime(pc.dateRange.getEnd().getMillis());

      indexBuilder.setMasterRuntime(writer.writeCoordProto(pc.masterRuntime));

      // dataset
      for (GribCollectionMutable.Dataset ds : pc.datasets)
        indexBuilder.addDataset(writeDatasetProto(pc, ds));

      // extensions
      if (pc.run2part != null) {
        for (int part : pc.run2part)
          indexBuilder.addRun2Part(part);
      }
      for (PartitionCollectionMutable.Partition part : pc.partitions)
        indexBuilder.addPartitions(writePartitionProto(pc, part));
      indexBuilder.setIsPartitionOfPartitions(pc.isPartitionOfPartitions);

      // write it out
      GribCollectionProto.GribCollection index = indexBuilder.build();
      byte[] b = index.toByteArray();
      NcStream.writeVInt(raf, b.length); // message size
      raf.write(b);  // message  - all in one gulp
      f.format("Grib2PartitionIndex= %d bytes file size =  %d bytes%n%n", b.length, raf.length());
    }

    return true;
  }
protected boolean writeIndex(PartitionCollectionMutable pc, Formatter f) throws IOException {
    File idxFile = GribIndexCache.getFileOrCache(partitionManager.getIndexFilename(GribCdmIndex.NCX_SUFFIX));
    if (idxFile.exists()) {
      RandomAccessFile.eject(idxFile.getPath());
      if (!idxFile.delete())
        logger.error("gc2tp cant delete " + idxFile.getPath());
    }

    writer = new GribCollectionWriter(null, null);

    try (RandomAccessFile raf = new RandomAccessFile(idxFile.getPath(), "rw")) {
      raf.order(RandomAccessFile.BIG_ENDIAN);

      //// header message
      raf.write(getMagicStart().getBytes(CDM.utf8Charset));
      raf.writeInt(getVersion());
      raf.writeLong(0); // no record section

      /*
      message GribCollection {
        required string name = 1;         // must be unique - index filename is name.ncx
        required string topDir = 2;       // filenames are reletive to this
        repeated MFile mfiles = 3;        // list of grib MFiles
        repeated Dataset dataset = 4;
        repeated Gds gds = 5;             // unique Gds, shared amongst datasets

        required int32 center = 6;      // these 4 fields are to get a GribTable object
        required int32 subcenter = 7;
        required int32 master = 8;
        required int32 local = 9;       // grib1 table Version

        optional int32 genProcessType = 10;
        optional int32 genProcessId = 11;
        optional int32 backProcessId = 12;

        // repeated Parameter params = 20;      // not used
        FcConfig config = 21;
        uint64 startTime = 22; // calendar date, first valid time
        uint64 endTime = 23;   // calendar date, last valid time

        extensions 100 to 199;
      }

      extend GribCollection {
        repeated Partition partitions = 100;
      }
       */

      GribCollectionProto.GribCollection.Builder indexBuilder = GribCollectionProto.GribCollection.newBuilder();
      indexBuilder.setName(pc.getName());
      Path topDir = pc.directory.toPath();
      String pathS = StringUtil2.replace(topDir.toString(), '\\', "/");
      indexBuilder.setTopDir(pathS);

      // mfiles are the partition indexes
      int count = 0;
      for (PartitionCollectionMutable.Partition part : pc.partitions) {
        GribCollectionProto.MFile.Builder b = GribCollectionProto.MFile.newBuilder();
        String pathRS = makeReletiveFilename(pc, part); // reletive to pc.directory
        b.setFilename(pathRS);
        b.setLastModified(part.getLastModified());
        b.setLength(part.fileSize);
        b.setIndex(count++);
        indexBuilder.addMfiles(b.build());
      }

      indexBuilder.setCenter(pc.center);
      indexBuilder.setSubcenter(pc.subcenter);
      indexBuilder.setMaster(pc.master);
      indexBuilder.setLocal(pc.local);

      indexBuilder.setGenProcessId(pc.genProcessId);
      indexBuilder.setGenProcessType(pc.genProcessType);
      indexBuilder.setBackProcessId(pc.backProcessId);

      indexBuilder.setStartTime(pc.dateRange.getStart().getMillis());
      indexBuilder.setEndTime(pc.dateRange.getEnd().getMillis());

      indexBuilder.setMasterRuntime(writer.writeCoordProto(pc.masterRuntime));

      // dataset
      for (GribCollectionMutable.Dataset ds : pc.datasets)
        indexBuilder.addDataset(writeDatasetProto(pc, ds));

      // extensions
      if (pc.run2part != null) {
        for (int part : pc.run2part)
          indexBuilder.addRun2Part(part);
      }
      for (PartitionCollectionMutable.Partition part : pc.partitions)
        indexBuilder.addPartitions(writePartitionProto(pc, part));
      indexBuilder.setIsPartitionOfPartitions(pc.isPartitionOfPartitions);

      // write it out
      GribCollectionProto.GribCollection index = indexBuilder.build();
      byte[] b = index.toByteArray();
      NcStream.writeVInt(raf, b.length); // message size
      raf.write(b);  // message  - all in one gulp
      f.format("Grib2PartitionIndex= %d bytes file size =  %d bytes%n%n", b.length, raf.length());
    }

    return true;
  }
/*
MAGIC_START
version
sizeRecords
VariableRecords (sizeRecords bytes)
sizeIndex
GribCollectionIndex (sizeIndex bytes)