Skip to content

Commit 013bdbe

Browse files
committed
Checkpoint commit of day 5. Anagram functionality mostly complete.
Remaining: GetWordStats() which will be easy, RemoveWord() which will be fiddly.
1 parent 3886f4e commit 013bdbe

12 files changed

Lines changed: 1139 additions & 147 deletions

File tree

Dictionary/AddWord.c

Lines changed: 89 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Module Name:
1717

1818
_Use_decl_annotations_
1919
BOOLEAN
20-
AddWord(
20+
AddWordEntry(
2121
PDICTIONARY Dictionary,
2222
PCBYTE Word,
2323
PCWORD_ENTRY *WordEntryPointer,
@@ -65,6 +65,7 @@ Return Value:
6565
PBYTE Buffer;
6666
ULONG Length;
6767
ULONG EntrySize;
68+
ULONGLONG StringBytesUsed = 0;
6869
PULONG BitmapHash;
6970
PULONG HistogramHash;
7071
BOOLEAN NewWordEntry;
@@ -73,6 +74,7 @@ Return Value:
7374
BOOLEAN NewHistogramEntry;
7475
BOOLEAN IsNewCurrentLongestWord;
7576
BOOLEAN IsNewLongestWordAllTime;
77+
PRTL_AVL_TABLE Avl;
7678
PALLOCATOR Allocator;
7779
PALLOCATOR WordAllocator;
7880
PLONG_STRING String;
@@ -88,6 +90,7 @@ Return Value:
8890
PCLONG_STRING CurrentLongestWord;
8991
PCLONG_STRING LongestWordAllTime;
9092
PTABLE_ENTRY_HEADER TableEntryHeader;
93+
ULARGE_INTEGER TotalStringBufferAllocSize;
9194
PRTL_INITIALIZE_GENERIC_TABLE_AVL RtlInitializeGenericTableAvl;
9295
PRTL_INSERT_ELEMENT_GENERIC_TABLE_AVL RtlInsertElementGenericTableAvl;
9396

@@ -117,10 +120,6 @@ Return Value:
117120
return FALSE;
118121
}
119122

120-
if (!ARGUMENT_PRESENT(EntryCountPointer)) {
121-
return FALSE;
122-
}
123-
124123
//
125124
// Clear the caller's word entry and entry count pointers up-front.
126125
//
@@ -192,13 +191,6 @@ Return Value:
192191
Context.Dictionary = Dictionary;
193192
DictionaryTlsSetContext(&Context);
194193

195-
//
196-
// Acquire the exclusive dictionary lock for the remaining duration of the
197-
// routine.
198-
//
199-
200-
AcquireDictionaryLockExclusive(&Dictionary->Lock);
201-
202194
//
203195
// Prepare a bitmap table entry for potential insertion into the bitmap
204196
// AVL table.
@@ -273,7 +265,7 @@ Return Value:
273265
}
274266

275267
//
276-
// Update the TLS context and initialize the word entry table alias.
268+
// Update the TLS context and initialize the word table alias.
277269
//
278270

279271
Context.HistogramTableEntry = HistogramTableEntry;
@@ -347,6 +339,19 @@ Return Value:
347339
goto Error;
348340
}
349341

342+
//
343+
// Update the number of bytes allocated to string buffers in the
344+
// current word table. Because the high and low parts of the count
345+
// are split, we need to do some LARGE_INTEGER juggling.
346+
//
347+
348+
Avl = &WordTable->Avl;
349+
TotalStringBufferAllocSize.LowPart = Avl->BytesAllocatedLowPart;
350+
TotalStringBufferAllocSize.HighPart = Avl->BytesAllocatedHighPart;
351+
TotalStringBufferAllocSize.QuadPart += (Length + 1);
352+
Avl->BytesAllocatedLowPart = TotalStringBufferAllocSize.LowPart;
353+
Avl->BytesAllocatedHighPart = TotalStringBufferAllocSize.HighPart;
354+
350355
//
351356
// Copy the buffer, add the trailing NULL, switch the underlying word
352357
// entry's buffer pointer.
@@ -491,7 +496,10 @@ Return Value:
491496
//
492497

493498
*WordEntryPointer = WordEntry;
494-
*EntryCountPointer = WordStats->EntryCount;
499+
500+
if (ARGUMENT_PRESENT(EntryCountPointer)) {
501+
*EntryCountPointer = WordStats->EntryCount;
502+
}
495503

496504
//
497505
// Indicate success and jump to the end, we're done.
@@ -511,9 +519,74 @@ Return Value:
511519

512520
End:
513521

514-
ReleaseDictionaryLockExclusive(&Dictionary->Lock);
522+
return Success;
523+
}
524+
525+
_Use_decl_annotations_
526+
BOOLEAN
527+
AddWord(
528+
PDICTIONARY Dictionary,
529+
PCBYTE Word,
530+
PLONGLONG EntryCountPointer
531+
)
532+
/*++
533+
534+
Routine Description:
535+
536+
Adds a word to a dictionary if it doesn't exist, increments the word's
537+
existing count if it does. Returns the entry count for the word.
538+
539+
N.B. The word may also be registered as the current and all-time longest
540+
word associated with the dictionary.
541+
542+
Arguments:
543+
544+
Dictionary - Supplies a pointer to a DICTIONARY structure to which the
545+
word is to be added.
515546
516-
DictionaryTlsSetContext(NULL);
547+
Word - Supplies a NULL-terminated array of bytes to add to the dictionary.
548+
The length of the array must be between the minimum and maximum lengths
549+
configured for the dictionary, otherwise the word will be rejected and
550+
this routine will return FALSE.
551+
552+
EntryCountPointer - Supplies an address to a variable that receives the
553+
current entry count associated with the word at the time that it was
554+
added to the directory. Set to zero on error.
555+
556+
Return Value:
557+
558+
TRUE on success, FALSE on failure.
559+
560+
--*/
561+
{
562+
BOOLEAN Success;
563+
PWORD_ENTRY WordEntry;
564+
565+
//
566+
// Validate arguments.
567+
//
568+
569+
if (!ARGUMENT_PRESENT(Dictionary)) {
570+
return FALSE;
571+
}
572+
573+
if (!ARGUMENT_PRESENT(Word)) {
574+
return FALSE;
575+
}
576+
577+
//
578+
// Obtain an exclusive lock on the dictionary.
579+
//
580+
581+
AcquireDictionaryLockExclusive(&Dictionary->Lock);
582+
583+
Success = AddWordEntry(Dictionary, Word, &WordEntry, EntryCountPointer);
584+
585+
//
586+
// Release the lock and return.
587+
//
588+
589+
ReleaseDictionaryLockExclusive(&Dictionary->Lock);
517590

518591
return Success;
519592
}

0 commit comments

Comments
 (0)