MCPcopy Create free account
hub / github.com/ashvardanian/StringZilla / test_utf8_case_fold_equivalence

Function test_utf8_case_fold_equivalence

scripts/test_stringzilla.cpp:543–670  ·  view source on GitHub ↗

* @brief Tests equivalence of case folding implementations (serial vs SIMD). * * Generates random UTF-8 strings containing: * - ASCII text (uppercase and lowercase) * - Multi-byte UTF-8 characters from various scripts (Cyrillic, Greek, Latin Extended) * - Special cases like German ß * * For each generated string, compares byte-by-byte output of both implementations. */

Source from the content-addressed store, hash-verified

541 * For each generated string, compares byte-by-byte output of both implementations.
542 */
543void test_utf8_case_fold_equivalence( //
544 sz_utf8_case_fold_t fold_base, sz_utf8_case_fold_t fold_simd, //
545 std::size_t min_text_length = 4000, std::size_t min_iterations = 10000) {
546
547 // Output buffers (3x input for worst-case expansion)
548 std::vector<char> output_base(min_text_length * 3 + 256);
549 std::vector<char> output_simd(min_text_length * 3 + 256);
550
551 auto check = [&](std::string const &text) {
552 // Ensure buffers are large enough
553 if (output_base.size() < text.size() * 3 + 64) {
554 output_base.resize(text.size() * 3 + 64);
555 output_simd.resize(text.size() * 3 + 64);
556 }
557
558 sz_size_t len_base = fold_base(text.data(), text.size(), output_base.data());
559 sz_size_t len_simd = fold_simd(text.data(), text.size(), output_simd.data());
560
561 if (len_base != len_simd) {
562 std::fprintf(stderr, "Case fold length mismatch: base=%zu, simd=%zu, input_len=%zu\n", //
563 len_base, len_simd, text.size());
564 // Print first divergence
565 for (std::size_t i = 0; i < std::min(len_base, len_simd); ++i) {
566 if (output_base[i] != output_simd[i]) {
567 std::fprintf(stderr, "First byte diff at output[%zu]: base=0x%02X, simd=0x%02X\n", //
568 i, (unsigned char)output_base[i], (unsigned char)output_simd[i]);
569 break;
570 }
571 }
572 assert(len_base == len_simd && "Case fold length mismatch");
573 }
574
575 for (sz_size_t i = 0; i < len_base; ++i) {
576 if (output_base[i] != output_simd[i]) {
577 std::fprintf(stderr, "Case fold content mismatch at byte %zu: base=0x%02X, simd=0x%02X\n", //
578 i, (unsigned char)output_base[i], (unsigned char)output_simd[i]);
579 // Show context around the mismatch
580 std::size_t start = i > 10 ? i - 10 : 0;
581 std::size_t end = std::min(i + 10, (std::size_t)len_base);
582 std::fprintf(stderr, "Base output[%zu..%zu]: ", start, end);
583 for (std::size_t j = start; j < end; ++j) std::fprintf(stderr, "%02X ", (unsigned char)output_base[j]);
584 std::fprintf(stderr, "\nSIMD output[%zu..%zu]: ", start, end);
585 for (std::size_t j = start; j < end; ++j) std::fprintf(stderr, "%02X ", (unsigned char)output_simd[j]);
586 std::fprintf(stderr, "\n");
587 assert(output_base[i] == output_simd[i] && "Case fold content mismatch");
588 }
589 }
590 };
591
592 // Test content - mix of scripts with case folding rules
593 static char const *utf8_content[] = {
594 // ASCII
595 "",
596 "a",
597 "A",
598 "hello",
599 "HELLO",
600 "Hello World",

Callers 1

test_equivalenceFunction · 0.85

Calls 3

resizeMethod · 0.80
sizeMethod · 0.45
dataMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…