Compare commits
2 Commits
9259f7c198
...
e83a44d7b5
Author | SHA1 | Date |
---|---|---|
|
e83a44d7b5 | |
|
b277d0274c |
|
@ -58,8 +58,8 @@ static inline Element generate_user_link(const httplib::Request& req, const Conf
|
||||||
std::string profile_picture = proxy_image_url(config, illust.user_profile_pictures.thumbnail_or_original().url);
|
std::string profile_picture = proxy_image_url(config, illust.user_profile_pictures.thumbnail_or_original().url);
|
||||||
std::string user_link = get_origin(req, config) + "/users/" + std::to_string(illust.user_id);
|
std::string user_link = get_origin(req, config) + "/users/" + std::to_string(illust.user_id);
|
||||||
|
|
||||||
return Element("a", {{"class", "usermetadata"}, {"href", std::move(user_link)}}, {
|
return Element("a", {{"class", "user_metadata"}, {"href", std::move(user_link)}}, {
|
||||||
Element("img", {{"class", "profilepicture small"}, {"loading", "lazy"}, {"src", std::move(profile_picture)}}, {}),
|
Element("img", {{"class", "user_profile_picture small"}, {"loading", "lazy"}, {"src", std::move(profile_picture)}}, {}),
|
||||||
Element("b", {illust.user_display_name})
|
Element("b", {illust.user_display_name})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ static inline Element generate_user_link(const httplib::Request& req, const Conf
|
||||||
static inline Element generate_images(const httplib::Request& req, const Config& config, const Illust& illust) {
|
static inline Element generate_images(const httplib::Request& req, const Config& config, const Illust& illust) {
|
||||||
using namespace std::string_literals;
|
using namespace std::string_literals;
|
||||||
|
|
||||||
Element div("div", {{"class", "illustimages"}}, {});
|
Element div("div", {{"class", "illust-images"}}, {});
|
||||||
bool show_pages = illust.images.size() > 1;
|
bool show_pages = illust.images.size() > 1;
|
||||||
|
|
||||||
if (show_pages) {
|
if (show_pages) {
|
||||||
|
@ -176,7 +176,7 @@ static inline Element generate_description(const httplib::Request& req, const Co
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Element generate_illust_tags(const httplib::Request& req, const Config& config, const Illust& illust) {
|
static inline Element generate_illust_tags(const httplib::Request& req, const Config& config, const Illust& illust) {
|
||||||
Element div("div", {{"class", "illusttags"}}, {});
|
Element div("div", {{"class", "illust-tags"}}, {});
|
||||||
|
|
||||||
if (illust.ai_generated) {
|
if (illust.ai_generated) {
|
||||||
div.nodes.push_back(Element("b", {"AI-Generated "}));
|
div.nodes.push_back(Element("b", {"AI-Generated "}));
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
|
#include <string>
|
||||||
|
#include <FastHash.h>
|
||||||
|
|
||||||
#include "routes.h"
|
#include "routes.h"
|
||||||
|
#include "../servehelper.h"
|
||||||
|
|
||||||
void css_route(const httplib::Request& req, httplib::Response& res) {
|
#define CSS R"EOF(
|
||||||
res.set_content(R"EOF(
|
|
||||||
|
|
||||||
/* GENERAL */
|
/* GENERAL */
|
||||||
:root {
|
:root {
|
||||||
--background-color: black;
|
--background-color: black;
|
||||||
|
@ -56,13 +58,13 @@ void css_route(const httplib::Request& req, httplib::Response& res) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ILLUSTRATIONS GRID (used in user illustrations page and search results page) */
|
/* ILLUSTRATIONS GRID (used in user illustrations page and search results page) */
|
||||||
.grid p {
|
.illusts_grid p {
|
||||||
width: 15em;
|
width: 15em;
|
||||||
}
|
}
|
||||||
.illustsgriditem {
|
.illusts_grid-illust {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
.illustbadge {
|
.illusts_grid-illust_badge {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: .25em;
|
top: .25em;
|
||||||
right: .25em;
|
right: .25em;
|
||||||
|
@ -71,48 +73,50 @@ void css_route(const httplib::Request& req, httplib::Response& res) {
|
||||||
background-color: var(--illust-badge-background-color);
|
background-color: var(--illust-badge-background-color);
|
||||||
text-decoration: none !important;
|
text-decoration: none !important;
|
||||||
}
|
}
|
||||||
.illustbadge.ai {
|
.illusts_grid-illust_badge.ai {
|
||||||
background-color: var(--illust-badge-ai-background-color);
|
background-color: var(--illust-badge-ai-background-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ILLUSTRATIONS PAGE */
|
/* USER PAGE AND ILLUSTRATIONS PAGE */
|
||||||
.profilepicture.small {
|
.user_profile_picture {
|
||||||
|
margin-right: .5em;
|
||||||
|
width: 5em;
|
||||||
|
height: 5em;
|
||||||
|
}
|
||||||
|
.user_metadata {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-left: .5em;
|
||||||
|
}
|
||||||
|
.user_profile_picture.small {
|
||||||
width: 2.5em;
|
width: 2.5em;
|
||||||
height: 2.5em;
|
height: 2.5em;
|
||||||
}
|
}
|
||||||
.illustimages {
|
|
||||||
|
/* ILLUSTRATIONS PAGE */
|
||||||
|
.illust-images {
|
||||||
display: grid;
|
display: grid;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
.illustimages .landmark {
|
.illust-images .landmark {
|
||||||
padding-top: 1em;
|
padding-top: 1em;
|
||||||
padding-bottom: 1em;
|
padding-bottom: 1em;
|
||||||
}
|
}
|
||||||
.illusttags {
|
.illust-tags {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 0 1em;
|
gap: 0 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* USER PAGE */
|
/* USER PAGE */
|
||||||
.profilecover {
|
.user-cover {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 50vh;
|
height: 50vh;
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
}
|
}
|
||||||
.profilepicture {
|
|
||||||
margin-right: .5em;
|
|
||||||
width: 5em;
|
|
||||||
height: 5em;
|
|
||||||
}
|
|
||||||
.usermetadata {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
margin-left: .5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* SEARCH RESULTS PAGE */
|
/* SEARCH RESULTS PAGE */
|
||||||
.searchsuggestions {
|
.search_results-suggestions {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-top: .5em;
|
margin-top: .5em;
|
||||||
|
@ -127,6 +131,20 @@ void css_route(const httplib::Request& req, httplib::Response& res) {
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-color: var(--error-border-color);
|
border-color: var(--error-border-color);
|
||||||
}
|
}
|
||||||
|
)EOF"
|
||||||
|
#define CSS_LEN sizeof(CSS) / sizeof(CSS[0]) - 1
|
||||||
|
|
||||||
)EOF", "text/css");
|
const uint64_t css_hash = FastHashConstEval(CSS, CSS_LEN, 0);
|
||||||
|
|
||||||
|
void css_route(const httplib::Request& req, httplib::Response& res) {
|
||||||
|
res.set_header("ETag", std::string(1, '"') + std::to_string(css_hash) + '"');
|
||||||
|
res.set_header("Cache-Control", "max-age=31536000, immutable");
|
||||||
|
|
||||||
|
if (should_send_304(req, css_hash)) {
|
||||||
|
res.status = 304;
|
||||||
|
res.set_header("Content-Length", std::to_string(CSS_LEN));
|
||||||
|
res.set_header("Content-Type", "text/css");
|
||||||
|
} else {
|
||||||
|
res.set_content(CSS, CSS_LEN, "text/css");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
struct Config; // forward declaration from ../config.h
|
struct Config; // forward declaration from ../config.h
|
||||||
class PixivClient; // forward declaration from ../pixivclient.h
|
class PixivClient; // forward declaration from ../pixivclient.h
|
||||||
|
|
||||||
|
extern const uint64_t css_hash;
|
||||||
|
|
||||||
void home_route(const httplib::Request& req, httplib::Response& res, const Config& config);
|
void home_route(const httplib::Request& req, httplib::Response& res, const Config& config);
|
||||||
void css_route(const httplib::Request& req, httplib::Response& res);
|
void css_route(const httplib::Request& req, httplib::Response& res);
|
||||||
void user_illustrations_route(const httplib::Request& req, httplib::Response& res, const Config& config, PixivClient& pixiv_client);
|
void user_illustrations_route(const httplib::Request& req, httplib::Response& res, const Config& config, PixivClient& pixiv_client);
|
||||||
|
|
|
@ -121,7 +121,7 @@ static inline Element generate_search_suggestions(const httplib::Request& req, c
|
||||||
|
|
||||||
Element details("details", {
|
Element details("details", {
|
||||||
Element("summary", {"Search suggestions"}),
|
Element("summary", {"Search suggestions"}),
|
||||||
Element("ul", {{"class", "searchsuggestions"}}, ul_nodes)
|
Element("ul", {{"class", "search_results-suggestions"}}, ul_nodes)
|
||||||
});
|
});
|
||||||
if (open_by_default) {
|
if (open_by_default) {
|
||||||
details.attributes.push_back({"open", ""});
|
details.attributes.push_back({"open", ""});
|
||||||
|
|
|
@ -11,15 +11,15 @@ Element generate_user_header(const User& user, const Config& config) {
|
||||||
std::string cover_original = proxy_image_url(config, user.cover_images->original_or_thumbnail().url);
|
std::string cover_original = proxy_image_url(config, user.cover_images->original_or_thumbnail().url);
|
||||||
std::string cover_thumbnail = proxy_image_url(config, user.cover_images->thumbnail_or_original().url);
|
std::string cover_thumbnail = proxy_image_url(config, user.cover_images->thumbnail_or_original().url);
|
||||||
header.nodes.push_back(Element("a", {{"href", std::move(cover_original)}}, {
|
header.nodes.push_back(Element("a", {{"href", std::move(cover_original)}}, {
|
||||||
Element("img", {{"class", "profilecover"}, {"loading", "lazy"}, {"src", std::move(cover_thumbnail)}}, {})
|
Element("img", {{"class", "user-cover"}, {"loading", "lazy"}, {"src", std::move(cover_thumbnail)}}, {})
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string profile_picture_original = proxy_image_url(config, user.profile_pictures.original_or_thumbnail().url);
|
std::string profile_picture_original = proxy_image_url(config, user.profile_pictures.original_or_thumbnail().url);
|
||||||
std::string profile_picture_thumbnail = proxy_image_url(config, user.profile_pictures.thumbnail_or_original().url);
|
std::string profile_picture_thumbnail = proxy_image_url(config, user.profile_pictures.thumbnail_or_original().url);
|
||||||
header.nodes.push_back(Element("div", {{"class", "usermetadata"}}, {
|
header.nodes.push_back(Element("div", {{"class", "user_metadata"}}, {
|
||||||
Element("a", {{"href", std::move(profile_picture_original)}}, {
|
Element("a", {{"href", std::move(profile_picture_original)}}, {
|
||||||
Element("img", {{"class", "profilepicture"}, {"loading", "lazy"}, {"src", std::move(profile_picture_thumbnail)}}, {})
|
Element("img", {{"class", "user_profile_picture"}, {"loading", "lazy"}, {"src", std::move(profile_picture_thumbnail)}}, {})
|
||||||
}),
|
}),
|
||||||
Element("div", {
|
Element("div", {
|
||||||
Element("p", {Element("b", {user.display_name}), " (@", user.username, ")"}),
|
Element("p", {Element("b", {user.display_name}), " (@", user.username, ")"}),
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
#include <FastHash.h>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "pixivmodels.h"
|
#include "pixivmodels.h"
|
||||||
#include "servehelper.h"
|
#include "servehelper.h"
|
||||||
|
#include "routes/routes.h"
|
||||||
|
|
||||||
static Element generate_pager(const Illusts& illusts, size_t page, const char* id);
|
static Element generate_pager(const Illusts& illusts, size_t page, const char* id);
|
||||||
static inline Element generate_illusts_grid(const httplib::Request& req, const Config& config, const Illusts& illusts);
|
static inline Element generate_illusts_grid(const httplib::Request& req, const Config& config, const Illusts& illusts);
|
||||||
|
@ -16,16 +18,26 @@ void serve(const httplib::Request& req, httplib::Response& res, const Config& co
|
||||||
res.set_header("Content-Security-Policy", "default-src 'none'; style-src "s + css_url
|
res.set_header("Content-Security-Policy", "default-src 'none'; style-src "s + css_url
|
||||||
+ "; img-src https://s.pximg.net " + config.image_proxy_url.get_origin());
|
+ "; img-src https://s.pximg.net " + config.image_proxy_url.get_origin());
|
||||||
|
|
||||||
Element html("html", {
|
std::string html = "<!DOCTYPE html>"s + Element("html", {
|
||||||
Element("head", {
|
Element("head", {
|
||||||
Element("meta", {{"charset", "utf-8"}}, {}),
|
Element("meta", {{"charset", "utf-8"}}, {}),
|
||||||
Element("title", {std::move(title)}),
|
Element("title", {std::move(title)}),
|
||||||
Element("link", {{"rel", "stylesheet"}, {"href", std::move(css_url)}}, {}),
|
Element("link", {{"rel", "stylesheet"}, {"href", std::move(css_url) + "?v=" + std::to_string(css_hash)}}, {}),
|
||||||
Element("meta", {{"name", "viewport"}, {"content", "width=device-width,initial-scale=1"}}, {})
|
Element("meta", {{"name", "viewport"}, {"content", "width=device-width,initial-scale=1"}}, {})
|
||||||
}),
|
}),
|
||||||
std::move(element)
|
std::move(element)
|
||||||
});
|
}).serialize();
|
||||||
res.set_content("<!DOCTYPE html>"s + html.serialize(), "text/html");
|
|
||||||
|
uint64_t hash = FastHash(html.data(), html.size(), 0);
|
||||||
|
res.set_header("ETag", std::string(1, '"') + std::to_string(hash) + '"');
|
||||||
|
|
||||||
|
if (should_send_304(req, hash)) {
|
||||||
|
res.status = 304;
|
||||||
|
res.set_header("Content-Length", std::to_string(html.size()));
|
||||||
|
res.set_header("Content-Type", "text/html");
|
||||||
|
} else {
|
||||||
|
res.set_content(std::move(html), "text/html");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void serve_error(const httplib::Request& req, httplib::Response& res, const Config& config,
|
void serve_error(const httplib::Request& req, httplib::Response& res, const Config& config,
|
||||||
|
@ -100,6 +112,16 @@ std::string proxy_image_url(const Config& config, blankie::murl::Url url) {
|
||||||
return proxy_url(config.image_proxy_url, std::move(url));
|
return proxy_url(config.image_proxy_url, std::move(url));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool should_send_304(const httplib::Request& req, uint64_t hash) {
|
||||||
|
std::string header = req.get_header_value("If-None-Match");
|
||||||
|
if (header == "*") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t pos = header.find(std::string(1, '"') + std::to_string(hash) + '"');
|
||||||
|
return pos != std::string::npos && (pos == 0 || header[pos - 1] != '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Element generate_illusts_pager(const httplib::Request& req, const Config& config, const Illusts& illusts, size_t page, const char* id) {
|
Element generate_illusts_pager(const httplib::Request& req, const Config& config, const Illusts& illusts, size_t page, const char* id) {
|
||||||
|
@ -135,7 +157,7 @@ static Element generate_pager(const Illusts& illusts, size_t page, const char* i
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Element generate_illusts_grid(const httplib::Request& req, const Config& config, const Illusts& illusts) {
|
static inline Element generate_illusts_grid(const httplib::Request& req, const Config& config, const Illusts& illusts) {
|
||||||
Element div("div", {{"class", "grid"}}, {});
|
Element div("div", {{"class", "grid illusts_grid"}}, {});
|
||||||
|
|
||||||
div.nodes.reserve(illusts.illusts.size());
|
div.nodes.reserve(illusts.illusts.size());
|
||||||
for (const Illust& i : illusts.illusts) {
|
for (const Illust& i : illusts.illusts) {
|
||||||
|
@ -149,7 +171,7 @@ static inline Element generate_illusts_grid_item(const httplib::Request& req, co
|
||||||
std::string illust_url = get_origin(req, config) + "/artworks/" + std::to_string(illust.illust_id);
|
std::string illust_url = get_origin(req, config) + "/artworks/" + std::to_string(illust.illust_id);
|
||||||
std::string image_url = proxy_image_url(config, illust.images[0].thumbnail_or_original(1).url);
|
std::string image_url = proxy_image_url(config, illust.images[0].thumbnail_or_original(1).url);
|
||||||
|
|
||||||
Element div("div", {{"class", "illustsgriditem"}}, {
|
Element div("div", {{"class", "illusts_grid-illust"}}, {
|
||||||
Element("a", {{"href", illust_url}}, {
|
Element("a", {{"href", illust_url}}, {
|
||||||
Element("img", {{"loading", "lazy"}, {"src", std::move(image_url)}}, {}),
|
Element("img", {{"loading", "lazy"}, {"src", std::move(image_url)}}, {}),
|
||||||
Element("p", {illust.title})
|
Element("p", {illust.title})
|
||||||
|
@ -164,7 +186,7 @@ static inline Element generate_illusts_grid_item(const httplib::Request& req, co
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Element generate_illust_badge(const Illust& illust, const std::string& illust_url) {
|
static inline Element generate_illust_badge(const Illust& illust, const std::string& illust_url) {
|
||||||
const char* css_class = !illust.ai_generated ? "illustbadge" : "illustbadge ai";
|
const char* css_class = !illust.ai_generated ? "illusts_grid-illust_badge" : "illusts_grid-illust_badge ai";
|
||||||
|
|
||||||
if (illust.page_count > 1) {
|
if (illust.page_count > 1) {
|
||||||
return Element("a", {{"class", css_class}, {"href", illust_url + "?preview=1"}}, {
|
return Element("a", {{"class", css_class}, {"href", illust_url + "?preview=1"}}, {
|
||||||
|
|
|
@ -18,5 +18,6 @@ void serve_redirect(const httplib::Request& req, httplib::Response& res, const C
|
||||||
std::string get_origin(const httplib::Request& req, const Config& config);
|
std::string get_origin(const httplib::Request& req, const Config& config);
|
||||||
std::string proxy_url(blankie::murl::Url base, blankie::murl::Url url);
|
std::string proxy_url(blankie::murl::Url base, blankie::murl::Url url);
|
||||||
std::string proxy_image_url(const Config& config, blankie::murl::Url url);
|
std::string proxy_image_url(const Config& config, blankie::murl::Url url);
|
||||||
|
bool should_send_304(const httplib::Request& req, uint64_t hash);
|
||||||
|
|
||||||
Element generate_illusts_pager(const httplib::Request& req, const Config& config, const Illusts& illusts, size_t page, const char* id);
|
Element generate_illusts_pager(const httplib::Request& req, const Config& config, const Illusts& illusts, size_t page, const char* id);
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
// https://github.com/KoneLinx/small_ECS/blob/master/FastHash.h
|
||||||
|
// but slightly modified to add FastHashConstEval and abandon ranges
|
||||||
|
|
||||||
|
// Copyright(C) 2021 Kobe Vrijsen <kobevrijsen@posteo.be>
|
||||||
|
//
|
||||||
|
// A simple ECS example
|
||||||
|
//
|
||||||
|
// This file is free software and distributed under the terms of the European Union
|
||||||
|
// Public Lincense as published by the European Commision; either version 1.2 of the
|
||||||
|
// License, or , at your option, any later version.
|
||||||
|
|
||||||
|
/* The MIT License
|
||||||
|
|
||||||
|
Copyright (C) 2012 Zilong Tan (eric.zltan@gmail.com)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person
|
||||||
|
obtaining a copy of this software and associated documentation
|
||||||
|
files (the "Software"), to deal in the Software without
|
||||||
|
restriction, including without limitation the rights to use, copy,
|
||||||
|
modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||||
|
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Source: fast-hash https://github.com/ztanml/fast-hash (26 Nov 2021)
|
||||||
|
// Changes: General uplift and providing a general constant hash for ranges
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// Compression function for Merkle-Damgard construction.
|
||||||
|
// This function is generated using the framework provided.
|
||||||
|
//#define mix(h) ({
|
||||||
|
// (h) ^= (h) >> 23;
|
||||||
|
// (h) *= 0x2127599bf4325c37ULL;
|
||||||
|
// (h) ^= (h) >> 47; })
|
||||||
|
|
||||||
|
constexpr uint64_t FastHash(const char* str, size_t size, uint64_t seed/*, uint64_t back = {}*/)
|
||||||
|
{
|
||||||
|
auto const mix = [](uint64_t h)
|
||||||
|
{
|
||||||
|
h ^= h >> 23;
|
||||||
|
h *= 0x2127599bf4325c37ULL;
|
||||||
|
h ^= h >> 47;
|
||||||
|
return h;
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint64_t m = 0x880355f21e6d1965ULL;
|
||||||
|
|
||||||
|
uint64_t h = seed ^ (size * m);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
h ^= mix(static_cast<uint64_t>(str[i]));
|
||||||
|
h *= m;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (back != uint64_t())
|
||||||
|
//{
|
||||||
|
// h ^= mix(back);
|
||||||
|
// h *= m;
|
||||||
|
//}
|
||||||
|
|
||||||
|
return mix(h);
|
||||||
|
}
|
||||||
|
|
||||||
|
consteval uint64_t FastHashConstEval(const char* str, size_t size, uint64_t seed) {
|
||||||
|
return FastHash(str, size, seed);
|
||||||
|
}
|
Loading…
Reference in New Issue