From 43b85217dbb2af4b553e481a930c226776a59031 Mon Sep 17 00:00:00 2001
From: Uwe Schulzweida <uwe.schulzweida@mpimet.mpg.de>
Date: Thu, 16 Jan 2025 10:03:28 +0100
Subject: [PATCH] Extract recinfo_t from record_t

---
 src/cdf_read.c       | 20 +++++++---------
 src/cdf_records.c    | 24 +++++++++----------
 src/cdi_int.h        | 15 ++++++++----
 src/grb_read.c       |  4 ++--
 src/grb_write.c      |  8 +++----
 src/grid.c           |  6 ++---
 src/stream.c         | 44 ++++++++++++++++------------------
 src/stream_cdf_o.c   |  2 +-
 src/stream_cgribex.c | 35 ++++++++++++++-------------
 src/stream_ext.c     | 24 ++++++++++---------
 src/stream_gribapi.c | 40 ++++++++++++++++++-------------
 src/stream_ieg.c     | 24 ++++++++++---------
 src/stream_record.c  | 57 ++++++++++++++++++++++++++++----------------
 src/stream_scan.c    | 11 +++++----
 src/stream_srv.c     | 24 ++++++++++---------
 src/tsteps.c         |  3 ++-
 16 files changed, 185 insertions(+), 156 deletions(-)

diff --git a/src/cdf_read.c b/src/cdf_read.c
index 05622e060..a4c55bf0e 100644
--- a/src/cdf_read.c
+++ b/src/cdf_read.c
@@ -794,14 +794,13 @@ static size_t
 cdf_read_data(stream_t *streamptr, int recID, int memtype, void *data)
 {
   int tsID = streamptr->curTsID;
-  int varID = streamptr->tsteps[tsID].records[recID].varID;
-  int levelID = streamptr->tsteps[tsID].records[recID].levelID;
+  recinfo_t *recInfo = &(streamptr->tsteps[tsID].recinfo[recID]);
 
   size_t numMissVals = 0;
   if (memtype == MEMTYPE_DOUBLE)
-    cdf_read_var_slice_DP(streamptr, tsID, varID, levelID, (double *) data, &numMissVals);
+    cdf_read_var_slice_DP(streamptr, tsID, recInfo->varID, recInfo->levelID, (double *) data, &numMissVals);
   else
-    cdf_read_var_slice_SP(streamptr, tsID, varID, levelID, (float *) data, &numMissVals);
+    cdf_read_var_slice_SP(streamptr, tsID, recInfo->varID, recInfo->levelID, (float *) data, &numMissVals);
 
   return numMissVals;
 }
@@ -815,16 +814,15 @@ typedef struct JobDescriptorCDF
 static JobArgsCDF
 job_args_init(stream_t *streamptr, long tsID, long recID, int memtype, void *data)
 {
-  int varID = streamptr->tsteps[tsID].records[recID].varID;
-  int levelID = streamptr->tsteps[tsID].records[recID].levelID;
-  size_t gridsize = (size_t) gridInqSize(vlistInqVarGrid(streamptr->vlistID, varID));
+  recinfo_t *recInfo = &(streamptr->tsteps[tsID].recinfo[recID]);
+  size_t gridsize = (size_t) gridInqSize(vlistInqVarGrid(streamptr->vlistID, recInfo->varID));
 
   if (!data) data = Malloc(gridsize * ((memtype == MEMTYPE_FLOAT) ? sizeof(float) : sizeof(double)));
 
-  return (JobArgsCDF){
+  return (JobArgsCDF) {
     .streamptr = streamptr,
-    .varID = varID,
-    .levelID = levelID,
+    .varID = recInfo->varID,
+    .levelID = recInfo->levelID,
     .memtype = memtype,
     .recID = recID,
     .tsID = tsID,
@@ -887,7 +885,7 @@ cdf_get_local_step_and_recId(stream_t *streamptr, long globalRecId)
       globalRecId -= tsteps[1].nrecs;
     }
 
-  return (struct recTsId){ .recID = globalRecId, .tsID = localTsId };
+  return (struct recTsId) { .recID = globalRecId, .tsID = localTsId };
 }
 
 static void
diff --git a/src/cdf_records.c b/src/cdf_records.c
index 1ad97c2a7..445c438c9 100644
--- a/src/cdf_records.c
+++ b/src/cdf_records.c
@@ -16,7 +16,7 @@
 static void
 cdf_init_timestep(tsteps_t *timeStep, int numRecs, int numRecsAvail)
 {
-  timeStep->records = (record_t *) Malloc((size_t) numRecs * sizeof(record_t));
+  timeStep->recinfo = (recinfo_t *) Malloc((size_t) numRecs * sizeof(recinfo_t));
   timeStep->nrecs = numRecsAvail;
   timeStep->nallrecs = numRecs;
   timeStep->recordSize = numRecs;
@@ -39,7 +39,7 @@ cdf_get_numRecsAvail(int vlistID)
 }
 
 static void
-cdf_init_records_step0(int numRecs, int *recIDs, record_t *records, int vlistID)
+cdf_init_records_step0(int numRecs, int *recIDs, recinfo_t *recinfo, int vlistID)
 {
   for (int recID = 0; recID < numRecs; recID++) recIDs[recID] = recID;
 
@@ -50,20 +50,20 @@ cdf_init_records_step0(int numRecs, int *recIDs, record_t *records, int vlistID)
       int nlevels = zaxisInqSize(zaxisID);
       for (int levelID = 0; levelID < nlevels; levelID++)
         {
-          recordInitEntry(&records[recID]);
-          records[recID].varID = (short) varID;
-          records[recID].levelID = levelID;
+          recinfoInitEntry(&recinfo[recID]);
+          recinfo[recID].varID = (short) varID;
+          recinfo[recID].levelID = levelID;
           recID++;
         }
     }
 }
 
 static void
