Retrieve the maximum capacity of a date collection
GetDateCollectionMaximumLength returns the maximum capacity (allocation limit) of a date collection handle. This function provides thread-safe access to the collection's maximum length by acquiring the internal mutex and reading the maximum length field.
Get the maximum number of date items that can be stored in a collection. This is useful for:
DWORD _Check_return_ _On_failure_(return > DATE_LOG_MAX) GetDateCollectionMaximumLength(
_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 resource misallocation
_On_failure_(return > DATE_LOG_MAX) : On failure, return value will exceed DATE_LOG_MAX (range 0x000000 to 0x001388)
[In] DATE_COLLECTION_HANDLE
A handle to a date collection previously created via one of the initialization functions.
IsValidDateLogHandle()Returns the maximum capacity of the collection. Range is 1 through DATE_LOG_MAX (5000 items maximum). The returned value is always >= 1 because collections cannot be created with zero capacity.
Indicates an error occurred. Possible error conditions:
| Return Value | Meaning | Action |
|---|---|---|
| 0x00000001 to 0x001388 | Maximum capacity (valid) | Normal operation; collection can hold up to this many items |
| 0x00000000 | Unexpected zero capacity | Data corruption; handle state is invalid |
| 0x00845698 | ERROR_SENTINEL (error) | Do not use returned value; close handle and retry |
| Any value > 0x001388 | Data corruption detected | Collection exceeds maximum allowed; handle state is unreliable |
// Pattern 1: Simple validity check
DWORD dwMaxLength = GetDateCollectionMaximumLength(hCollection);
if (dwMaxLength == DATE_LOG_SENTINEL) {
// Error occurred
printf("Failed to get collection maximum length\n");
// Close handle and retry
} else if (dwMaxLength == 0 || dwMaxLength > DATE_LOG_MAX) {
// Data corruption detected
printf("ERROR: Invalid maximum length: %u\n", dwMaxLength);
} else {
// Valid maximum capacity
printf("Collection capacity: %u items\n", dwMaxLength);
}
// Pattern 2: Calculate utilization
DWORD dwCurrentLen = GetDateCollectionLength(hCollection);
DWORD dwMaxLen = GetDateCollectionMaximumLength(hCollection);
if (dwCurrentLen != DATE_LOG_SENTINEL && dwMaxLen != DATE_LOG_SENTINEL) {
double utilization = (100.0 * dwCurrentLen) / dwMaxLen;
printf("Utilization: %.1f%% (%u of %u items)\n",
utilization, dwCurrentLen, dwMaxLen);
if (utilization > 90.0) {
printf("WARNING: Collection nearly full!\n");
}
}
// Pattern 3: Check available capacity
DWORD dwRemaining = dwMaxLen - dwCurrentLen;
printf("Remaining capacity: %u items\n", dwRemaining);
IsValidDateLogHandle(hDateCollection) to verify:
DATE_LOG_SENTINEL
PDATE_LOG and retrieves the core handle from pContext->hDateLogCore
GetDateLogCoreMaxLength() which:
dwMaxLength field inside the mutexDATE_LOG_SENTINEL if any step fails
The maximum length of a collection is established at initialization and never changes:
InitializeDateLogHandle(dwMaximumLength, ...)DATE_LOG_CORE.dwMaxLengthThe function is fully thread-safe:
| Aspect | GetDateCollectionLength | GetDateCollectionMaximumLength |
|---|---|---|
| Reads Field | dwLength |
dwMaxLength |
| Changes Over Time | Yes (0 to max as items added) | No (fixed at initialization) |
| Typical Use | Get current item count | Get capacity limit |
| Can Be Zero | Yes (empty collection) | No (always >= 1) |
#include "datelog.h"
DWORD dwCurrentLength = GetDateCollectionLength(hMyCollection);
DWORD dwMaxLength = GetDateCollectionMaximumLength(hMyCollection);
if (dwCurrentLength == DATE_LOG_SENTINEL || dwMaxLength == DATE_LOG_SENTINEL) {
printf("ERROR: Failed to get collection information\n");
goto error_cleanup;
}
DWORD dwRemaining = dwMaxLength - dwCurrentLength;
if (dwRemaining < 100) {
printf("WARNING: Only %u items of capacity remaining\n", dwRemaining);
printf("Collection is %.1f%% full\n",
(100.0 * dwCurrentLength) / dwMaxLength);
} else {
printf("Plenty of space available (%u items)\n", dwRemaining);
}
// ... continue with operation ...
error_cleanup:
CloseDateLogHandle(hMyCollection);
return FALSE;
// Allocate buffer sized to collection's maximum capacity
DWORD dwMaxLength = GetDateCollectionMaximumLength(hCollection);
if (dwMaxLength == DATE_LOG_SENTINEL || dwMaxLength == 0) {
printf("Cannot allocate buffer for invalid collection\n");
return NULL;
}
if (dwMaxLength > DATE_LOG_MAX) {
printf("ERROR: Collection capacity exceeds maximum allowed\n");
return NULL;
}
// Each date item is sizeof(DATE_STRUCT) bytes
SIZE_T cbBuffer = (SIZE_T)dwMaxLength * sizeof(DATE_STRUCT);
// Check for integer overflow
if (cbBuffer / sizeof(DATE_STRUCT) != dwMaxLength) {
printf("ERROR: Buffer size calculation overflow\n");
return NULL;
}
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 maximum %u dates\n", cbBuffer, dwMaxLength);
return pDates;
void PrintCollectionStatistics(DATE_COLLECTION_HANDLE hCollection) {
DWORD dwLength = GetDateCollectionLength(hCollection);
DWORD dwMaxLength = GetDateCollectionMaximumLength(hCollection);
if (dwLength == DATE_LOG_SENTINEL || dwMaxLength == DATE_LOG_SENTINEL) {
printf("Collection is invalid or inaccessible\n");
return;
}
// Validate data integrity
if (dwLength > dwMaxLength) {
printf("ERROR: Current length (%u) exceeds maximum (%u)\n",
dwLength, dwMaxLength);
return;
}
// Calculate statistics
DWORD dwRemaining = dwMaxLength - dwLength;
double percentUsed = (100.0 * dwLength) / dwMaxLength;
double percentFree = 100.0 - percentUsed;
printf("=== Collection Statistics ===\n");
printf("Current items: %u\n", dwLength);
printf("Maximum capacity: %u\n", dwMaxLength);
printf("Remaining space: %u items\n", dwRemaining);
printf("Utilization: %.1f%% used, %.1f%% free\n",
percentUsed, percentFree);
// Alert on capacity thresholds
if (percentUsed >= 90.0) {
printf("⚠ CRITICAL: Collection is nearly full!\n");
} else if (percentUsed >= 75.0) {
printf("⚠ WARNING: Collection is getting full\n");
} else if (percentUsed >= 50.0) {
printf("ℹ INFO: Collection is half-full\n");
}
}
// Before merging, check if result will fit
DWORD dwDestCurrent = GetDateCollectionLength(hDestLog);
DWORD dwDestMax = GetDateCollectionMaximumLength(hDestLog);
DWORD dwSourceLength = GetDateCollectionLength(hSourceLog);
if (dwDestCurrent == DATE_LOG_SENTINEL ||
dwDestMax == DATE_LOG_SENTINEL ||
dwSourceLength == DATE_LOG_SENTINEL) {
printf("ERROR: Cannot get collection sizes\n");
return FALSE;
}
// Estimate space needed (conservative: assume all source items are new)
DWORD dwEstimatedTotal = dwDestCurrent + dwSourceLength;
if (dwEstimatedTotal > dwDestMax) {
printf("ERROR: Merge would exceed capacity\n");
printf("Destination: %u current + %u source = %u total\n",
dwDestCurrent, dwSourceLength, dwEstimatedTotal);
printf("Maximum capacity: %u\n", dwDestMax);
printf("Shortfall: %u items\n", dwEstimatedTotal - dwDestMax);
return FALSE;
} else {
DWORD dwRemaining = dwDestMax - dwEstimatedTotal;
printf("Merge will fit with %u items to spare\n", dwRemaining);
// Proceed with merge
return SUCCEEDED(MergeDateLogHandle(hDestLog, hSourceLog,
DATE_RANGE_MERGE_FAVOR_SOURCE));
}
| Aspect | Detail |
|---|---|
| Mutex Timeout | 5 seconds (5000 milliseconds) |
| Lock Scope | Only the dwMaxLength field read |
| Lock Duration | Minimal (~1-2 microseconds) |
| Deadlock Risk | None—single lock acquisition |
| Value Consistency | Always consistent; field is immutable |
DWORD dwMaxCapacity = GetDateCollectionMaximumLength(hCollection);GetDateCollectionLength() – Get current number of itemsInitializeDateLogHandle() – Create collection with specified max capacityCloseDateLogHandle() – Close and free a collectionIsValidDateLogHandle() – Validate a handleGetDateLogFirstDate() – Get first date itemGetDateLogLastDate() – Get last date item_On_failure_(return > DATE_LOG_MAX) instead of _Success_pContext NULL; delegated to caller validation