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

Function sz_utf8_count_ice

include/stringzilla/utf8.h:709–759  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

707}
708
709SZ_PUBLIC sz_size_t sz_utf8_count_ice(sz_cptr_t text, sz_size_t length) {
710 // UTF-8 character counting strategy:
711 // Count every byte that is NOT a continuation byte (i.e., character start bytes).
712 //
713 // UTF-8 byte patterns:
714 // ASCII: 0xxxxxxx (0x00-0x7F) - single byte character
715 // Start 2-byte: 110xxxxx (0xC0-0xDF) - first byte of 2-byte sequence
716 // Start 3-byte: 1110xxxx (0xE0-0xEF) - first byte of 3-byte sequence
717 // Start 4-byte: 11110xxx (0xF0-0xF7) - first byte of 4-byte sequence
718 // Continuation: 10xxxxxx (0x80-0xBF) - continuation byte (NOT a character start)
719 //
720 // To detect continuation bytes: (byte & 0xC0) == 0x80
721 // 0xC0 = 11000000 - masks the top 2 bits
722 // 0x80 = 10000000 - pattern for continuation bytes after masking
723
724 sz_u512_vec_t continuation_mask_vec, continuation_pattern_vec;
725 continuation_mask_vec.zmm = _mm512_set1_epi8((char)0xC0); // 0xC0 = 0b11000000 - mask top 2 bits
726 continuation_pattern_vec.zmm = _mm512_set1_epi8((char)0x80); // 0x80 = 0b10000000 - continuation pattern
727
728 sz_u8_t const *text_u8 = (sz_u8_t const *)text;
729 sz_size_t char_count = 0;
730
731 // Process 64 bytes at a time
732 sz_u512_vec_t text_vec, headers_vec;
733 while (length >= 64) {
734 text_vec.zmm = _mm512_loadu_epi8(text_u8);
735
736 // Apply mask (byte & 0xC0) to extract top 2 bits of each byte
737 headers_vec.zmm = _mm512_and_si512(text_vec.zmm, continuation_mask_vec.zmm);
738
739 // Compare with 0x80 (0b10000000) to find continuation bytes
740 sz_u64_t start_byte_mask =
741 _cvtmask64_u64(_mm512_cmpneq_epi8_mask(headers_vec.zmm, continuation_pattern_vec.zmm));
742
743 // Count non-continuation bytes (i.e., character starts)
744 char_count += _mm_popcnt_u64(start_byte_mask);
745 text_u8 += 64;
746 length -= 64;
747 }
748
749 // Process remaining bytes with a masked variant
750 if (length) {
751 __mmask64 load_mask = sz_u64_mask_until_(length);
752 text_vec.zmm = _mm512_maskz_loadu_epi8(load_mask, text_u8);
753 headers_vec.zmm = _mm512_and_si512(text_vec.zmm, continuation_mask_vec.zmm);
754 __mmask64 start_byte_mask =
755 _mm512_mask_cmpneq_epi8_mask(load_mask, headers_vec.zmm, continuation_pattern_vec.zmm);
756 char_count += _mm_popcnt_u64(_cvtmask64_u64(start_byte_mask));
757 }
758 return char_count;
759}
760
761SZ_PUBLIC sz_cptr_t sz_utf8_find_nth_ice(sz_cptr_t text, sz_size_t length, sz_size_t n) {
762

Callers 1

sz_utf8_countFunction · 0.85

Calls 1

sz_u64_mask_until_Function · 0.85

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…