| 667 | } |
| 668 | |
| 669 | static void batch_resolve_worker(int worker_id, void *ctx_ptr) { |
| 670 | (void)worker_id; |
| 671 | batch_resolve_ctx_t *bc = ctx_ptr; |
| 672 | /* Per-worker scratch for unique-per-doc tracking */ |
| 673 | int local_seen_cap = CBM_SEM_SEEN_INIT_CAP; |
| 674 | int *seen = malloc((size_t)local_seen_cap * sizeof(int)); |
| 675 | if (!seen) { |
| 676 | return; |
| 677 | } |
| 678 | |
| 679 | while (true) { |
| 680 | int start = |
| 681 | atomic_fetch_add_explicit(&bc->next_idx, CBM_SEM_RESOLVE_CHUNK, memory_order_relaxed); |
| 682 | if (start >= bc->doc_count) { |
| 683 | break; |
| 684 | } |
| 685 | int end = start + CBM_SEM_RESOLVE_CHUNK; |
| 686 | if (end > bc->doc_count) { |
| 687 | end = bc->doc_count; |
| 688 | } |
| 689 | for (int d = start; d < end; d++) { |
| 690 | int count = bc->token_counts[d]; |
| 691 | if (count > local_seen_cap) { |
| 692 | int *grown = realloc(seen, (size_t)count * sizeof(int)); |
| 693 | if (!grown) { |
| 694 | continue; |
| 695 | } |
| 696 | seen = grown; |
| 697 | local_seen_cap = count; |
| 698 | } |
| 699 | batch_resolve_one_doc(bc, d, seen); |
| 700 | } |
| 701 | } |
| 702 | free(seen); |
| 703 | } |
| 704 | |
| 705 | void cbm_sem_corpus_add_docs_batch(cbm_sem_corpus_t *corpus, char **all_tokens, |
| 706 | const int *token_counts, int doc_count, int max_tokens_per_doc) { |
nothing calls this directly
no test coverage detected