diff --git a/libc/mem/alg.h b/libc/mem/alg.h index ae519f76f..f2824c8ba 100644 --- a/libc/mem/alg.h +++ b/libc/mem/alg.h @@ -7,7 +7,6 @@ void *bsearch(const void *, const void *, size_t, size_t, void *bsearch_r(const void *, const void *, size_t, size_t, int (*)(const void *, const void *, void *), void *) paramsnonnull((1, 2, 5)) nosideeffect; -void djbsort(int32_t *, size_t) libcesque; void qsort3(void *, size_t, size_t, int (*)(const void *, const void *)) libcesque paramsnonnull(); void qsort(void *, size_t, size_t, @@ -25,8 +24,12 @@ int mergesort(void *, size_t, size_t, int (*)(const void *, const void *)); int mergesort_r(void *, size_t, size_t, int (*)(const void *, const void *, void *), void *); +#ifdef _COSMO_SOURCE +void djbsort(int32_t *, size_t) libcesque; int radix_sort_int32(int32_t *, size_t) libcesque; int radix_sort_int64(int64_t *, size_t) libcesque; +double levenshtein(const char *, const char *) libcesque; +#endif COSMOPOLITAN_C_END_ #endif /* COSMOPOLITAN_LIBC_ALG_ALG_H_ */ diff --git a/libc/mem/levenshtein.c b/libc/mem/levenshtein.c new file mode 100644 index 000000000..198ddf200 --- /dev/null +++ b/libc/mem/levenshtein.c @@ -0,0 +1,48 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi │ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2024 Justine Alexandra Roberts Tunney │ +│ │ +│ Permission to use, copy, modify, and/or distribute this software for │ +│ any purpose with or without fee is hereby granted, provided that the │ +│ above copyright notice and this permission notice appear in all copies. │ +│ │ +│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ +│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ +│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ +│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ +│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ +│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ +│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ +│ PERFORMANCE OF THIS SOFTWARE. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/mem/alg.h" +#include "libc/mem/mem.h" + +#define MIN3(a, b, c) \ + ((a) < (b) ? ((a) < (c) ? (a) : (c)) : ((b) < (c) ? (b) : (c))) + +/** + * Computes similarity between two strings. + */ +double levenshtein(const char *s0, const char *s1) { + int n0 = strlen(s0) + 1; + int n1 = strlen(s1) + 1; + int *col = (int *)malloc(n1 * sizeof(int)); + int *pol = (int *)malloc(n1 * sizeof(int)); + for (int i = 0; i < n1; i++) + pol[i] = i; + for (int i = 0; i < n0; i++) { + col[0] = i; + for (int j = 1; j < n1; j++) + col[j] = MIN3(1 + col[j - 1], 1 + pol[j], + pol[j - 1] + !(i > 0 && s0[i - 1] == s1[j - 1])); + int *t = col; + col = pol; + pol = t; + } + int dist = pol[n1 - 1]; + free(pol); + free(col); + return 1 - dist / ((n0 > n1 ? n0 : n1) - 1.); +} diff --git a/third_party/dlmalloc/locks.inc b/third_party/dlmalloc/locks.inc index bb2a149f8..4e6c0198a 100644 --- a/third_party/dlmalloc/locks.inc +++ b/third_party/dlmalloc/locks.inc @@ -34,7 +34,7 @@ #define MLOCK_T atomic_uint static int malloc_wipe(MLOCK_T *lk) { - bzero(lk, sizeof(*lk)); + atomic_store_explicit(lk, 0, memory_order_relaxed); return 0; }