docs: @Override
      public int encodingLengthBytes() {
          //TODO convert Strings to byte[] only once
  
          //First: determine buffer size.
          //(a) Header: 8 bytes (4x uint16 = 8 bytes)
          //(b) Fixed length entries length (sie.BlockLength())
          //(c) Group 1: Memory use.
          //(d) Group 2: Performance stats
          //(e) Group 3: GC stats
          //(f) Group 4: param names (variable length strings)
          //(g) Group 5: layer names (variable length strings)
          //(g) Group 6: Per parameter performance stats
          //Variable length String fields: 4 - session/type/worker IDs and metadata -> 4*4=16 bytes header, plus content
  
          UpdateEncoder ue = new UpdateEncoder();
          int bufferSize = 8 + ue.sbeBlockLength() + 16;
  
          //Memory use group length...
          int memoryUseCount;
          if (!memoryUsePresent) {
              memoryUseCount = 0;
          } else {
              memoryUseCount = 4 + (deviceCurrentBytes == null ? 0 : deviceCurrentBytes.length)
                              + (deviceMaxBytes == null ? 0 : deviceMaxBytes.length);
          }
          bufferSize += 4 + 9 * memoryUseCount; //Group header: 4 bytes (always present); Each entry in group - 1x MemoryType (uint8) + 1x int64 -> 1+8 = 9 bytes
  
          //Performance group length
          bufferSize += 4 + (performanceStatsPresent ? 32 : 0); //Group header: 4 bytes (always present); Only 1 group: 3xint64 + 2xfloat = 32 bytes
  
          //GC stats group length
          bufferSize += 4; //Group header: always present
          List<byte[]> gcStatsLabelBytes = null;
          if (gcStats != null && !gcStats.isEmpty()) {
              gcStatsLabelBytes = new ArrayList<>();
              for (int i = 0; i < gcStats.size(); i++) {
                  GCStats stats = gcStats.get(i);
                  bufferSize += 12; //Fixed per group entry: 2x int32 -> 8 bytes PLUS the header for the variable length GC name: another 4 bytes
                  byte[] nameAsBytes = SbeUtil.toBytes(true, stats.gcName);
                  bufferSize += nameAsBytes.length;
                  gcStatsLabelBytes.add(nameAsBytes);
              }
          }
  
          //Param names group
          bufferSize += 4; //Header; always present
          List<String> paramNames = getParamNames();
          for (String s : paramNames) {
              bufferSize += 4; //header for each entry
              bufferSize += SbeUtil.toBytes(true, s).length; //Content
          }
  
          //Layer names group
          bufferSize += 4; //Header; always present
          List<String> layerNames = getlayerNames();
          for (String s : layerNames) {
              bufferSize += 4;
              bufferSize += SbeUtil.toBytes(true, s).length; //Content
          }
  
          //Per parameter and per layer (activations) stats group length
          bufferSize += 4; //Per parameter/layer stats group header: always present
          int nEntries = paramNames.size() + layerNames.size();
          bufferSize += nEntries * 12; //Each parameter/layer entry: has learning rate -> float -> 4 bytes PLUS headers for 2 nested groups: 2*4 = 8 each -> 12 bytes total
          bufferSize += entrySize(paramNames, StatsType.Parameters, StatsType.Gradients, StatsType.Updates);
          bufferSize += entrySize(layerNames, StatsType.Activations);
  
          //Metadata group:
          bufferSize += 4; //Metadata group header: always present
          if (dataSetMetaData != null && !dataSetMetaData.isEmpty()) {
              for (byte[] b : dataSetMetaData) {
                  bufferSize += 4 + b.length; //4 bytes header + content
              }
          }
  
          //Session/worker IDs
          byte[] bSessionID = SbeUtil.toBytes(true, sessionID);
          byte[] bTypeID = SbeUtil.toBytes(true, typeID);
          byte[] bWorkerID = SbeUtil.toBytes(true, workerID);
          bufferSize += bSessionID.length + bTypeID.length + bWorkerID.length;
  
          //Metadata class name:
          byte[] metaDataClassNameBytes = SbeUtil.toBytes(true, metaDataClassName);
          bufferSize += metaDataClassNameBytes.length;
  
          return bufferSize;
      }