@@ -319,14 +319,13 @@ DelimFileAdapter<T>::extendRead(const std::string& fileName) const {
319
319
FileIsEmpty,
320
320
fileName);
321
321
322
- auto table = std::make_shared<TimeSeriesTable_<T>>();
323
-
324
322
size_t line_num{};
325
323
// All the lines until "endheader" is header.
326
324
std::regex endheader{R"( [ \t]*)" + _endHeaderString + R"( [ \t]*)" };
327
325
std::regex keyvalue{R"( (.*)=(.*))" };
328
326
std::string header{};
329
327
std::string line{};
328
+ ValueArrayDictionary keyValuePairs;
330
329
while (std::getline (in_stream, line)) {
331
330
++line_num;
332
331
@@ -361,7 +360,7 @@ DelimFileAdapter<T>::extendRead(const std::string& fileName) const {
361
360
// Discard OpenSim version number. Version number is added
362
361
// during writing.
363
362
} else {
364
- table-> updTableMetaData () .setValueForKey (key, value);
363
+ keyValuePairs .setValueForKey (key, value);
365
364
}
366
365
continue ;
367
366
}
@@ -372,7 +371,7 @@ DelimFileAdapter<T>::extendRead(const std::string& fileName) const {
372
371
else
373
372
header += " \n " + line;
374
373
}
375
- table-> updTableMetaData () .setValueForKey (" header" , header);
374
+ keyValuePairs .setValueForKey (" header" , header);
376
375
377
376
// Callable to get the next line in form of vector of tokens.
378
377
auto nextLine = [&] {
@@ -400,39 +399,62 @@ DelimFileAdapter<T>::extendRead(const std::string& fileName) const {
400
399
_timeColumnLabel,
401
400
column_labels[0 ]);
402
401
column_labels.erase (column_labels.begin ());
403
- // Set the column labels as metadata.
404
- ValueArray<std::string> value_array{};
405
- for (const auto & cl : column_labels)
406
- value_array.upd ().push_back (SimTK::Value<std::string>{cl});
407
- typename TimeSeriesTable_<T>::DependentsMetaData dep_metadata{};
408
- dep_metadata.setValueArrayForKey (" labels" , value_array);
409
- table->setDependentsMetaData (dep_metadata);
410
402
411
403
// Read the rows one at a time and fill up the time column container and
412
- // the data container.
404
+ // the data container. Start with a reasonable initial capacity for
405
+ // tradeoff between a small file and larger files. 100 worked well for
406
+ // a 50 MB file with ~80000 lines.
407
+ std::vector<double > timeVec;
408
+ int initCapacity = 100 ;
409
+ int ncol = static_cast <int >(column_labels.size ());
410
+ timeVec.reserve (initCapacity);
411
+ SimTK::Matrix_<T> matrix (initCapacity, ncol);
412
+
413
+ // Initialize current row and capacity
414
+ int curCapacity = initCapacity;
415
+ int curRow = 0 ;
416
+
417
+ // Start looping through each line
413
418
auto row = nextLine ();
414
- while (!row.empty ()) {
419
+ while (!row.empty ()) {
415
420
++line_num;
421
+
422
+ // Double capacity if we reach the end of the containers.
423
+ // This is necessary until Simbody issue #401 is addressed.
424
+ if (curRow+1 > curCapacity) {
425
+ curCapacity *= 2 ;
426
+ timeVec.reserve (curCapacity);
427
+ matrix.resizeKeep (curCapacity, ncol);
428
+ }
416
429
417
430
// Time is column 0.
418
- double time = std::stod (row.front ());
431
+ timeVec. push_back ( std::stod (row.front () ));
419
432
row.erase (row.begin ());
420
433
421
434
auto row_vector = readElems (row);
422
435
423
436
OPENSIM_THROW_IF (row_vector.size () != column_labels.size (),
424
- RowLengthMismatch,
425
- fileName,
426
- line_num,
427
- column_labels.size (),
428
- static_cast <size_t >(row_vector.size ()));
429
-
430
- // Column 1 is time.
431
- table->appendRow (time , std::move (row_vector));
437
+ RowLengthMismatch,
438
+ fileName,
439
+ line_num,
440
+ column_labels.size (),
441
+ static_cast <size_t >(row_vector.size ()));
442
+
443
+ matrix.updRow (curRow) = std::move (row_vector);
432
444
433
445
row = nextLine ();
446
+ ++curRow;
434
447
}
435
448
449
+ // Resize the matrix down to the correct number of rows.
450
+ // This is necessary until Simbody issue #401 is addressed.
451
+ matrix.resizeKeep (curRow, ncol);
452
+
453
+ // Create the table and update other metadata from above
454
+ auto table =
455
+ std::make_shared<TimeSeriesTable_<T>>(timeVec, matrix, column_labels);
456
+ table->updTableMetaData () = keyValuePairs;
457
+
436
458
OutputTables output_tables{};
437
459
output_tables.emplace (tableString (), table);
438
460
0 commit comments