Retrieve the current number of date items in a date collection
GetDateCollectionLength returns the current count of date items stored in a date collection handle. This function provides thread-safe access to the collection's length by acquiring the internal mutex and reading the length field.
Get the actual number of date items currently in a collection. This is useful for:
DWORD _Check_return_ _On_failure_(return > DATE_LOG_MAX) GetDateCollectionLength(
_In_ DATE_COLLECTION_HANDLE hDateCollection
);
Standard C calling convention with SAL annotations for parameter and return value validation.
_Check_return_ : Caller must check the return value; ignoring it may lead to processing invalid data
_On_failure_(return > DATE_LOG_MAX) : On failure, return value will exceed DATE_LOG_MAX (0x00000000 to 0x001388 range)
[In] DATE_COLLECTION_HANDLE
A handle to a date collection previously created via one of the initialization functions.
IsValidDateLogHandle()Returns the actual number of date items in the collection. Range is 0 (empty collection) through DATE_LOG_MAX (5000 items maximum). A value of 0 indicates an empty collection, which is valid.
Indicates an error occurred. Possible error conditions:
| Return Value | Meaning | Action |
|---|---|---|
| 0x00000000 | Empty collection (valid) | No items; handle is valid but unpopulated |
| 1 to 0x001388 | Collection size (valid) | Normal operation; collection contains this many items |
| 0x00845698 | ERROR_SENTINEL (error) | Do not use returned value; close handle and retry |
| Any other value | Data corruption detected | Indicates memory corruption; handle state is unreliable |
// Pattern 1: Simple validity check
DWORD dwLength = GetDateCollectionLength(hCollection);
if (dwLength == DATE_LOG_SENTINEL) {
// Error occurred
printf("Failed to get collection length\n");
// Close handle and retry
} else if (dwLength == 0) {
// Empty collection (valid)
printf("Collection is empty\n");
} else {
// Valid collection with dwLength items
printf("Collection has %u items\n", dwLength);
}
// Pattern 2: Loop processing
DWORD dwMaxLen = GetDateCollectionMaximumLength(hCollection);
DWORD dwLen = GetDateCollectionLength(hCollection);
if (dwLen != DATE_LOG_SENTINEL && dwMaxLen != DATE_LOG_SENTINEL) {
printf("Utilization: %u of %u (%.1f%%)\n",
dwLen, dwMaxLen, (100.0 * dwLen) / dwMaxLen);
}
IsValidDateLogHandle(hDateCollection) to verify:
DATE_LOG_SENTINEL
PDATE_LOG and retrieves the core handle from pContext->hDateLogCore
GetDateLogCoreLength() which:
dwLength field inside the mutexDATE_LOG_SENTINEL if any step fails
The function is fully thread-safe:
// Error conditions handled gracefully
if (IsValidDateLogHandle(hDateCollection) == FALSE)
return DATE_LOG_SENTINEL; // Handle is invalid
PDATE_LOG pDateLog = (PDATE_LOG)hDateCollection;
return GetDateLogCoreLength(pDateLog->pContext->hDateLogCore);
// GetDateLogCoreLength also checks:
// - IsValidDateLogCore(hDateLogCore)
// - Mutex timeout
// - Mutex wait result
#include "datelog.h"
DWORD dwLength = GetDateCollectionLength(hMyCollection);
if (dwLength == DATE_LOG_SENTINEL) {
printf("ERROR: Failed to get collection length\n");
goto error_cleanup;
}
if (dwLength == 0) {
printf("Collection is empty\n");
} else {
printf("Collection contains %u market dates\n", dwLength);
}
// ... continue processing ...
error_cleanup:
CloseDateLogHandle(hMyCollection);
return FALSE;
// After merging two collections
HRESULT hr = MergeDateLogHandle(hDestLog, hSourceLog,
DATE_RANGE_MERGE_FAVOR_SOURCE);
if (SUCCEEDED(hr)) {
DWORD dwNewLength = GetDateCollectionLength(hDestLog);
DWORD dwMaxLength = GetDateCollectionMaximumLength(hDestLog);
if (dwNewLength != DATE_LOG_SENTINEL &&
dwMaxLength != DATE_LOG_SENTINEL) {
printf("Merge successful. Collection now has %u dates\n", dwNewLength);
printf("Capacity utilization: %.1f%%\n",
(100.0 * dwNewLength) / dwMaxLength);
// Verify merge didn't exceed capacity
if (dwNewLength > dwMaxLength) {
printf("ERROR: Length exceeds maximum!\n");
}
} else {
printf("ERROR: Failed to verify merged collection state\n");
}
}
// Process each item in the collection
DWORD dwCount = GetDateCollectionLength(hCollection);
if (dwCount == DATE_LOG_SENTINEL) {
printf("Invalid collection\n");
return;
}
if (dwCount == 0) {
printf("Collection is empty, nothing to process\n");
return;
}
for (DWORD i = 0; i < dwCount; i++) {
DATE_ITEM_HANDLE hItem = GetDateLogFirstDate(hCollection);
if (hItem == NULL) {
printf("Failed to get date item %u\n", i);
break;
}
DATE_STRUCT date = {0};
GetDateItemDate(hItem, &date);
printf("Date %u: %04d-%02d-%02d\n", i,
date.year, date.month, date.day);
}
// Allocate buffer sized to collection
DWORD dwLength = GetDateCollectionLength(hCollection);
if (dwLength == DATE_LOG_SENTINEL || dwLength == 0) {
printf("Cannot allocate buffer for empty/invalid collection\n");
return NULL;
}
// Each date item is sizeof(DATE_STRUCT) bytes
SIZE_T cbBuffer = dwLength * sizeof(DATE_STRUCT);
PDATE_STRUCT pDates = (PDATE_STRUCT)malloc(cbBuffer);
if (pDates == NULL) {
printf("Failed to allocate %zu bytes\n", cbBuffer);
return NULL;
}
printf("Allocated %zu bytes for %u dates\n", cbBuffer, dwLength);
return pDates;
| Aspect | Detail |
|---|---|
| Mutex Timeout | 5 seconds (5000 milliseconds) |
| Lock Scope | Only the dwLength field read |
| Lock Duration | Minimal (~1-2 microseconds) |
| Deadlock Risk | None—single lock acquisition |
DATE_LOG_SENTINEL to detect errors.
GetDateCollectionMaximumLength() – Get the maximum capacityGetDateLogFirstDate() – Get the first date itemGetDateLogLastDate() – Get the last date itemInitializeDateLogHandle() – Create a new collectionCloseDateLogHandle() – Close and free a collectionIsValidDateLogHandle() – Validate a handle_On_failure_(return > DATE_LOG_MAX) instead of _Success_pContext NULL; delegated to caller validation