A structure for tracking progress during multithreaded date collection parsing
DATE_COLLECTION_PROGRESS is an optional structure that allows callers to monitor and track the progress of multithreaded date collection parsing operations. This structure provides real-time feedback about the parsing process, including how many items have been processed, how many remain, and any errors encountered.
This structure is particularly useful in scenarios where large date collections are being parsed from files or databases, and the caller wants to provide progress feedback to users or log parsing statistics.
The DATE_COLLECTION_PROGRESS structure is defined in datelog.h as follows:
typedef struct _DATE_COLLECTION_PROGRESS {
DWORD ItemsProcessed; /* Number of date items successfully processed */
DWORD ItemsRemaining; /* Number of date items still to be processed */
DWORD ErrorCount; /* Number of errors encountered during parsing */
DWORD ParsingThreadCount; /* Number of active parsing threads */
HRESULT LastError; /* HRESULT code of the most recent error */
} DATE_COLLECTION_PROGRESS, *PDATE_COLLECTION_PROGRESS;
The number of date items that have been successfully parsed and added to the date collection. This value increments as parsing progresses.
The number of date items that still need to be processed. This value decrements as the parsing operation progresses. When this reaches zero, parsing is complete.
The total number of errors that have occurred during parsing. This includes validation errors, format errors, and other non-fatal errors that were skipped.
The number of threads currently active in the multithreaded parsing operation. This can be useful for understanding the parallelism level.
The HRESULT code of the most recent error encountered during parsing. Set to S_OK if no errors have occurred. Useful for diagnosing parsing failures.
When loading or parsing a date collection, you can pass a DATE_COLLECTION_PROGRESS structure to receive real-time updates:
DATE_COLLECTION_PROGRESS progress = {0};
DATE_LOG_HANDLE hDateLog = NULL;
/* Start parsing with progress tracking */
HRESULT hr = LoadDateLogHandle(
hDateLog,
"dates.csv",
&progress /* Optional progress structure */
);
/* Check progress during parsing */
printf("Processed: %lu items\n", progress.ItemsProcessed);
printf("Remaining: %lu items\n", progress.ItemsRemaining);
printf("Errors: %lu\n", progress.ErrorCount);
printf("Active threads: %lu\n", progress.ParsingThreadCount);
If you don't need progress information, simply pass NULL:
DATE_LOG_HANDLE hDateLog = NULL;
HRESULT hr = LoadDateLogHandle(
hDateLog,
"dates.csv",
NULL /* No progress tracking */
);
#include "datelog.h"
#include
#include
int main(void)
{
HRESULT hr = S_OK;
DATE_LOG_HANDLE hDateLog = NULL;
DATE_COLLECTION_PROGRESS progress = {0};
DWORD lastProcessed = 0;
/* Initialize a date log handle */
hr = InitializeDateLogHandle(
NULL, /* Use default security attributes */
DATE_LOG_MAX, /* Maximum number of date items */
NULL, /* No holidays handle */
&hDateLog, /* Output handle */
HandleIsForDatelog
);
if (FAILED(hr)) {
printf("Failed to initialize date log handle.\n");
return 1;
}
printf("Loading date collection from file...\n");
printf("Progress monitoring initialized.\n\n");
/* Load dates from file with progress tracking */
hr = LoadDateLogHandle(
hDateLog,
"dates.csv",
&progress
);
/* If the operation is running asynchronously or multithreaded,
we could periodically check progress like this: */
while (progress.ItemsRemaining > 0) {
if (progress.ItemsProcessed != lastProcessed) {
printf("Progress: %lu/%lu items (Errors: %lu, Threads: %lu)\n",
progress.ItemsProcessed,
progress.ItemsProcessed + progress.ItemsRemaining,
progress.ErrorCount,
progress.ParsingThreadCount);
lastProcessed = progress.ItemsProcessed;
}
/* Small delay to avoid busy-waiting */
Sleep(100);
}
/* Parsing complete */
if (SUCCEEDED(hr)) {
printf("\nParsing completed successfully!\n");
printf("Total items processed: %lu\n", progress.ItemsProcessed);
printf("Total errors: %lu\n", progress.ErrorCount);
if (progress.ErrorCount > 0) {
printf("Last error HRESULT: 0x%08lx\n", progress.LastError);
}
} else {
printf("\nParsing failed with HRESULT: 0x%08lx\n", hr);
printf("Items processed before failure: %lu\n", progress.ItemsProcessed);
printf("Errors encountered: %lu\n", progress.ErrorCount);
}
/* Clean up */
if (hDateLog != NULL) {
CloseDateLogHandle(hDateLog);
}
return SUCCEEDED(hr) ? 0 : 1;
}
#include "datelog.h"
#include
int main(void)
{
HRESULT hr = S_OK;
DATE_LOG_HANDLE hDateLog = NULL;
DATE_COLLECTION_PROGRESS progress = {0};
/* Setup ... */
hr = InitializeDateLogHandle(NULL, DATE_LOG_MAX, NULL, &hDateLog, HandleIsForDatelog);
if (FAILED(hr)) return 1;
/* Load with progress tracking */
hr = LoadDateLogHandle(hDateLog, "data.csv", &progress);
/* Analyze results */
printf("=== Parsing Results ===\n");
printf("Status: %s\n", SUCCEEDED(hr) ? "SUCCESS" : "FAILED");
printf("Items Processed: %lu\n", progress.ItemsProcessed);
printf("Items Remaining: %lu\n", progress.ItemsRemaining);
printf("Total Errors: %lu\n", progress.ErrorCount);
if (progress.ErrorCount > 0) {
printf("Last Error Code: 0x%08lx\n", progress.LastError);
/* Handle specific error codes */
if (progress.LastError == HRESULT_FROM_WIN32(ERROR_INVALID_DATA)) {
printf("Invalid data format detected in input file.\n");
}
}
/* Cleanup */
CloseDateLogHandle(hDateLog);
return 0;
}