-cdf_init_records_step1(int numRecs, int *recIDs, record_t *records, int vlistID)
+cdf_init_records_step1(int numRecs, int *recIDs, recinfo_t *recinfo, int vlistID)
 {
   for (int recID = 0, vrecID = 0; recID < numRecs; recID++)
     {
-      if (vlistInqVarTimetype(vlistID, records[recID].varID) != TIME_CONSTANT)
+      if (vlistInqVarTimetype(vlistID, recinfo[recID].varID) != TIME_CONSTANT)
         {
           recIDs[vrecID++] = recID;
         }
@@ -94,7 +94,7 @@ cdf_create_records(stream_t *streamptr, size_t tsID)
       cdf_init_timestep(destTstep, numFields, numRecsAvail);
 
       destTstep->recIDs = (int *) Malloc((size_t) numRecsAvail * sizeof(int));
-      cdf_init_records_step0(numFields, destTstep->recIDs, destTstep->records, vlistID);
+      cdf_init_records_step0(numFields, destTstep->recIDs, destTstep->recinfo, vlistID);
     }
   else if (tsID == 1)
     {
@@ -104,17 +104,17 @@ cdf_create_records(stream_t *streamptr, size_t tsID)
 
       cdf_init_timestep(destTstep, numFields, numRecsAvail);
 
-      memcpy(destTstep->records, sourceTstep->records, (size_t) numFields * sizeof(record_t));
+      memcpy(destTstep->recinfo, sourceTstep->recinfo, (size_t) numFields * sizeof(recinfo_t));
 
       if (numRecsAvail)
         {
           destTstep->recIDs = (int *) Malloc((size_t) numRecsAvail * sizeof(int));
-          cdf_init_records_step1(numFields, destTstep->recIDs, destTstep->records, vlistID);
+          cdf_init_records_step1(numFields, destTstep->recIDs, destTstep->recinfo, vlistID);
         }
     }
   else
     {
-      if (streamptr->tsteps[1].records == 0) cdf_create_records(streamptr, 1);
+      if (streamptr->tsteps[1].recinfo == 0) cdf_create_records(streamptr, 1);
 
       int numRecsAvail = streamptr->tsteps[1].nrecs;
 
@@ -122,7 +122,7 @@ cdf_create_records(stream_t *streamptr, size_t tsID)
 
       cdf_init_timestep(destTstep, numFields, numRecsAvail);
 
-      memcpy(destTstep->records, sourceTstep->records, (size_t) numFields * sizeof(record_t));
+      memcpy(destTstep->recinfo, sourceTstep->recinfo, (size_t) numFields * sizeof(recinfo_t));
 
       if (numRecsAvail)
         {
diff --git a/src/cdi_int.h b/src/cdi_int.h
index 4361a81ed..e39998429 100644
--- a/src/cdi_int.h
+++ b/src/cdi_int.h
@@ -171,6 +171,13 @@ varScanKeysIsEqual(const VarScanKeys *s1, const VarScanKeys *s2)
   return memcmp(s1, s2, sizeof(VarScanKeys)) == 0;
 }
 
+typedef struct
+{
+  int levelID;
+  short varID;
+  short used;
+} recinfo_t;
+
 typedef struct
 {
   off_t position;
@@ -179,9 +186,6 @@ typedef struct
   int param;
   int ilevel;
   int ilevel2;
-  int levelID;
-  short varID;
-  short used;
   short ltype;
   short tsteptype;
 #ifdef HAVE_LIBGRIB
@@ -200,6 +204,7 @@ typedef struct
 typedef struct
 {
   int *recIDs;  // IDs of non constant records
+  recinfo_t *recinfo;
   record_t *records;
   int recordSize;   // number of allocated records
   int nrecs;        // number of used records
@@ -459,7 +464,7 @@ void cdi_generate_vars(stream_t *streamptr);
 
 void vlist_check_contents(int vlistID);
 
-void cdi_create_records(stream_t *streamptr, int tsID);
+void cdi_create_records(stream_t *streamptr, int tsID, bool allocRecords);
 
 void streamFCopyRecord(stream_t *streamptr2, stream_t *streamptr1, const char *container_name);
 
@@ -467,7 +472,7 @@ int recordNewEntry(stream_t *streamptr, int tsID);
 
 void cdi_create_timesteps(size_t numTimesteps, stream_t *streamptr);
 
-void recordInitEntry(record_t *record);
+void recinfoInitEntry(recinfo_t *recinfo);
 
 void cdiCheckZaxis(int zaxisID);
 
diff --git a/src/grb_read.c b/src/grb_read.c
index 9c8246194..460dac3e2 100644
--- a/src/grb_read.c
+++ b/src/grb_read.c
@@ -131,7 +131,7 @@ static JobArgsGRB
 grb_read_raw_data(stream_t *streamptr, int tsID, int recID, int memType, void *gribbuffer, void *data, bool resetFilePos)
 {
   int vlistID = streamptr->vlistID;
-  int varID = streamptr->tsteps[tsID].records[recID].varID;
+  int varID = streamptr->tsteps[tsID].recinfo[recID].varID;
   size_t recsize = streamptr->tsteps[tsID].records[recID].size;
 
   int gridID = vlistInqVarGrid(vlistID, varID);
@@ -167,7 +167,7 @@ grb_read_raw_data(stream_t *streamptr, int tsID, int recID, int memType, void *g
       if (!resetFilePos) streamptr->numvals += (SizeType) gridsize;
     }
 
-  return (JobArgsGRB){
+  return (JobArgsGRB) {
     .recID = recID,
     .tsID = tsID,
     .outZip = &streamptr->tsteps[tsID].records[recID].zip,
diff --git a/src/grb_write.c b/src/grb_write.c
index 9ece9e4c1..217904313 100644
--- a/src/grb_write.c
+++ b/src/grb_write.c
@@ -224,7 +224,8 @@ grbCopyField(stream_t *streamptr2, stream_t *streamptr1)
   int tsID = streamptr1->curTsID;
   int vrecID = streamptr1->tsteps[tsID].curRecID;
   int recID = streamptr1->tsteps[tsID].recIDs[vrecID];
-  const record_t *record = &streamptr1->tsteps[tsID].records[recID];
+  const recinfo_t *recinfo = &(streamptr1->tsteps[tsID].recinfo[recID]);
+  const record_t *record = &(streamptr1->tsteps[tsID].records[recID]);
   off_t recpos = record->position;
   size_t recsize = record->size;
 
@@ -347,8 +348,7 @@ grbCopyField(stream_t *streamptr2, stream_t *streamptr1)
   if (streamptr2->protocol == CDI_PROTOCOL_FDB)
     {
       int vlistID = streamptr1->vlistID;
-      int varID = record->varID;
-      int zaxisID = vlistInqVarZaxis(vlistID, varID);
+      int zaxisID = vlistInqVarZaxis(vlistID, recinfo->varID);
       int zaxisType = zaxisInqType(zaxisID);
       CdiDateTime vDateTime = streamptr1->tsteps[tsID].taxis.vDateTime;
 
@@ -443,7 +443,7 @@ grb_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, co
     case CDI_PROTOCOL_FILE:
       {
         size_t (*myFileWrite)(int fileID, const void *restrict buffer, size_t len)
-            = (size_t(*)(int, const void *restrict, size_t)) namespaceSwitchGet(NSSWITCH_FILE_WRITE).func;
+            = (size_t (*)(int, const void *restrict, size_t)) namespaceSwitchGet(NSSWITCH_FILE_WRITE).func;
 
         size_t nwrite = myFileWrite(fileID, gribbuffer, nbytes);
         if (nwrite != nbytes) SysError("Failed to write GRIB slice!");
diff --git a/src/grid.c b/src/grid.c
index 9e2897e92..f29d333f0 100644
--- a/src/grid.c
+++ b/src/grid.c
@@ -989,9 +989,7 @@ gridInqSize(int gridID)
     {
       size_t xsize = gridptr->x.size;
       size_t ysize = gridptr->y.size;
-
       size = ysize ? xsize * ysize : xsize;
-
       gridptr->size = size;
     }
 
@@ -2194,7 +2192,7 @@ compareXYvals2(grid_t *gridRef, grid_t *gridTest)
                 || ((gridTest->x.bounds == NULL) ^ (gridRef->x.bounds == NULL))
                 || ((gridTest->y.bounds == NULL) ^ (gridRef->y.bounds == NULL));
 
-  typedef double (*inqVal)(grid_t * grid, SizeType index);
+  typedef double (*inqVal)(grid_t *grid, SizeType index);
   inqVal inqXValRef = gridRef->vtable->inqXVal, inqYValRef = gridRef->vtable->inqYVal, inqXValTest = gridTest->vtable->inqXVal,
          inqYValTest = gridTest->vtable->inqYVal;
 
@@ -4871,7 +4869,7 @@ cdiVlistAddGridIfNew(int vlistID, grid_t *grid, int mode)
         }
     }
 
-  return (struct addIfNewRes){ .Id = gridID, .isNew = (!gridIsDefined && !gridIsDefinedGlobal) };
+  return (struct addIfNewRes) { .Id = gridID, .isNew = (!gridIsDefined && !gridIsDefinedGlobal) };
 }
 
 const struct gridVirtTable cdiGridVtable = {
diff --git a/src/stream.c b/src/stream.c
index dfd969ae7..646219c5c 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -1233,16 +1233,12 @@ cdiStreamCloseDefaultDelegate(stream_t *streamptr, int recordBufIsToBeDeleted)
         cdfClose(fileID);
         if (streamptr->ntsteps == 0 && streamptr->tsteps != NULL)
           {
-            if (streamptr->tsteps[0].records)
-              {
-                Free(streamptr->tsteps[0].records);
-                streamptr->tsteps[0].records = NULL;
-              }
-            if (streamptr->tsteps[0].recIDs)
-              {
-                Free(streamptr->tsteps[0].recIDs);
-                streamptr->tsteps[0].recIDs = NULL;
-              }
+            tsteps_t *tstep = &(streamptr->tsteps[0]);
+            // clang-format off
+            if (tstep->recinfo) { Free(tstep->recinfo); tstep->recinfo = NULL; }
+            if (tstep->records) { Free(tstep->records); tstep->records = NULL; }
+            if (tstep->recIDs) { Free(tstep->recIDs); tstep->recIDs = NULL; }
+            // clang-format on
           }
         break;
       }
@@ -1306,8 +1302,11 @@ streamDestroyViaDelegate(stream_t *streamptr, void (*streamCloseDelegate)(stream
       for (int index = 0; index < maxSteps; ++index)
         {
           tsteps_t *tstep = &(streamptr->tsteps[index]);
-          if (tstep->records) Free(tstep->records);
-          if (tstep->recIDs) Free(tstep->recIDs);
+          // clang-format off
+          if (tstep->recinfo) { Free(tstep->recinfo); tstep->recinfo = NULL; }
+          if (tstep->records) { Free(tstep->records); tstep->records = NULL; }
+          if (tstep->recIDs) { Free(tstep->recIDs); tstep->recIDs = NULL; }
+          // clang-format on
           taxisDestroyKernel(&(tstep->taxis));
         }
 
@@ -1466,9 +1465,10 @@ cdiStreamDefTimestep_(stream_t *streamptr, int tsID)
   streamptr->curTsID = tsID;
   streamptr->ntsteps = tsID + 1;
 
+  bool baseFiletypeIsNetCDF = (cdiBaseFiletype(streamptr->filetype) == CDI_FILETYPE_NETCDF);
 #ifdef HAVE_LIBNETCDF
   int timeIsVarying = vlistHasTime(vlistID);
-  if (cdiBaseFiletype(streamptr->filetype) == CDI_FILETYPE_NETCDF && timeIsVarying)
+  if (baseFiletypeIsNetCDF && timeIsVarying)
     {
       /* usually points to cdfDefTimestep in serial mode but
        * to cdiPioCdfDefTimestep on servers and to a null-op on
@@ -1479,7 +1479,7 @@ cdiStreamDefTimestep_(stream_t *streamptr, int tsID)
     }
 #endif
 
-  cdi_create_records(streamptr, tsID);
+  cdi_create_records(streamptr, tsID, !baseFiletypeIsNetCDF);
 
   return (int) streamptr->ntsteps;
 }
@@ -2035,16 +2035,12 @@ freePtrAfterNCMem(stream_t *streamptr, int recordBufIsToBeDeleted)
 
   if (streamptr->ntsteps == 0 && streamptr->tsteps != NULL)
     {
-      if (streamptr->tsteps[0].records)
-        {
-          Free(streamptr->tsteps[0].records);
-          streamptr->tsteps[0].records = NULL;
-        }
-      if (streamptr->tsteps[0].recIDs)
-        {
-          Free(streamptr->tsteps[0].recIDs);
-          streamptr->tsteps[0].recIDs = NULL;
-        }
+      tsteps_t *tstep = &(streamptr->tsteps[0]);
+      // clang-format off
+      if (tstep->recinfo) { Free(tstep->recinfo); tstep->recinfo = NULL; }
+      if (tstep->records) { Free(tstep->records); tstep->records = NULL; }
+      if (tstep->recIDs) { Free(tstep->recIDs); tstep->recIDs = NULL; }
+      // clang-format on
     }
 }
 
diff --git a/src/stream_cdf_o.c b/src/stream_cdf_o.c
index 4be42ced0..196eba54b 100644
--- a/src/stream_cdf_o.c
+++ b/src/stream_cdf_o.c
@@ -24,7 +24,7 @@ cdfCopyField(stream_t *streamptr2, stream_t *streamptr1)
   int tsID = streamptr1->curTsID;
   int vrecID = streamptr1->tsteps[tsID].curRecID;
   int recID = streamptr1->tsteps[tsID].recIDs[vrecID];
-  int ivarID = streamptr1->tsteps[tsID].records[recID].varID;
+  int ivarID = streamptr1->tsteps[tsID].recinfo[recID].varID;
   int gridID = vlistInqVarGrid(vlistID1, ivarID);
   size_t datasize = (size_t) gridInqSize(gridID);
   int datatype = vlistInqVarDatatype(vlistID1, ivarID);
diff --git a/src/stream_cgribex.c b/src/stream_cgribex.c
index 6b2bca3fe..94d9e134d 100644
--- a/src/stream_cgribex.c
+++ b/src/stream_cgribex.c
@@ -548,7 +548,8 @@ cgribexAddRecord(stream_t *streamptr, cgribexrec_t *cgribexp, int param, size_t
   int vlistID = streamptr->vlistID;
   int tsID = streamptr->curTsID;
   int recID = recordNewEntry(streamptr, tsID);
-  record_t *record = &streamptr->tsteps[tsID].records[recID];
+  recinfo_t *recinfo = &(streamptr->tsteps[tsID].recinfo[recID]);
+  record_t *record = &(streamptr->tsteps[tsID].records[recID]);
 
   int tsteptype = cgribexGetTsteptype(ISEC1_TimeRange);
 
@@ -602,8 +603,8 @@ cgribexAddRecord(stream_t *streamptr, cgribexrec_t *cgribexp, int param, size_t
   varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2, 0, 0, datatype, &varID, &levelID, tsteptype, leveltype, -1,
                NULL, NULL, NULL, NULL);
 
-  record->varID = (short) varID;
-  record->levelID = levelID;
+  recinfo->varID = (short) varID;
+  recinfo->levelID = levelID;
 
   varDefCompType(varID, comptype);
 
@@ -958,7 +959,8 @@ cgribexScanTimestep2(stream_t *streamptr)
 
   fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
-  cdi_create_records(streamptr, tsID);
+  cdi_create_records(streamptr, tsID, true);
+  recinfo_t *recinfo = streamptr->tsteps[tsID].recinfo;
   record_t *records = streamptr->tsteps[tsID].records;
 
   int nrecords = streamScanInitRecords2(streamptr);
@@ -1044,19 +1046,19 @@ cgribexScanTimestep2(stream_t *streamptr)
 
       if (CDI_Inventory_Mode == 1)
         {
-          if (records[recID].used)
+          if (recinfo[recID].used)
             {
               break;
             }
           else
             {
-              records[recID].used = true;
+              recinfo[recID].used = true;
               streamptr->tsteps[tsID].recIDs[rindex] = recID;
             }
         }
       else
         {
-          if (records[recID].used)
+          if (recinfo[recID].used)
             {
               if (cdiDateTime_isNE(vDateTime, vDateTime0)) break;
 
@@ -1065,7 +1067,7 @@ cgribexScanTimestep2(stream_t *streamptr)
             }
           else
             {
-              records[recID].used = true;
+              recinfo[recID].used = true;
               streamptr->tsteps[tsID].recIDs[rindex] = recID;
             }
         }
@@ -1084,7 +1086,7 @@ cgribexScanTimestep2(stream_t *streamptr)
       records[recID].position = recpos;
       records[recID].size = recsize;
 
-      int varID = records[recID].varID;
+      int varID = recinfo[recID].varID;
       int gridID = vlistInqVarGrid(vlistID, varID);
       if (gridInqSize(gridID) == 1 && gridInqType(gridID) == GRID_LONLAT)
         {
@@ -1102,10 +1104,10 @@ cgribexScanTimestep2(stream_t *streamptr)
   int nrecs = 0;
   for (recID = 0; recID < nrecords; recID++)
     {
-      if (records[recID].used)
+      if (recinfo[recID].used)
         nrecs++;
       else
-        vlistDefVarTimetype(vlistID, records[recID].varID, TIME_CONSTANT);
+        vlistDefVarTimetype(vlistID, recinfo[recID].varID, TIME_CONSTANT);
     }
   streamptr->tsteps[tsID].nrecs = nrecs;
 
@@ -1143,7 +1145,8 @@ cgribexScanTimestep(stream_t *streamptr)
       void *gribbuffer = streamptr->record->buffer;
       size_t buffersize = streamptr->record->buffersize;
 
-      cdi_create_records(streamptr, tsID);
+      cdi_create_records(streamptr, tsID, true);
+      recinfo_t *recinfo = streamptr->tsteps[tsID].recinfo;
       record_t *records = streamptr->tsteps[tsID].records;
 
       nrecs = streamScanInitRecords(streamptr, tsID);
@@ -1243,12 +1246,12 @@ cgribexScanTimestep(stream_t *streamptr)
 
           if (CDI_Inventory_Mode == 1)
             {
-              records[recID].used = true;
+              recinfo[recID].used = true;
               streamptr->tsteps[tsID].recIDs[rindex] = recID;
             }
           else
             {
-              if (records[recID].used)
+              if (recinfo[recID].used)
                 {
                   char paramstr_[32];
                   cdiParamToString(param, paramstr_, sizeof(paramstr_));
@@ -1262,7 +1265,7 @@ cgribexScanTimestep(stream_t *streamptr)
                 }
               else
                 {
-                  records[recID].used = true;
+                  recinfo[recID].used = true;
                   streamptr->tsteps[tsID].recIDs[rindex] = recID;
                 }
             }
@@ -1287,7 +1290,7 @@ cgribexScanTimestep(stream_t *streamptr)
       for (vrecID = 0; vrecID < nrecs; vrecID++)
         {
           recID = streamptr->tsteps[tsID].recIDs[vrecID];
-          if (!records[recID].used) break;
+          if (!recinfo[recID].used) break;
         }
 
       if (vrecID < nrecs)
diff --git a/src/stream_ext.c b/src/stream_ext.c
index 616ef92dc..a5cd4f5ae 100644
--- a/src/stream_ext.c
+++ b/src/stream_ext.c
@@ -47,7 +47,7 @@ ext_read_recordSP(stream_t *streamptr, float *data, size_t *numMissVals)
 
   int vrecID = streamptr->tsteps[tsID].curRecID;
   int recID = streamptr->tsteps[tsID].recIDs[vrecID];
-  int varID = streamptr->tsteps[tsID].records[recID].varID;
+  int varID = streamptr->tsteps[tsID].recinfo[recID].varID;
   off_t recpos = streamptr->tsteps[tsID].records[recID].position;
 
   fileSetPos(fileID, recpos, SEEK_SET);
@@ -79,7 +79,7 @@ ext_read_recordDP(stream_t *streamptr, double *data, size_t *numMissVals)
 
   int vrecID = streamptr->tsteps[tsID].curRecID;
   int recID = streamptr->tsteps[tsID].recIDs[vrecID];
-  int varID = streamptr->tsteps[tsID].records[recID].varID;
+  int varID = streamptr->tsteps[tsID].recinfo[recID].varID;
   off_t recpos = streamptr->tsteps[tsID].records[recID].position;
 
   fileSetPos(fileID, recpos, SEEK_SET);
@@ -169,7 +169,8 @@ extAddRecord(stream_t *streamptr, int param, int level, size_t xysize, size_t re
   int vlistID = streamptr->vlistID;
   int tsID = streamptr->curTsID;
   int recID = recordNewEntry(streamptr, tsID);
-  record_t *record = &streamptr->tsteps[tsID].records[recID];
+  recinfo_t *recinfo = &(streamptr->tsteps[tsID].recinfo[recID]);
+  record_t *record = &(streamptr->tsteps[tsID].records[recID]);
 
   record->size = recsize;
   record->position = position;
@@ -196,8 +197,8 @@ extAddRecord(stream_t *streamptr, int param, int level, size_t xysize, size_t re
   varAddRecord(recID, param, gridID, leveltype, 0, level, 0, 0, 0, datatype, &varID, &levelID, TSTEP_INSTANT, 0, -1, NULL, NULL,
                NULL, NULL);
 
-  record->varID = (short) varID;
-  record->levelID = levelID;
+  recinfo->varID = (short) varID;
+  recinfo->levelID = levelID;
 
   streamptr->tsteps[tsID].nallrecs++;
   streamptr->nrecs++;
@@ -304,7 +305,8 @@ extScanTimestep2(stream_t *streamptr)
 
   fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
-  cdi_create_records(streamptr, tsID);
+  cdi_create_records(streamptr, tsID, true);
+  recinfo_t *recinfo = streamptr->tsteps[tsID].recinfo;
   record_t *records = streamptr->tsteps[tsID].records;
 
   int nrecords = streamScanInitRecords2(streamptr);
@@ -340,13 +342,13 @@ extScanTimestep2(stream_t *streamptr)
         {
           if (param == records[recID].param && rlevel == records[recID].ilevel)
             {
-              if (records[recID].used)
+              if (recinfo[recID].used)
                 {
                   nextstep = true;
                 }
               else
                 {
-                  records[recID].used = true;
+                  recinfo[recID].used = true;
                   streamptr->tsteps[tsID].recIDs[rindex] = recID;
                 }
               break;
@@ -376,10 +378,10 @@ extScanTimestep2(stream_t *streamptr)
   int nrecs = 0;
   for (int recID = 0; recID < nrecords; recID++)
     {
-      if (records[recID].used)
+      if (recinfo[recID].used)
         nrecs++;
       else
-        vlistDefVarTimetype(vlistID, records[recID].varID, TIME_CONSTANT);
+        vlistDefVarTimetype(vlistID, recinfo[recID].varID, TIME_CONSTANT);
     }
   streamptr->tsteps[tsID].nrecs = nrecs;
 
@@ -417,7 +419,7 @@ extScanTimestep(stream_t *streamptr)
 
   if (streamptr->tsteps[tsID].recordSize == 0)
     {
-      cdi_create_records(streamptr, tsID);
+      cdi_create_records(streamptr, tsID, true);
       record_t *records = streamptr->tsteps[tsID].records;
 
       nrecs = streamScanInitRecords(streamptr, tsID);
diff --git a/src/stream_gribapi.c b/src/stream_gribapi.c
index 7d895bb91..28d9137a6 100644
--- a/src/stream_gribapi.c
+++ b/src/stream_gribapi.c
@@ -710,7 +710,8 @@ gribapiAddRecord(stream_t *streamptr, int param, grib_handle *gh, size_t recsize
   int vlistID = streamptr->vlistID;
   int tsID = streamptr->curTsID;
   int recID = recordNewEntry(streamptr, tsID);
-  record_t *record = &streamptr->tsteps[tsID].records[recID];
+  recinfo_t *recinfo = &(streamptr->tsteps[tsID].recinfo[recID]);
+  record_t *record = &(streamptr->tsteps[tsID].records[recID]);
 
   int tsteptype = gribapiGetTsteptype(gh);
 
@@ -743,7 +744,7 @@ gribapiAddRecord(stream_t *streamptr, int param, grib_handle *gh, size_t recsize
   CdiQuery *query = streamptr->query;
   if (query && cdiQueryName(query, varname) < 0)
     {
-      record->used = false;
+      recinfo->used = false;
       return;
     }
 
@@ -814,8 +815,8 @@ gribapiAddRecord(stream_t *streamptr, int param, grib_handle *gh, size_t recsize
   varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2, level_sf, level_unit, datatype, &varID, &levelID,
                tsteptype, leveltype1, leveltype2, varname, scanKeys, tiles, &tile_index);
 
-  record->varID = (short) varID;
-  record->levelID = levelID;
+  recinfo->varID = (short) varID;
+  recinfo->levelID = levelID;
 
   varDefCompType(varID, comptype);
 
@@ -1173,7 +1174,8 @@ fdbScanTimesteps(stream_t *streamptr)
 
       taxis = &streamptr->tsteps[tsID].taxis;
 
-      cdi_create_records(streamptr, tsID);
+      cdi_create_records(streamptr, tsID, true);
+      recinfo_t *recinfo = streamptr->tsteps[tsID].recinfo;
       record_t *records = streamptr->tsteps[tsID].records;
 
       int nrecs = (tsID == 1) ? streamScanInitRecords2(streamptr) : streamScanInitRecords(streamptr, tsID);
@@ -1184,7 +1186,7 @@ fdbScanTimesteps(stream_t *streamptr)
       int rindex = 0;
       for (int recID = 0; recID < numRecords; recID++)
         {
-          records[recID].used = true;
+          recinfo[recID].used = true;
           streamptr->tsteps[tsID].recIDs[rindex] = recID;
           rindex++;
 
@@ -1216,6 +1218,7 @@ records_cmp_varname(const void *s1, const void *s2)
   return strcmp(x->varname, y->varname);
 }
 
+/*
 void
 sort_records(stream_t *streamptr)
 {
@@ -1223,6 +1226,7 @@ sort_records(stream_t *streamptr)
   size_t numRecords = (size_t) streamptr->tsteps[0].recordSize;
   qsort(records, numRecords, sizeof(records[0]), records_cmp_varname);
 }
+*/
 
 long
 gribapiScanTimestep1(stream_t *streamptr)
@@ -1373,7 +1377,7 @@ gribapiScanTimestep1(stream_t *streamptr)
   streamScanTsFixNtsteps(streamptr, recpos);
   streamScanTimeConstAdjust(streamptr, taxis);
 
-  if (streamptr->sortname) sort_records(streamptr);
+  // if (streamptr->sortname) sort_records(streamptr);
 
   return 0;
 }
@@ -1404,7 +1408,8 @@ gribapiScanTimestep2(stream_t *streamptr)
 
   fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
-  cdi_create_records(streamptr, tsID);
+  cdi_create_records(streamptr, tsID, true);
+  recinfo_t *recinfo = streamptr->tsteps[tsID].recinfo;
   record_t *records = streamptr->tsteps[tsID].records;
 
   int nrecords = streamScanInitRecords2(streamptr);
@@ -1492,7 +1497,7 @@ gribapiScanTimestep2(stream_t *streamptr)
             }
         }
 
-      if (records[recID].used)
+      if (recinfo[recID].used)
         {
           if (CDI_Inventory_Mode == 1)
             break;
@@ -1505,7 +1510,7 @@ gribapiScanTimestep2(stream_t *streamptr)
             }
         }
 
-      records[recID].used = true;
+      recinfo[recID].used = true;
       streamptr->tsteps[tsID].recIDs[rindex] = recID;
 
       if (CDI_Debug)
@@ -1526,7 +1531,7 @@ gribapiScanTimestep2(stream_t *streamptr)
       records[recID].position = recpos;
       records[recID].size = recsize;
 
-      int varID = records[recID].varID;
+      int varID = recinfo[recID].varID;
 
       if (tsteptype != vlistInqVarTsteptype(vlistID, varID)) vlistDefVarTsteptype(vlistID, varID, tsteptype);
 
@@ -1539,10 +1544,10 @@ gribapiScanTimestep2(stream_t *streamptr)
   int nrecs = 0;
   for (recID = 0; recID < nrecords; recID++)
     {
-      if (records[recID].used)
+      if (recinfo[recID].used)
         nrecs++;
       else
-        vlistDefVarTimetype(vlistID, records[recID].varID, TIME_CONSTANT);
+        vlistDefVarTimetype(vlistID, recinfo[recID].varID, TIME_CONSTANT);
     }
   streamptr->tsteps[tsID].nrecs = nrecs;
 
@@ -1570,7 +1575,8 @@ gribapiScanTimestep(stream_t *streamptr)
       void *gribbuffer = streamptr->record->buffer;
       size_t buffersize = streamptr->record->buffersize;
 
-      cdi_create_records(streamptr, tsID);
+      cdi_create_records(streamptr, tsID, true);
+      recinfo_t *recinfo = streamptr->tsteps[tsID].recinfo;
       record_t *records = streamptr->tsteps[tsID].records;
 
       nrecs = streamScanInitRecords(streamptr, tsID);
@@ -1679,7 +1685,7 @@ gribapiScanTimestep(stream_t *streamptr)
 
           if (CDI_Inventory_Mode != 1)
             {
-              if (records[recID].used)
+              if (recinfo[recID].used)
                 {
                   if (cdiDateTime_isNE(vDateTime, vDateTime0)) break;
 
@@ -1690,7 +1696,7 @@ gribapiScanTimestep(stream_t *streamptr)
                 }
             }
 
-          records[recID].used = true;
+          recinfo[recID].used = true;
           streamptr->tsteps[tsID].recIDs[rindex] = recID;
 
           if (CDI_Debug)
@@ -1717,7 +1723,7 @@ gribapiScanTimestep(stream_t *streamptr)
       for (vrecID = 0; vrecID < nrecs; vrecID++)
         {
           recID = streamptr->tsteps[tsID].recIDs[vrecID];
-          if (!records[recID].used) break;
+          if (!recinfo[recID].used) break;
         }
 
       if (vrecID < nrecs)
diff --git a/src/stream_ieg.c b/src/stream_ieg.c
index 072544bfb..9caeadf6f 100644
--- a/src/stream_ieg.c
+++ b/src/stream_ieg.c
@@ -44,7 +44,7 @@ ieg_read_recordSP(stream_t *streamptr, float *data, size_t *numMissVals)
 
   int vrecID = streamptr->tsteps[tsID].curRecID;
   int recID = streamptr->tsteps[tsID].recIDs[vrecID];
-  int varID = streamptr->tsteps[tsID].records[recID].varID;
+  int varID = streamptr->tsteps[tsID].recinfo[recID].varID;
   off_t recpos = streamptr->tsteps[tsID].records[recID].position;
 
   fileSetPos(fileID, recpos, SEEK_SET);
@@ -71,7 +71,7 @@ ieg_read_recordDP(stream_t *streamptr, double *data, size_t *numMissVals)
 
   int vrecID = streamptr->tsteps[tsID].curRecID;
   int recID = streamptr->tsteps[tsID].recIDs[vrecID];
-  int varID = streamptr->tsteps[tsID].records[recID].varID;
+  int varID = streamptr->tsteps[tsID].recinfo[recID].varID;
   off_t recpos = streamptr->tsteps[tsID].records[recID].position;
 
   fileSetPos(fileID, recpos, SEEK_SET);
@@ -521,7 +521,8 @@ iegAddRecord(stream_t *streamptr, int param, int *pdb, int *gdb, double *vct, si
   int vlistID = streamptr->vlistID;
   int tsID = streamptr->curTsID;
   int recID = recordNewEntry(streamptr, tsID);
-  record_t *record = &streamptr->tsteps[tsID].records[recID];
+  recinfo_t *recinfo = &(streamptr->tsteps[tsID].recinfo[recID]);
+  record_t *record = &(streamptr->tsteps[tsID].records[recID]);
 
   int level1, level2;
   if (IEG_P_LevelType(pdb) == IEG_LTYPE_HYBRID_LAYER)
@@ -641,8 +642,8 @@ iegAddRecord(stream_t *streamptr, int param, int *pdb, int *gdb, double *vct, si
   varAddRecord(recID, param, gridID, leveltype, lbounds, level1, level2, 0, 0, datatype, &varID, &levelID, TSTEP_INSTANT, 0, -1,
                NULL, NULL, NULL, NULL);
 
-  record->varID = (short) varID;
-  record->levelID = levelID;
+  recinfo->varID = (short) varID;
+  recinfo->levelID = levelID;
 
   streamptr->tsteps[tsID].nallrecs++;
   streamptr->nrecs++;
@@ -791,7 +792,8 @@ iegScanTimestep2(stream_t *streamptr)
 
   fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
-  cdi_create_records(streamptr, tsID);
+  cdi_create_records(streamptr, tsID, true);
+  recinfo_t *recinfo = streamptr->tsteps[tsID].recinfo;
   record_t *records = streamptr->tsteps[tsID].records;
 
   int nrecords = streamScanInitRecords2(streamptr);
@@ -828,13 +830,13 @@ iegScanTimestep2(stream_t *streamptr)
         {
           if (param == records[recID].param && rlevel == records[recID].ilevel)
             {
-              if (records[recID].used)
+              if (recinfo[recID].used)
                 {
                   nextstep = true;
                 }
               else
                 {
-                  records[recID].used = true;
+                  recinfo[recID].used = true;
                   streamptr->tsteps[tsID].recIDs[rindex] = recID;
                 }
               break;
@@ -866,10 +868,10 @@ iegScanTimestep2(stream_t *streamptr)
   int nrecs = 0;
   for (int recID = 0; recID < nrecords; recID++)
     {
-      if (records[recID].used)
+      if (recinfo[recID].used)
         nrecs++;
       else
-        vlistDefVarTimetype(vlistID, records[recID].varID, TIME_CONSTANT);
+        vlistDefVarTimetype(vlistID, recinfo[recID].varID, TIME_CONSTANT);
     }
   streamptr->tsteps[tsID].nrecs = nrecs;
 
@@ -908,7 +910,7 @@ iegScanTimestep(stream_t *streamptr)
   int nrecs = 0;
   if (streamptr->tsteps[tsID].recordSize == 0)
     {
-      cdi_create_records(streamptr, tsID);
+      cdi_create_records(streamptr, tsID, true);
       record_t *records = streamptr->tsteps[tsID].records;
 
       nrecs = streamScanInitRecords(streamptr, tsID);
diff --git a/src/stream_record.c b/src/stream_record.c
index 5660b47a6..4fadd14cb 100644
--- a/src/stream_record.c
+++ b/src/stream_record.c
@@ -17,6 +17,14 @@
 #include "stream_ieg.h"
 
 void
+recinfoInitEntry(recinfo_t *recinfo)
+{
+  recinfo->varID = CDI_UNDEFID;
+  recinfo->levelID = CDI_UNDEFID;
+  recinfo->used = false;
+}
+
+static void
 recordInitEntry(record_t *record)
 {
   record->position = CDI_UNDEFID;
@@ -24,10 +32,7 @@ recordInitEntry(record_t *record)
   record->gridsize = 0;
   record->param = 0;
   record->ilevel = CDI_UNDEFID;
-  record->used = false;
   record->tsteptype = CDI_UNDEFID;
-  record->varID = CDI_UNDEFID;
-  record->levelID = CDI_UNDEFID;
 #ifdef HAVE_LIBGRIB
   varScanKeysInit(&record->scanKeys);
   memset(&record->tiles, 0, sizeof(record->tiles));
@@ -44,19 +49,21 @@ int
 recordNewEntry(stream_t *streamptr, int tsID)
 {
   int recordSize = streamptr->tsteps[tsID].recordSize;
+  recinfo_t *recinfo = streamptr->tsteps[tsID].recinfo;
   record_t *records = streamptr->tsteps[tsID].records;
 
   // Look for a free slot in record.
   int recordID = 0;
   if (recordSize)
     {
-      while (recordID < recordSize && records[recordID].used != CDI_UNDEFID) ++recordID;
+      while (recordID < recordSize && recinfo[recordID].used != CDI_UNDEFID) ++recordID;
     }
   else  // Create the table the first time through.
     {
       recordSize = 1;  //  <<<<----
+      recinfo = (recinfo_t *) Malloc((size_t) recordSize * sizeof(recinfo_t));
       records = (record_t *) Malloc((size_t) recordSize * sizeof(record_t));
-      for (int i = recordID; i < recordSize; i++) records[i].used = CDI_UNDEFID;
+      for (int i = recordID; i < recordSize; i++) recinfo[i].used = CDI_UNDEFID;
     }
 
   // If the table overflows, double its size.
@@ -67,16 +74,19 @@ recordNewEntry(stream_t *streamptr, int tsID)
       else if (recordSize < INT_MAX)      recordSize = INT_MAX;
       else Error("Cannot handle this many records!\n");
       // clang-format on
+      recinfo = (recinfo_t *) Realloc(recinfo, (size_t) recordSize * sizeof(recinfo_t));
       records = (record_t *) Realloc(records, (size_t) recordSize * sizeof(record_t));
 
-      for (int i = recordID; i < recordSize; i++) records[i].used = CDI_UNDEFID;
+      for (int i = recordID; i < recordSize; i++) recinfo[i].used = CDI_UNDEFID;
     }
 
+  recinfoInitEntry(&recinfo[recordID]);
   recordInitEntry(&records[recordID]);
 
-  records[recordID].used = true;
+  recinfo[recordID].used = true;
 
   streamptr->tsteps[tsID].recordSize = recordSize;
+  streamptr->tsteps[tsID].recinfo = recinfo;
   streamptr->tsteps[tsID].records = records;
 
   return recordID;
@@ -121,10 +131,10 @@ streamInqField(int streamID, int *varID, int *levelID)
 
   if (recID == -1 || recID >= streamptr->tsteps[tsID].nallrecs) Error("Internal problem! tsID = %d recID = %d", tsID, recID);
 
-  *varID = streamptr->tsteps[tsID].records[recID].varID;
+  *varID = streamptr->tsteps[tsID].recinfo[recID].varID;
   if (*varID == -1) Error("Internal problem! varID = %d recID = %d", *varID, recID);
 
-  int lindex = streamptr->tsteps[tsID].records[recID].levelID;
+  int lindex = streamptr->tsteps[tsID].recinfo[recID].levelID;
 
   int isub = subtypeInqActiveIndex(streamptr->vars[*varID].subtypeID);
   *levelID = streamptr->vars[*varID].recordTable[isub].lindex[lindex];
@@ -239,14 +249,14 @@ streamCopyField(int streamID2, int streamID1)
 }
 
 void
-cdi_create_records(stream_t *streamptr, int tsID)
+cdi_create_records(stream_t *streamptr, int tsID, bool allocRecords)
 {
   unsigned nrecords, maxrecords;
 
   tsteps_t *sourceTstep = streamptr->tsteps;
   tsteps_t *destTstep = sourceTstep + tsID;
 
-  if (destTstep->records) return;
+  if (destTstep->recinfo) return;
 
   int vlistID = streamptr->vlistID;
 
@@ -275,7 +285,7 @@ cdi_create_records(stream_t *streamptr, int tsID)
         {
           for (size_t recID = 0; recID < maxrecords; recID++)
             {
-              int varID = sourceTstep->records[recID].varID;
+              int varID = sourceTstep->recinfo[recID].varID;
               nrecords += (varID == CDI_UNDEFID /* varID = CDI_UNDEFID for write mode !!! */
                            || vlistInqVarTimetype(vlistID, varID) != TIME_CONSTANT);
               //    printf("varID nrecords %d %d %d \n", varID, nrecords, vlistInqVarTsteptype(vlistID, varID));
@@ -292,8 +302,10 @@ cdi_create_records(stream_t *streamptr, int tsID)
     }
   //  printf("tsID, nrecords %d %d\n", tsID, nrecords);
 
-  record_t *records = (maxrecords > 0) ? (record_t *) (Malloc(maxrecords * sizeof(record_t))) : (record_t *) NULL;
+  recinfo_t *recinfo = (maxrecords > 0) ? (recinfo_t *) Malloc(maxrecords * sizeof(recinfo_t)) : (recinfo_t *) NULL;
+  record_t *records = (allocRecords && maxrecords > 0) ? (record_t *) Malloc(maxrecords * sizeof(record_t)) : (record_t *) NULL;
 
+  destTstep->recinfo = recinfo;
   destTstep->records = records;
   destTstep->recordSize = (int) maxrecords;
   destTstep->nallrecs = (int) nrecords;
@@ -303,23 +315,26 @@ cdi_create_records(stream_t *streamptr, int tsID)
 
   if (tsID == 0)
     {
-      for (unsigned recID = 0; recID < maxrecords; recID++) recordInitEntry(&destTstep->records[recID]);
+      for (unsigned recID = 0; recID < maxrecords; recID++) recinfoInitEntry(&destTstep->recinfo[recID]);
+      if (allocRecords)
+        for (unsigned recID = 0; recID < maxrecords; recID++) recordInitEntry(&destTstep->records[recID]);
     }
-  else if (sourceTstep->records)
+  else if (sourceTstep->recinfo)
     {
-      memcpy(destTstep->records, sourceTstep->records, (size_t) maxrecords * sizeof(record_t));
+      memcpy(destTstep->recinfo, sourceTstep->recinfo, (size_t) maxrecords * sizeof(recinfo_t));
+      if (allocRecords) memcpy(destTstep->records, sourceTstep->records, (size_t) maxrecords * sizeof(record_t));
 
       for (size_t recID = 0; recID < maxrecords; recID++)
         {
-          record_t *curRecord = &sourceTstep->records[recID];
-          destTstep->records[recID].used = curRecord->used;
+          recinfo_t *curRecord = &sourceTstep->recinfo[recID];
+          destTstep->recinfo[recID].used = curRecord->used;
           if (curRecord->used != CDI_UNDEFID && curRecord->varID != -1)  // curRecord->varID = -1 for write mode !!!
             {
               if (vlistInqVarTimetype(vlistID, curRecord->varID) != TIME_CONSTANT)
                 {
-                  destTstep->records[recID].position = CDI_UNDEFID;
-                  destTstep->records[recID].size = 0;
-                  destTstep->records[recID].used = false;
+                  if (allocRecords) destTstep->records[recID].position = CDI_UNDEFID;
+                  if (allocRecords) destTstep->records[recID].size = 0;
+                  destTstep->recinfo[recID].used = false;
                 }
             }
         }
diff --git a/src/stream_scan.c b/src/stream_scan.c
index b1f4488a7..a4531bf58 100644
--- a/src/stream_scan.c
+++ b/src/stream_scan.c
@@ -16,10 +16,11 @@
 void
 streamScanResizeRecords1(stream_t *streamptr)
 {
-  const int nrecords = streamptr->tsteps[0].nallrecs;
+  int nrecords = streamptr->tsteps[0].nallrecs;
   if (nrecords < streamptr->tsteps[0].recordSize)
     {
       streamptr->tsteps[0].recordSize = nrecords;
+      streamptr->tsteps[0].recinfo = (recinfo_t *) Realloc(streamptr->tsteps[0].recinfo, (size_t) nrecords * sizeof(recinfo_t));
       streamptr->tsteps[0].records = (record_t *) Realloc(streamptr->tsteps[0].records, (size_t) nrecords * sizeof(record_t));
     }
 
@@ -31,7 +32,7 @@ streamScanResizeRecords1(stream_t *streamptr)
 int
 streamScanInitRecords2(stream_t *streamptr)
 {
-  const int nrecords = streamptr->tsteps[1].nallrecs;
+  int nrecords = streamptr->tsteps[1].nallrecs;
   streamptr->tsteps[1].recIDs = (int *) Malloc((size_t) nrecords * sizeof(int));
   streamptr->tsteps[1].nrecs = 0;
 
@@ -48,7 +49,7 @@ streamScanInitRecords2(stream_t *streamptr)
 int
 streamScanInitRecords(stream_t *streamptr, int tsID)
 {
-  const int nrecs = streamptr->tsteps[1].nrecs;
+  int nrecs = streamptr->tsteps[1].nrecs;
 
   streamptr->tsteps[tsID].nrecs = nrecs;
   streamptr->tsteps[tsID].recIDs = (int *) Malloc((size_t) nrecs * sizeof(int));
@@ -61,7 +62,7 @@ streamScanInitRecords(stream_t *streamptr, int tsID)
 void
 streamScanTimeConstAdjust(stream_t *streamptr, const taxis_t *taxis)
 {
-  const int vlistID = streamptr->vlistID;
+  int vlistID = streamptr->vlistID;
   if (streamptr->ntsteps == 1 && cdiDateTime_isNull(taxis->vDateTime))
     {
       streamptr->ntsteps = 0;
@@ -74,7 +75,7 @@ streamScanTsFixNtsteps(stream_t *streamptr, off_t recpos)
 {
   if (streamptr->ntsteps == -1)
     {
-      const int tsID = tstepsNewEntry(streamptr);
+      int tsID = tstepsNewEntry(streamptr);
       if (tsID != streamptr->rtsteps) Error("Internal error. tsID = %d", tsID);
 
       streamptr->tsteps[tsID - 1].next = true;
diff --git a/src/stream_srv.c b/src/stream_srv.c
index fa1beba76..61bf91f74 100644
--- a/src/stream_srv.c
+++ b/src/stream_srv.c
@@ -43,7 +43,7 @@ srv_read_recordSP(stream_t *streamptr, float *data, size_t *numMissVals)
 
   int vrecID = streamptr->tsteps[tsID].curRecID;
   int recID = streamptr->tsteps[tsID].recIDs[vrecID];
-  int varID = streamptr->tsteps[tsID].records[recID].varID;
+  int varID = streamptr->tsteps[tsID].recinfo[recID].varID;
   off_t recpos = streamptr->tsteps[tsID].records[recID].position;
 
   fileSetPos(fileID, recpos, SEEK_SET);
@@ -72,7 +72,7 @@ srv_read_recordDP(stream_t *streamptr, double *data, size_t *numMissVals)
 
   int vrecID = streamptr->tsteps[tsID].curRecID;
   int recID = streamptr->tsteps[tsID].recIDs[vrecID];
-  int varID = streamptr->tsteps[tsID].records[recID].varID;
+  int varID = streamptr->tsteps[tsID].recinfo[recID].varID;
   off_t recpos = streamptr->tsteps[tsID].records[recID].position;
 
   fileSetPos(fileID, recpos, SEEK_SET);
@@ -175,7 +175,8 @@ srv_add_record(stream_t *streamptr, int param, int level, size_t xsize, size_t y
   int vlistID = streamptr->vlistID;
   int tsID = streamptr->curTsID;
   int recID = recordNewEntry(streamptr, tsID);
-  record_t *record = &streamptr->tsteps[tsID].records[recID];
+  recinfo_t *recinfo = &(streamptr->tsteps[tsID].recinfo[recID]);
+  record_t *record = &(streamptr->tsteps[tsID].records[recID]);
 
   record->size = recsize;
   record->position = position;
@@ -203,8 +204,8 @@ srv_add_record(stream_t *streamptr, int param, int level, size_t xsize, size_t y
                NULL, NULL);
 
   xassert(varID <= SHRT_MAX && levelID <= SHRT_MAX);
-  record->varID = (short) varID;
-  record->levelID = levelID;
+  recinfo->varID = (short) varID;
+  recinfo->levelID = levelID;
 
   streamptr->tsteps[tsID].nallrecs++;
   streamptr->nrecs++;
@@ -313,7 +314,8 @@ srvScanTimestep2(stream_t *streamptr)
 
   fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
-  cdi_create_records(streamptr, tsID);
+  cdi_create_records(streamptr, tsID, true);
+  recinfo_t *recinfo = streamptr->tsteps[tsID].recinfo;
   record_t *records = streamptr->tsteps[tsID].records;
 
   int nrecords = streamScanInitRecords2(streamptr);
@@ -349,13 +351,13 @@ srvScanTimestep2(stream_t *streamptr)
         {
           if (param == records[recID].param && rlevel == records[recID].ilevel)
             {
-              if (records[recID].used)
+              if (recinfo[recID].used)
                 {
                   nextstep = true;
                 }
               else
                 {
-                  records[recID].used = true;
+                  recinfo[recID].used = true;
                   streamptr->tsteps[tsID].recIDs[rindex] = recID;
                 }
               break;
@@ -385,10 +387,10 @@ srvScanTimestep2(stream_t *streamptr)
   int nrecs = 0;
   for (int recID = 0; recID < nrecords; recID++)
     {
-      if (records[recID].used)
+      if (recinfo[recID].used)
         nrecs++;
       else
-        vlistDefVarTimetype(vlistID, records[recID].varID, TIME_CONSTANT);
+        vlistDefVarTimetype(vlistID, recinfo[recID].varID, TIME_CONSTANT);
     }
   streamptr->tsteps[tsID].nrecs = nrecs;
 
@@ -426,7 +428,7 @@ srvScanTimestep(stream_t *streamptr)
 
   if (streamptr->tsteps[tsID].recordSize == 0)
     {
-      cdi_create_records(streamptr, tsID);
+      cdi_create_records(streamptr, tsID, true);
       record_t *records = streamptr->tsteps[tsID].records;
 
       nrecs = streamScanInitRecords(streamptr, tsID);
diff --git a/src/tsteps.c b/src/tsteps.c
index 7a22bd248..d2a6da608 100644
--- a/src/tsteps.c
+++ b/src/tsteps.c
@@ -20,6 +20,7 @@ static void
 tstepsInitEntry(tsteps_t *tstep)
 {
   tstep->recIDs = NULL;
+  tstep->recinfo = NULL;
   tstep->records = NULL;
   tstep->recordSize = 0;
   tstep->nrecs = 0;
@@ -35,7 +36,7 @@ tstepsInitEntry(tsteps_t *tstep)
 int
 tstepsNewEntry(stream_t *streamptr)
 {
-  const int tsID = streamptr->tstepsNextID++;
+  int tsID = streamptr->tstepsNextID++;
   int tstepsTableSize = streamptr->tstepsTableSize;
   tsteps_t *tstepsTable = streamptr->tsteps;
 
-- 
GitLab