Replace nlohmann/json with native C++20 JSON engine, cut build RAM/time, fix 32-bit build, enable -O2 -march=native
This commit is contained in:
+51
-58
@@ -4,14 +4,10 @@
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <fstream>
|
||||
#include <set>
|
||||
#include <strings.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <strings.h>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
/* ----------------------------- raw map -------------------------------- */
|
||||
static void cfg_raw_set(Cfg &c, std::string_view k, std::string_view v) {
|
||||
@@ -62,11 +58,15 @@ bool internal_key(std::string_view k) {
|
||||
/* parse_cfg_file records every key it sees in *file_keys so that the
|
||||
* config file can take precedence over environment variables. */
|
||||
static void parse_cfg_file(std::string_view path, Cfg &c, std::set<std::string> *file_keys) {
|
||||
std::ifstream f(std::string(path), std::ios::binary);
|
||||
if (!f) return;
|
||||
std::string line;
|
||||
while (std::getline(f, line)) {
|
||||
std::string_view s(line);
|
||||
std::string content;
|
||||
if (!read_file_str(path, content)) return;
|
||||
size_t pos = 0, n = content.size();
|
||||
while (pos < n) {
|
||||
size_t nl = content.find('\n', pos);
|
||||
std::string_view s = (nl == std::string::npos)
|
||||
? std::string_view(content).substr(pos)
|
||||
: std::string_view(content).substr(pos, nl - pos);
|
||||
pos = (nl == std::string::npos) ? n : nl + 1;
|
||||
while (!s.empty() && std::isspace((unsigned char)s.front())) s.remove_prefix(1);
|
||||
if (s.empty() || s.front() == '#') continue;
|
||||
auto eq = s.find('=');
|
||||
@@ -136,8 +136,8 @@ Cfg get_cfg(std::string_view path) {
|
||||
int set_cfg(std::string_view path, std::string_view key, std::string_view val) {
|
||||
std::vector<std::string> lines;
|
||||
{
|
||||
std::ifstream f(std::string(path), std::ios::binary);
|
||||
std::string content((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>());
|
||||
std::string content;
|
||||
read_file_str(path, content);
|
||||
size_t i = 0, n = content.size();
|
||||
while (i < n) {
|
||||
size_t j = content.find('\n', i);
|
||||
@@ -168,10 +168,9 @@ int set_cfg(std::string_view path, std::string_view key, std::string_view val) {
|
||||
}
|
||||
lines.push_back(sfmt("%s=%s\n", std::string(key).c_str(), std::string(val).c_str()));
|
||||
}
|
||||
std::ofstream out(std::string(path), std::ios::binary);
|
||||
if (!out) return -1;
|
||||
for (auto &line : lines) out << line;
|
||||
return 0;
|
||||
std::string out_buf;
|
||||
for (auto &line : lines) out_buf += line;
|
||||
return write_file_str(path, out_buf) ? 0 : -1;
|
||||
}
|
||||
|
||||
std::string config_path() {
|
||||
@@ -189,31 +188,25 @@ static int query_models_context_window(Cfg &cfg) {
|
||||
std::string err;
|
||||
if (http_get(cfg, url, body, code, err) != 0) return 0;
|
||||
if (code >= 400) return 0;
|
||||
Json root_mut;
|
||||
if (!Json::parse(body, root_mut) || !root_mut.is_object()) return 0;
|
||||
const Json &root = root_mut;
|
||||
const Json &list = root.contains("data") ? root["data"] : root["models"];
|
||||
if (!list.is_array()) return 0;
|
||||
static const char *keys[] = {"context_window", "context_length", "max_context_length",
|
||||
"max_model_len", "context_size", "max_tokens", "max_input_tokens", nullptr};
|
||||
int cw = 0;
|
||||
try {
|
||||
auto root = json::parse(body);
|
||||
if (!root.is_object()) return 0;
|
||||
json list = nullptr;
|
||||
if (root.contains("data")) list = root["data"];
|
||||
else if (root.contains("models")) list = root["models"];
|
||||
if (list.is_array()) {
|
||||
static const char *keys[] = {"context_window", "context_length", "max_context_length",
|
||||
"max_model_len", "context_size", "max_tokens", "max_input_tokens", nullptr};
|
||||
for (auto &item : list) {
|
||||
if (cw != 0) break;
|
||||
if (!item.is_object() || !item.contains("id") || !item["id"].is_string()) continue;
|
||||
std::string id = item["id"].get<std::string>();
|
||||
if (!id.empty() && (id == cfg.model || strcasecmp(id.c_str(), cfg.model.c_str()) == 0)) {
|
||||
for (int k = 0; keys[k]; k++) {
|
||||
if (item.contains(keys[k]) && item[keys[k]].is_number_integer()) {
|
||||
int v = item[keys[k]].get<int>();
|
||||
if (v > 0) { cw = v; break; }
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto &item : list.aval) {
|
||||
if (cw != 0) break;
|
||||
if (!item.is_object()) continue;
|
||||
std::string id = item["id"].str();
|
||||
if (!id.empty() && (id == cfg.model || strcasecmp(id.c_str(), cfg.model.c_str()) == 0)) {
|
||||
for (int k = 0; keys[k]; k++) {
|
||||
int v = item[keys[k]].as_int();
|
||||
if (v > 0) { cw = v; break; }
|
||||
}
|
||||
}
|
||||
} catch (...) { return 0; }
|
||||
}
|
||||
return cw;
|
||||
}
|
||||
|
||||
@@ -238,29 +231,29 @@ std::string list_models(Cfg &cfg, int *errout) {
|
||||
std::string err;
|
||||
if (http_get(cfg, url, body, code, err) != 0) { *errout = -1; return err.empty() ? "request failed" : err; }
|
||||
if (code >= 400) { *errout = -1; return "HTTP error from /models"; }
|
||||
std::string out;
|
||||
try {
|
||||
auto root = json::parse(body);
|
||||
if (!root.is_object()) { *errout = -1; return "invalid JSON from /models"; }
|
||||
json list = nullptr;
|
||||
if (root.contains("data")) list = root["data"];
|
||||
else if (root.contains("models")) list = root["models"];
|
||||
bool any = false;
|
||||
if (list.is_array()) {
|
||||
for (auto &item : list) {
|
||||
if (!item.is_object() || !item.contains("id") || !item["id"].is_string()) continue;
|
||||
std::string id = item["id"].get<std::string>();
|
||||
if (id.empty()) continue;
|
||||
any = true;
|
||||
if (id == cfg.model) str_appendf(out, "* %s\n", id.c_str());
|
||||
else str_appendf(out, " %s\n", id.c_str());
|
||||
}
|
||||
}
|
||||
if (!any) return "No models returned by the endpoint.";
|
||||
} catch (...) {
|
||||
Json root_mut;
|
||||
if (!Json::parse(body, root_mut) || !root_mut.is_object()) {
|
||||
*errout = -1;
|
||||
return "invalid JSON from /models";
|
||||
}
|
||||
const Json &root = root_mut;
|
||||
const Json &list = root.contains("data") ? root["data"] : root["models"];
|
||||
std::string out;
|
||||
bool any = false;
|
||||
if (list.is_array()) {
|
||||
for (auto &item : list.aval) {
|
||||
if (!item.is_object()) continue;
|
||||
std::string id = item["id"].str();
|
||||
if (id.empty()) continue;
|
||||
any = true;
|
||||
if (id == cfg.model) str_appendf(out, "* %s\n", id.c_str());
|
||||
else str_appendf(out, " %s\n", id.c_str());
|
||||
}
|
||||
}
|
||||
if (!any) {
|
||||
*errout = 0;
|
||||
return "No models returned by the endpoint.";
|
||||
}
|
||||
*errout = 0;
|
||||
return out;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user