Skip to content

Commit

Permalink
added levenstein distance search
Browse files Browse the repository at this point in the history
  • Loading branch information
DeaSTL committed Oct 30, 2023
1 parent 23335e8 commit 689d969
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 176 deletions.
83 changes: 1 addition & 82 deletions install_manifest.txt
Original file line number Diff line number Diff line change
@@ -1,82 +1 @@
/usr/local/bin/cmaker
/usr/local/lib/libz.so.1.2.13.zlib-ng
/usr/local/lib/libz.so.1
/usr/local/lib/libz.so
/usr/local/include/zlib.h
/usr/local/include/zlib_name_mangling.h
/usr/local/include/zconf.h
/usr/local/lib/pkgconfig/zlib.pc
/usr/local/lib/libcurl.so.4.8.0
/usr/local/lib/libcurl.so.4
/usr/local/lib/libcurl.so
/usr/local/bin/curl-config
/usr/local/lib/pkgconfig/libcurl.pc
/usr/local/include/curl/multi.h
/usr/local/include/curl/options.h
/usr/local/include/curl/urlapi.h
/usr/local/include/curl/header.h
/usr/local/include/curl/websockets.h
/usr/local/include/curl/curlver.h
/usr/local/include/curl/system.h
/usr/local/include/curl/typecheck-gcc.h
/usr/local/include/curl/easy.h
/usr/local/include/curl/stdcheaders.h
/usr/local/include/curl/curl.h
/usr/local/include/curl/mprintf.h
/usr/local/lib/cmake/CURL/CURLTargets.cmake
/usr/local/lib/cmake/CURL/CURLTargets-release.cmake
/usr/local/lib/cmake/CURL/CURLConfigVersion.cmake
/usr/local/lib/cmake/CURL/CURLConfig.cmake
/usr/local/lib/libcpr.so.1.11.0
/usr/local/lib/libcpr.so.1
/usr/local/lib/libcpr.so
/usr/local/include/cpr/curlmultiholder.h
/usr/local/include/cpr/file.h
/usr/local/include/cpr/util.h
/usr/local/include/cpr/auth.h
/usr/local/include/cpr/range.h
/usr/local/include/cpr/interceptor.h
/usr/local/include/cpr/interface.h
/usr/local/include/cpr/http_version.h
/usr/local/include/cpr/redirect.h
/usr/local/include/cpr/async.h
/usr/local/include/cpr/bearer.h
/usr/local/include/cpr/cert_info.h
/usr/local/include/cpr/user_agent.h
/usr/local/include/cpr/filesystem.h
/usr/local/include/cpr/cookies.h
/usr/local/include/cpr/ssl_ctx.h
/usr/local/include/cpr/reserve_size.h
/usr/local/include/cpr/low_speed.h
/usr/local/include/cpr/unix_socket.h
/usr/local/include/cpr/connect_timeout.h
/usr/local/include/cpr/local_port.h
/usr/local/include/cpr/ssl_options.h
/usr/local/include/cpr/cpr.h
/usr/local/include/cpr/body.h
/usr/local/include/cpr/buffer.h
/usr/local/include/cpr/api.h
/usr/local/include/cpr/multiperform.h
/usr/local/include/cpr/response.h
/usr/local/include/cpr/threadpool.h
/usr/local/include/cpr/error.h
/usr/local/include/cpr/payload.h
/usr/local/include/cpr/proxyauth.h
/usr/local/include/cpr/accept_encoding.h
/usr/local/include/cpr/local_port_range.h
/usr/local/include/cpr/callback.h
/usr/local/include/cpr/curlholder.h
/usr/local/include/cpr/limit_rate.h
/usr/local/include/cpr/status_codes.h
/usr/local/include/cpr/parameters.h
/usr/local/include/cpr/verbose.h
/usr/local/include/cpr/resolve.h
/usr/local/include/cpr/session.h
/usr/local/include/cpr/cprtypes.h
/usr/local/include/cpr/curl_container.h
/usr/local/include/cpr/multipart.h
/usr/local/include/cpr/proxies.h
/usr/local/include/cpr/timeout.h
/usr/local/include/cpr/singleton.h
/usr/local/include/cpr/async_wrapper.h
/usr/local/include/cpr/cprver.h
/usr/local/bin/cmaker
9 changes: 9 additions & 0 deletions src/Command/Command.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ namespace Command {
ParseResult removeOptions(int argc, char** argv);
ParseResult updateOptions(int argc, char** argv);

typedef struct packageResult {
std::string name;
std::string url;
std::string version;
int score;
} packageResult;

typedef struct dependency {
std::string name;
std::string url;
Expand Down Expand Up @@ -134,6 +141,8 @@ namespace Command {
* What the fuck lucas
*/

std::vector<packageResult> searchPackage(std::string query);

std::string downloadIndex();
/*
* adds dependency to toml and regenerates the CMakeLists.txt
Expand Down
70 changes: 0 additions & 70 deletions src/Command/CommandAdd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,76 +38,6 @@ namespace Command {
return true;
}

typedef struct packageResult {
std::string name;
std::string url;
std::string version;
int score;
} packageResult;

std::vector<packageResult> calculatePackageScores(std::vector<std::string> queryTokens){
std::vector<packageResult> results;
json rawIndex = Utils::fetchJson("https://github.com/cmaker-dev/index/releases/latest/download/index.json");
int lengthDiffAbs = 0;
for(std::string query: queryTokens){
for(json package: rawIndex){
//TODO: add description that can be searched
results.push_back({
.name = package["name"],
.url = package["git"],
.score = 0
});
//if it is an exact match
if(results.back().name == query){
results.back().score += 100;
break;
}
//Check if the query is in the package name
if(results.back().name.find(query) != std::string::npos){
results.back().score += 50;
}

lengthDiffAbs = std::abs((int)results.back().name.length() - (int)query.length());
if(results.back().score > 10){
results.back().score -= lengthDiffAbs;
}
}
}
std::sort(results.begin(), results.end(), [](packageResult a, packageResult b){
return a.score > b.score;
});
std::vector<packageResult> resultsUnique;

for(packageResult result: results){
if(std::any_of(resultsUnique.begin(), resultsUnique.end(), [&result](packageResult &r){
r.score += result.score;
return r.name == result.name;
})){
continue;
}
resultsUnique.push_back(result);
}
return resultsUnique;
}

std::vector<packageResult> searchPackage(std::string query){
std::cout << "Searching for package" << std::endl;

std::vector<std::string> queryTokens = Utils::split(query, ' ');

std::vector<packageResult> results = calculatePackageScores(queryTokens);


std::cout << "Results:" << std::endl;
for(int i = results.size();i > -1; i--){
if(results[i].score > 10){
//Adjusting the indexes for the normies
std::cout << "[" << i << "]" << results[i].name << " - (" << results[i].url << ")" << std::endl;
}
}

return results;
}


bool checkForOverlappingDependencies(std::shared_ptr<Context> ctx, std::string name){
Expand Down
122 changes: 98 additions & 24 deletions src/Command/CommandSearchPackage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,108 @@
#include <curl/curl.h>
#include <curl/easy.h>
#include <nlohmann/json.hpp>
#include "../Utils/General.hpp"



namespace Command {
// const std::string RepoIndex = "https://raw.githubusercontent.com/cmaker-dev/index/main/index.json";
// void writeCallback(char* ptr, size_t size, size_t nmemb, std::string* data) {
// data->append(ptr, size * nmemb);
// }
// void SearchPackage(){
// curl_easy_init();
// std::shared_ptr<CURL> curl(curl_easy_init(), curl_easy_cleanup);
//
// curl_easy_setopt(curl.get(), CURLOPT_URL, RepoIndex.c_str());
//
// std::string response;
//
// curl_easy_setopt(curl.get(), CURLOPT_WRITEFUNCTION, writeCallback);
// curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA, &response);
//
// curl_easy_perform(curl.get());
//
// nlohmann::json j = nlohmann::json::parse(response);
//
// std::cout << j.dump(4) << std::endl;
//
//
//
// }
using nlohmann::json;

int levensteinDistance(std::string aStr, std::string bStr){
//minimize the amount of memory used
std::string* a = &aStr;
std::string* b = &bStr;
if(aStr.length() > bStr.length()){
a = &bStr;
b = &aStr;
}
int aLen = a->length();
int bLen = b->length();
int* prev = new int[aLen + 1];
int* curr = new int[aLen + 1];
for(int i = 0; i <= aLen; i++){
prev[i] = i;
}

for(int i = 1; i <= bLen; i++){
curr[0] = i;
for(int j = 1; j <= aLen; j++){
int cost = (*a)[j - 1] == (*b)[i - 1] ? 0 : 1;
curr[j] = std::min(std::min(curr[j - 1] + 1, prev[j] + 1), prev[j - 1] + cost);
}
int* temp = prev;
prev = curr;
curr = temp;
}
int result = prev[aLen];
delete[] prev;
delete[] curr;
return result;
}
std::vector<packageResult> calculatePackageScores(std::vector<std::string> queryTokens){
std::vector<packageResult> results;
json rawIndex = Utils::fetchJson("https://github.com/cmaker-dev/index/releases/latest/download/index.json");
int lengthDiffAbs = 0;
for(std::string query: queryTokens){
for(json package: rawIndex){
//TODO: add description that can be searched
results.push_back({
.name = package["name"],
.url = package["git"],
.score = 0
});
//if it is an exact match
if(results.back().name == query){
results.back().score += 100;
}
//Check if the query is in the package name
if(results.back().name.find(query) != std::string::npos){
results.back().score += 50;
}
if(levensteinDistance(results.back().name, query) < 3){
results.back().score += 10;
}

lengthDiffAbs = std::abs((int)results.back().name.length() - (int)query.length());
if(results.back().score > 20){
results.back().score -= lengthDiffAbs;
}
}
}
std::sort(results.begin(), results.end(), [](packageResult a, packageResult b){
return a.score > b.score;
});
std::vector<packageResult> resultsUnique;

for(packageResult result: results){
if(std::any_of(resultsUnique.begin(), resultsUnique.end(), [&result](packageResult &r){
r.score += result.score;
return r.name == result.name;
})){
continue;
}
resultsUnique.push_back(result);
}
return resultsUnique;
}

std::vector<packageResult> searchPackage(std::string query){
std::cout << "Searching for package" << std::endl;

std::vector<std::string> queryTokens = Utils::split(query, ' ');

std::vector<packageResult> results = calculatePackageScores(queryTokens);


std::cout << "Results:" << std::endl;
for(int i = results.size();i > -1; i--){
if(results[i].score > 10){
//Adjusting the indexes for the normies
std::cout << "[" << i << "]" << "[s:" << results[i].score << "] " << results[i].name << " - (" << results[i].url << ")" << std::endl;
}
}

return results;
}

}

0 comments on commit 689d969

Please sign in to comment.