@@ -855,93 +855,96 @@ const pair <size_t, size_t> anyks::Dict::find(const word_t & word, dumper_t & dm
855855 hypothesis.etalon = word.wreal ();
856856 // Выполняем получение максимального количества ошибок для слова
857857 const u_short errors = this ->alphabet ->errors (word);
858- /* *
859- * findFn Функция извлечения слова из базы
860- * @param idw идентификатор слова
861- */
862- auto findFn = [&](const size_t idw){
863- // Получаем данные слова
864- auto it = this ->words .find (idw);
865- // Если такое слово существует
866- if (it != this ->words .end ()){
867- // Выполняем блокировки потока
868- this ->locker .lock ();
869- // Устанавливаем идентификатор гипотезы
870- hypothesis.idw = idw;
871- // Получаем дистанцию
872- hypothesis.lev = (errors > 1 ? algorithms.distance (word, it->second ) : algorithms.damerau (word, it->second ));
873- // Отфильтровываем ненужные нам слова
874- if (!it->second .empty () && (hypothesis.lev <= errors)){
875- // Извлекаем слово из списка
876- hypothesis.word = it->second ;
877- // Устанавливаем значение Танимото
878- hypothesis.tmo = algorithms.tanimoto (word, hypothesis.word );
879- // Если расстояние Левенштейна слишком большое, тогда Танимото должен быть больше 4.0
880- if ((hypothesis.lev <= 3 ) || (hypothesis.tmo >= 0.4 )){
881- // Если вывод отладочной информации разрешён
882- if (this ->isOption (options_t ::debug)){
883- // Выводим основное сообщение отладки
884- this ->alphabet ->log (" find word: [%s => %s]\r\n " , alphabet_t ::log_t ::info, this ->logfile , word.real ().c_str (), hypothesis.word .real ().c_str ());
885- }
886- // Добавляем вариант в дампер
887- const auto & res = dmp.smart (hypothesis, size);
888- // Если вариант добавлен, запоминаем позицию
889- if (res.second > 0 ){
890- // Увеличиваем количество добавленных вариантов
891- result.second ++;
892- // Запоминаем новую позицию
893- result.first = res.first ;
858+ // Если количество ошибок больше 0
859+ if (errors > 0 ){
860+ /* *
861+ * findFn Функция извлечения слова из базы
862+ * @param idw идентификатор слова
863+ */
864+ auto findFn = [&](const size_t idw){
865+ // Получаем данные слова
866+ auto it = this ->words .find (idw);
867+ // Если такое слово существует
868+ if (it != this ->words .end ()){
869+ // Выполняем блокировки потока
870+ this ->locker .lock ();
871+ // Устанавливаем идентификатор гипотезы
872+ hypothesis.idw = idw;
873+ // Получаем дистанцию
874+ hypothesis.lev = (errors > 1 ? algorithms.distance (word, it->second ) : algorithms.damerau (word, it->second ));
875+ // Отфильтровываем ненужные нам слова
876+ if (!it->second .empty () && (hypothesis.lev <= errors)){
877+ // Извлекаем слово из списка
878+ hypothesis.word = it->second ;
879+ // Устанавливаем значение Танимото
880+ hypothesis.tmo = algorithms.tanimoto (word, hypothesis.word );
881+ // Если расстояние Левенштейна слишком большое, тогда Танимото должен быть больше 4.0
882+ if ((hypothesis.lev <= 3 ) || (hypothesis.tmo >= 0.4 )){
883+ // Если вывод отладочной информации разрешён
884+ if (this ->isOption (options_t ::debug)){
885+ // Выводим основное сообщение отладки
886+ this ->alphabet ->log (" find word: [%s => %s]\r\n " , alphabet_t ::log_t ::info, this ->logfile , word.real ().c_str (), hypothesis.word .real ().c_str ());
887+ }
888+ // Добавляем вариант в дампер
889+ const auto & res = dmp.smart (hypothesis, size);
890+ // Если вариант добавлен, запоминаем позицию
891+ if (res.second > 0 ){
892+ // Увеличиваем количество добавленных вариантов
893+ result.second ++;
894+ // Запоминаем новую позицию
895+ result.first = res.first ;
896+ }
894897 }
895898 }
899+ // Выполняем разблокировки потока
900+ this ->locker .unlock ();
896901 }
897- // Выполняем разблокировки потока
898- this ->locker .unlock ();
899- }
900- };
901- // Если нужно выполнять исправление опечаток
902- if (this ->isOption (options_t ::onlytypos)){
903- // Получаем список всех возможных векторов слова
904- auto vectors = this ->vecsb (word);
905- // Если список получен
906- if (!vectors.empty ()){
907- // Выполняем инициализацию пула потоков
908- this ->start ();
909- // Переходим по всему списку векторов
910- for (auto & vector : vectors){
911- // Получаем диапазон значений вектора
912- auto ret = this ->vectors .equal_range (vector);
913- // Перебираем весь диапазон полученных векторов
914- for (auto it = ret.first ; it != ret.second ; ++it){
915- // Выполняем добавление полученного слова
916- this ->tpool ->push (findFn, it->second );
917- }
918- }
919- // Ожидаем завершения работы всех потоков
920- this ->finish ();
921- }
922- // Если hnsw загружен
923- } else if (!this ->hnsw .empty ()) {
924- // Создаёс эмбеддинг слова
925- const auto & embedding = this ->vec (word);
926- // Если эмбеддинг получен
927- if (!embedding.empty ()){
928- // Множитель для расчёта максимального количества вариантов
929- vector <double > factor = {0.25 , 0.5 , 0.75 , 1 };
930- // Получаем количество элементов для выдачи
931- const size_t count = pow (10 , floor (log10 (words.size ())));
932- // Получаем количество максимаольно-возможных вариантов для рассмотрения
933- const size_t nswlibCount = (factor.at (errors - 1 ) * this ->nswlibCount );
934- // Запрашиваем nswlibCount вариантов
935- const auto & res = this ->hnsw .query ({embedding}, (count < nswlibCount ? count : nswlibCount));
936- // Если список вариантов получен
937- if (!res.first .empty ()){
902+ };
903+ // Если нужно выполнять исправление опечаток
904+ if (this ->isOption (options_t ::onlytypos)){
905+ // Получаем список всех возможных векторов слова
906+ auto vectors = this ->vecsb (word);
907+ // Если список получен
908+ if (!vectors.empty ()){
938909 // Выполняем инициализацию пула потоков
939910 this ->start ();
940- // Переходим по всему списку вариантов
941- for (auto & idw : res.first ) this ->tpool ->push (findFn, idw);
911+ // Переходим по всему списку векторов
912+ for (auto & vector : vectors){
913+ // Получаем диапазон значений вектора
914+ auto ret = this ->vectors .equal_range (vector);
915+ // Перебираем весь диапазон полученных векторов
916+ for (auto it = ret.first ; it != ret.second ; ++it){
917+ // Выполняем добавление полученного слова
918+ this ->tpool ->push (findFn, it->second );
919+ }
920+ }
942921 // Ожидаем завершения работы всех потоков
943922 this ->finish ();
944923 }
924+ // Если hnsw загружен
925+ } else if (!this ->hnsw .empty ()) {
926+ // Создаёс эмбеддинг слова
927+ const auto & embedding = this ->vec (word);
928+ // Если эмбеддинг получен
929+ if (!embedding.empty ()){
930+ // Множитель для расчёта максимального количества вариантов
931+ vector <double > factor = {0.25 , 0.5 , 0.75 , 1 };
932+ // Получаем количество элементов для выдачи
933+ const size_t count = pow (10 , floor (log10 (words.size ())));
934+ // Получаем количество максимаольно-возможных вариантов для рассмотрения
935+ const size_t nswlibCount = (factor.at (errors - 1 ) * this ->nswlibCount );
936+ // Запрашиваем nswlibCount вариантов
937+ const auto & res = this ->hnsw .query ({embedding}, (count < nswlibCount ? count : nswlibCount));
938+ // Если список вариантов получен
939+ if (!res.first .empty ()){
940+ // Выполняем инициализацию пула потоков
941+ this ->start ();
942+ // Переходим по всему списку вариантов
943+ for (auto & idw : res.first ) this ->tpool ->push (findFn, idw);
944+ // Ожидаем завершения работы всех потоков
945+ this ->finish ();
946+ }
947+ }
945948 }
946949 }
947950 }
0 commit comments