0 then
- local balancerTag = get_balancer_tag(_node[".name"])
- table.insert(balancers, {
- tag = balancerTag,
- selector = valid_nodes,
- fallbackTag = fallback_node_id,
- strategy = { type = _node.balancingStrategy or "random" }
- })
- if _node.balancingStrategy == "leastPing" then
- if not observatory then
- observatory = {
- subjectSelector = { "blc-" },
- probeUrl = _node.useCustomProbeUrl and _node.probeUrl or nil,
- probeInterval = _node.probeInterval or "1m",
- enableConcurrency = true
- }
- end
+ table.insert(balancers, {
+ tag = balancer_tag,
+ selector = valid_nodes,
+ fallbackTag = fallback_node_id,
+ strategy = { type = _node.balancingStrategy or "random" }
+ })
+ if _node.balancingStrategy == "leastPing" then
+ if not observatory then
+ observatory = {
+ subjectSelector = { "blc-" },
+ probeUrl = _node.useCustomProbeUrl and _node.probeUrl or nil,
+ probeInterval = _node.probeInterval or "1m",
+ enableConcurrency = true
+ }
end
- if loopbackTag == nil or loopbackTag =="" then loopbackTag = _node[".name"] end
- local inboundTag = gen_loopback(loopbackTag, _node[".name"])
- table.insert(rules, { type = "field", inboundTag = { inboundTag }, balancerTag = balancerTag })
- valid = true
end
- return valid
+ local inbound_tag = gen_loopback(loopback_tag, loopback_dst)
+ table.insert(rules, { type = "field", inboundTag = { inbound_tag }, balancerTag = balancer_tag })
+ return balancer_tag
end
local function set_outbound_detour(node, outbound, outbounds_table, shunt_rule_name)
if not node or not outbound or not outbounds_table then return nil end
- local default_outTag = outbound.tag
+ local default_out_tag = outbound.tag
if node.to_node then
local to_node = uci:get_all(appname, node.to_node)
@@ -759,33 +759,35 @@ function gen_config(var)
transportLayer = true
}
table.insert(outbounds_table, to_outbound)
- default_outTag = to_outbound.tag
+ default_out_tag = to_outbound.tag
end
end
end
- return default_outTag
+ return default_out_tag
end
if node.protocol == "_shunt" then
- local proxy_tag = "main"
local proxy_node_id = node["main_node"]
- local proxy_node = node.preproxy_enabled == "1" and proxy_node_id and uci:get_all(appname, proxy_node_id) or nil
- local proxy_outboundTag, proxy_balancerTag
+ local proxy_tag = "main"
+ local proxy_balancer_tag
+ local proxy_nodes
local function gen_shunt_node(rule_name, _node_id)
if not rule_name then return nil, nil end
- if not _node_id then _node_id = node[rule_name] or "nil" end
- local rule_outboundTag
- local rule_balancerTag
+ if not _node_id then
+ _node_id = node[rule_name] or nil
+ if not _node_id then return nil, nil end
+ end
if _node_id == "_direct" then
- rule_outboundTag = "direct"
+ return "direct", nil
elseif _node_id == "_blackhole" then
- rule_outboundTag = "blackhole"
+ return "blackhole", nil
elseif _node_id == "_default" then
- rule_outboundTag = "default"
+ return "default", nil
elseif _node_id:find("Socks_") then
local socks_id = _node_id:sub(1 + #"Socks_")
local socks_node = uci:get_all(appname, socks_id) or nil
+ local socks_tag
if socks_node then
local _node = {
type = "Xray",
@@ -798,124 +800,121 @@ function gen_config(var)
local outbound = gen_outbound(flag, _node, rule_name)
if outbound then
table.insert(outbounds, outbound)
- rule_outboundTag = rule_name
+ socks_tag = outbound.tag
end
end
- elseif _node_id ~= "nil" then
- local _node = uci:get_all(appname, _node_id)
- if not _node then return nil, nil end
+ return socks_tag, nil
+ end
- if api.is_normal_node(_node) then
- local use_proxy = proxy_node and node[rule_name .. "_proxy_tag"] == proxy_tag and _node_id ~= proxy_node_id
- if use_proxy and proxy_balancerTag then
- for _, blc_node_id in ipairs(proxy_node.balancing_node) do
- if _node_id == blc_node_id then
- use_proxy = false
- break
- end
- end
+ local _node = uci:get_all(appname, _node_id)
+ if not _node then return nil, nil end
+
+ if api.is_normal_node(_node) then
+ local use_proxy = proxy_tag and node[rule_name .. "_proxy_tag"] == proxy_tag and _node_id ~= proxy_node_id
+ if use_proxy and proxy_balancer_tag and proxy_nodes[_node_id] then use_proxy = false end
+ local copied_outbound
+ for index, value in ipairs(outbounds) do
+ if value["_flag_tag"] == _node_id and value["_flag_proxy_tag"] == (use_proxy and proxy_tag or "nil") then
+ copied_outbound = api.clone(value)
+ break
end
- local copied_outbound
- for index, value in ipairs(outbounds) do
- if value["_flag_tag"] == _node_id and value["_flag_proxy_tag"] == proxy_tag then
- copied_outbound = api.clone(value)
- break
- end
+ end
+ if copied_outbound then
+ copied_outbound.tag = rule_name
+ table.insert(outbounds, copied_outbound)
+ return copied_outbound.tag, nil
+ end
+ --new outbound
+ if use_proxy and (_node.type ~= "Xray" or _node.flow == "xtls-rprx-vision") then
+ new_port = get_new_port()
+ table.insert(inbounds, {
+ tag = "proxy_" .. rule_name,
+ listen = "127.0.0.1",
+ port = new_port,
+ protocol = "dokodemo-door",
+ settings = {network = "tcp,udp", address = _node.address, port = tonumber(_node.port)}
+ })
+ if _node.tls_serverName == nil then
+ _node.tls_serverName = _node.address
end
- if copied_outbound then
- copied_outbound.tag = rule_name
- table.insert(outbounds, copied_outbound)
- rule_outboundTag = rule_name
- else
- if use_proxy and (_node.type ~= "Xray" or _node.flow == "xtls-rprx-vision") then
- new_port = get_new_port()
- table.insert(inbounds, {
- tag = "proxy_" .. rule_name,
- listen = "127.0.0.1",
- port = new_port,
- protocol = "dokodemo-door",
- settings = {network = "tcp,udp", address = _node.address, port = tonumber(_node.port)}
- })
- if _node.tls_serverName == nil then
- _node.tls_serverName = _node.address
- end
- _node.address = "127.0.0.1"
- _node.port = new_port
- table.insert(rules, 1, {
- type = "field",
- inboundTag = {"proxy_" .. rule_name},
- outboundTag = proxy_outboundTag,
- balancerTag = proxy_balancerTag
- })
- end
- local proxy_table = {
- proxy = use_proxy and 1 or 0,
- tag = use_proxy and proxy_tag or nil
- }
- if xray_settings.fragment == "1" and not proxy_table.tag then
- proxy_table.fragment = true
- end
- local outbound = gen_outbound(flag, _node, rule_name, proxy_table)
- if outbound then
- set_outbound_detour(_node, outbound, outbounds, rule_name)
- table.insert(outbounds, outbound)
- rule_outboundTag = rule_name
- end
- end
- elseif _node.protocol == "_balancing" then
- local is_new_balancer = true
- rule_balancerTag = get_balancer_tag(_node_id)
- for _, v in ipairs(balancers) do
- if v.tag == rule_balancerTag then
- is_new_balancer = false
- gen_loopback(rule_name, _node_id)
- break
- end
- end
- if is_new_balancer then
- local valid = gen_balancer(_node, rule_name)
- if not valid then
- rule_balancerTag = nil
- end
- end
- elseif _node.protocol == "_iface" then
- if _node.iface then
- local outbound = {
- protocol = "freedom",
- tag = rule_name,
- streamSettings = {
- sockopt = {
- mark = 255,
- interface = _node.iface
- }
+ _node.address = "127.0.0.1"
+ _node.port = new_port
+ table.insert(rules, 1, {
+ type = "field",
+ inboundTag = {"proxy_" .. rule_name},
+ outboundTag = not proxy_balancer_tag and proxy_tag or nil,
+ balancerTag = proxy_balancer_tag
+ })
+ end
+ local proxy_table = {
+ proxy = use_proxy and 1 or 0,
+ tag = use_proxy and proxy_tag or nil
+ }
+ if xray_settings.fragment == "1" and not proxy_table.tag then
+ proxy_table.fragment = true
+ end
+ local outbound = gen_outbound(flag, _node, rule_name, proxy_table)
+ local outbound_tag
+ if outbound then
+ set_outbound_detour(_node, outbound, outbounds, rule_name)
+ table.insert(outbounds, outbound)
+ outbound_tag = outbound.tag
+ end
+ return outbound_tag, nil
+ elseif _node.protocol == "_balancing" then
+
+ return nil, gen_balancer(_node, rule_name)
+ elseif _node.protocol == "_iface" then
+ if _node.iface then
+ local outbound = {
+ protocol = "freedom",
+ tag = rule_name,
+ streamSettings = {
+ sockopt = {
+ mark = 255,
+ interface = _node.iface
}
}
- table.insert(outbounds, outbound)
- rule_outboundTag = rule_name
- sys.call("touch /tmp/etc/passwall/iface/" .. _node.iface)
- end
+ }
+ table.insert(outbounds, outbound)
+ sys.call("touch /tmp/etc/passwall/iface/" .. _node.iface)
+ return outbound.tag, nil
end
end
- return rule_outboundTag, rule_balancerTag
end
--proxy_node
- if proxy_node then
- proxy_outboundTag, proxy_balancerTag = gen_shunt_node(proxy_tag, proxy_node_id)
- if not proxy_outboundTag and not proxy_balancerTag then
- proxy_node = nil
+ if node.preproxy_enabled == "1" and proxy_node_id then
+ local proxy_outbound_tag
+ proxy_outbound_tag, proxy_balancer_tag = gen_shunt_node(proxy_tag, proxy_node_id)
+ if proxy_balancer_tag then
+ local _node_id = proxy_node_id
+ proxy_nodes = {}
+ while _node_id do
+ _node = uci:get_all(appname, _node_id)
+ if not _node then break end
+ if _node.protocol ~= "_balancing" then
+ proxy_nodes[_node_id] = true
+ break
+ end
+ local _blc_nodes = _node.balancing_node
+ for i = 1, #_blc_nodes do proxy_nodes[_blc_nodes[i]] = true end
+ _node_id = _node.fallback_node
+ end
+ else
+ proxy_tag = proxy_outbound_tag
end
end
--default_node
local default_node_id = node.default_node or "_direct"
- local default_outboundTag, default_balancerTag = gen_shunt_node("default", default_node_id)
+ local default_outbound_tag, default_balancer_tag = gen_shunt_node("default", default_node_id)
--shunt rule
uci:foreach(appname, "shunt_rules", function(e)
- local outboundTag, balancerTag = gen_shunt_node(e[".name"])
- if outboundTag or balancerTag and e.remarks then
- if outboundTag == "default" then
- outboundTag = default_outboundTag
- balancerTag = default_balancerTag
+ local outbound_tag, balancer_tag = gen_shunt_node(e[".name"])
+ if outbound_tag or balancer_tag and e.remarks then
+ if outbound_tag == "default" then
+ outbound_tag = default_outbound_tag
+ balancer_tag = default_balancer_tag
end
local protocols = nil
if e["protocol"] and e["protocol"] ~= "" then
@@ -924,20 +923,20 @@ function gen_config(var)
table.insert(protocols, w)
end)
end
- local inboundTag = nil
+ local inbound_tag = nil
if e["inbound"] and e["inbound"] ~= "" then
- inboundTag = {}
+ inbound_tag = {}
if e["inbound"]:find("tproxy") then
if tcp_redir_port then
- table.insert(inboundTag, "tcp_redir")
+ table.insert(inbound_tag, "tcp_redir")
end
if udp_redir_port then
- table.insert(inboundTag, "udp_redir")
+ table.insert(inbound_tag, "udp_redir")
end
end
if e["inbound"]:find("socks") then
if local_socks_port then
- table.insert(inboundTag, "socks-in")
+ table.insert(inbound_tag, "socks-in")
end
end
end
@@ -965,9 +964,9 @@ function gen_config(var)
local rule = {
_flag = e.remarks,
type = "field",
- inboundTag = inboundTag,
- outboundTag = outboundTag,
- balancerTag = balancerTag,
+ inboundTag = inbound_tag,
+ outboundTag = outbound_tag,
+ balancerTag = balancer_tag,
network = e["network"] or "tcp,udp",
source = source,
sourcePort = nil,
@@ -992,11 +991,11 @@ function gen_config(var)
end
end)
- if default_outboundTag or default_balancerTag then
+ if default_outbound_tag or default_balancer_tag then
table.insert(rules, {
type = "field",
- outboundTag = default_outboundTag,
- balancerTag = default_balancerTag,
+ outboundTag = default_outbound_tag,
+ balancerTag = default_balancer_tag,
network = "tcp,udp"
})
end
@@ -1009,9 +1008,9 @@ function gen_config(var)
}
elseif node.protocol == "_balancing" then
if node.balancing_node then
- local valid = gen_balancer(node)
- if valid then
- table.insert(rules, { type = "field", network = "tcp,udp", balancerTag = get_balancer_tag(node_id) })
+ local balancer_tag = gen_balancer(node)
+ if balancer_tag then
+ table.insert(rules, { type = "field", network = "tcp,udp", balancerTag = balancer_tag })
end
routing = {
balancers = balancers,
@@ -1114,11 +1113,11 @@ function gen_config(var)
end
end
]]--
- local dns_outboundTag = "direct"
+ local dns_outbound_tag = "direct"
if dns_socks_address and dns_socks_port then
- dns_outboundTag = "out"
+ dns_outbound_tag = "out"
table.insert(outbounds, 1, {
- tag = dns_outboundTag,
+ tag = dns_outbound_tag,
protocol = "socks",
streamSettings = {
network = "tcp",
@@ -1138,10 +1137,10 @@ function gen_config(var)
})
else
if node_id and tcp_redir_port then
- dns_outboundTag = node_id
+ dns_outbound_tag = node_id
local node = uci:get_all(appname, node_id)
if node.protocol == "_shunt" then
- dns_outboundTag = "default"
+ dns_outbound_tag = "default"
end
end
end
@@ -1163,7 +1162,7 @@ function gen_config(var)
tag = "dns-out",
protocol = "dns",
proxySettings = {
- tag = dns_outboundTag
+ tag = dns_outbound_tag
},
settings = {
address = remote_dns_tcp_server,
@@ -1190,7 +1189,7 @@ function gen_config(var)
remote_dns_tcp_server
},
port = tonumber(remote_dns_tcp_port),
- outboundTag = dns_outboundTag
+ outboundTag = dns_outbound_tag
})
if _remote_dns_host then
table.insert(rules, {
@@ -1202,7 +1201,7 @@ function gen_config(var)
_remote_dns_host
},
port = tonumber(remote_dns_doh_port),
- outboundTag = dns_outboundTag
+ outboundTag = dns_outbound_tag
})
end
if remote_dns_doh_ip then
@@ -1215,7 +1214,7 @@ function gen_config(var)
remote_dns_doh_ip
},
port = tonumber(remote_dns_doh_port),
- outboundTag = dns_outboundTag
+ outboundTag = dns_outbound_tag
})
end
diff --git a/small/luci-app-passwall/root/usr/share/passwall/app.sh b/small/luci-app-passwall/root/usr/share/passwall/app.sh
index dfd9870c2a..5602597ca5 100755
--- a/small/luci-app-passwall/root/usr/share/passwall/app.sh
+++ b/small/luci-app-passwall/root/usr/share/passwall/app.sh
@@ -327,7 +327,7 @@ run_ipt2socks() {
run_singbox() {
local flag type node tcp_redir_port udp_redir_port socks_address socks_port socks_username socks_password http_address http_port http_username http_password
local dns_listen_port direct_dns_port direct_dns_udp_server remote_dns_protocol remote_dns_udp_server remote_dns_tcp_server remote_dns_doh remote_fakedns remote_dns_query_strategy dns_cache dns_socks_address dns_socks_port
- local loglevel log_file config_file
+ local loglevel log_file config_file server_host server_port
local _extra_param=""
eval_set_val $@
[ -z "$type" ] && {
@@ -353,6 +353,8 @@ run_singbox() {
[ -n "$flag" ] && _extra_param="${_extra_param} -flag $flag"
[ -n "$node" ] && _extra_param="${_extra_param} -node $node"
+ [ -n "$server_host" ] && _extra_param="${_extra_param} -server_host $server_host"
+ [ -n "$server_port" ] && _extra_param="${_extra_param} -server_port $server_port"
[ -n "$tcp_redir_port" ] && _extra_param="${_extra_param} -tcp_redir_port $tcp_redir_port"
[ -n "$udp_redir_port" ] && _extra_param="${_extra_param} -udp_redir_port $udp_redir_port"
[ -n "$socks_address" ] && _extra_param="${_extra_param} -local_socks_address $socks_address"
@@ -364,7 +366,7 @@ run_singbox() {
[ -n "$dns_socks_address" ] && [ -n "$dns_socks_port" ] && _extra_param="${_extra_param} -dns_socks_address ${dns_socks_address} -dns_socks_port ${dns_socks_port}"
[ -n "$dns_listen_port" ] && _extra_param="${_extra_param} -dns_listen_port ${dns_listen_port}"
[ -n "$dns_cache" ] && _extra_param="${_extra_param} -dns_cache ${dns_cache}"
-
+
local local_dns=$(echo -n $(echo "${LOCAL_DNS}" | sed "s/,/\n/g" | head -n1) | tr " " ",")
[ -z "$direct_dns_udp_server" ] && direct_dns_udp_server=$(echo ${local_dns} | awk -F '#' '{print $1}')
[ -z "$direct_dns_port" ] && direct_dns_port=$(echo ${local_dns} | awk -F '#' '{print $2}')
@@ -404,7 +406,7 @@ run_singbox() {
run_xray() {
local flag type node tcp_redir_port udp_redir_port socks_address socks_port socks_username socks_password http_address http_port http_username http_password
local dns_listen_port remote_dns_udp_server remote_dns_tcp_server remote_dns_doh dns_client_ip dns_query_strategy dns_cache dns_socks_address dns_socks_port
- local loglevel log_file config_file
+ local loglevel log_file config_file server_host server_port
local _extra_param=""
eval_set_val $@
[ -z "$type" ] && {
@@ -419,6 +421,8 @@ run_xray() {
[ -z "$loglevel" ] && local loglevel=$(config_t_get global loglevel "warning")
[ -n "$flag" ] && _extra_param="${_extra_param} -flag $flag"
[ -n "$node" ] && _extra_param="${_extra_param} -node $node"
+ [ -n "$server_host" ] && _extra_param="${_extra_param} -server_host $server_host"
+ [ -n "$server_port" ] && _extra_param="${_extra_param} -server_port $server_port"
[ -n "$tcp_redir_port" ] && _extra_param="${_extra_param} -tcp_redir_port $tcp_redir_port"
[ -n "$udp_redir_port" ] && _extra_param="${_extra_param} -udp_redir_port $udp_redir_port"
[ -n "$socks_address" ] && _extra_param="${_extra_param} -local_socks_address $socks_address"
@@ -478,7 +482,7 @@ run_dns2socks() {
run_chinadns_ng() {
local _listen_port _dns_china _dns_trust _chnlist _gfwlist _no_ipv6_rules _log_path _no_logic_log
eval_set_val $@
-
+
local _LOG_FILE=$LOG_FILE
[ -n "$_no_logic_log" ] && LOG_FILE="/dev/null"
@@ -595,7 +599,7 @@ run_socks() {
config_file=$(echo $config_file | sed "s/SOCKS/HTTP_SOCKS/g")
local _args="http_port=$http_port"
}
- [ -n "$relay_port" ] && _args="${_args} -server_host $server_host -server_port $port"
+ [ -n "$relay_port" ] && _args="${_args} server_host=$server_host server_port=$port"
run_singbox flag=$flag node=$node socks_port=$socks_port config_file=$config_file log_file=$log_file ${_args}
;;
xray)
@@ -604,7 +608,7 @@ run_socks() {
config_file=$(echo $config_file | sed "s/SOCKS/HTTP_SOCKS/g")
local _args="http_port=$http_port"
}
- [ -n "$relay_port" ] && _args="${_args} -server_host $server_host -server_port $port"
+ [ -n "$relay_port" ] && _args="${_args} server_host=$server_host server_port=$port"
run_xray flag=$flag node=$node socks_port=$socks_port config_file=$config_file log_file=$log_file ${_args}
;;
trojan*)
@@ -646,7 +650,7 @@ run_socks() {
ln_run "$(first_type tuic-client)" "tuic-client" $log_file -c "$config_file"
;;
esac
-
+
eval node_${node}_socks_port=$socks_port
# http to socks
@@ -1382,7 +1386,7 @@ acl_app() {
[ "$dns_mode" = "sing-box" ] && {
[ "$v2ray_dns_mode" = "doh" ] && remote_dns=${remote_dns_doh:-https://1.1.1.1/dns-query}
}
-
+
[ "${use_global_config}" = "1" ] && {
tcp_node="default"
udp_node="default"
diff --git a/suyu/README.md b/suyu/README.md
index fc456c50f5..5baba68ea9 100644
--- a/suyu/README.md
+++ b/suyu/README.md
@@ -6,7 +6,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
**Note**: We do not support or condone piracy in any form. In order to use suyu, you'll need keys from your real Switch system, and games which you have legally obtained and paid for. We do not intend to make money or profit from this project.
-We're in need of developers. Please join our Matrix below if you want to contribute!
+We're in need of developers. Please join our chat below if you want to contribute!
This repo is based on Yuzu EA 4176.
@@ -25,7 +25,7 @@ It is written in C++ with portability in mind, and we're actively working on bui
- Matrix |
+ Chat |
Status |
Development |
Downloads |
@@ -48,7 +48,7 @@ We currently have builds over at the [Releases](https://git.suyu.dev/suyu/suyu/r
This project is completely free and open source, and anyone can contribute to help improve suyu.
-Most of the development happens on GitLab. For development discussion, please join us on [Matrix](https://chat.suyu.dev).
+Most of the development happens on GitLab. For development discussion, please join us in our [Chat](https://chat.suyu.dev).
If you want to contribute, please take a look at the [Contributor's Guide](https://git.suyu.dev/suyu/suyu/wiki/Contributing) and [Developer Information](https://git.suyu.dev/suyu/suyu/wiki/Developer-Information).
You can also contact any of the developers on Discord to learn more about the current state of suyu.
@@ -77,7 +77,7 @@ We have official builds [here.](https://git.suyu.dev/suyu/suyu/releases) If any
## Support
-If you have any questions, don't hesitate to ask us on [Matrix](https://chat.suyu.dev). We don't bite!
+If you have any questions, don't hesitate to ask us in our [chat](https://chat.suyu.dev). We don't bite!
## License
diff --git a/v2rayng/V2rayNG/app/src/main/kotlin/com/v2ray/ang/AppConfig.kt b/v2rayng/V2rayNG/app/src/main/kotlin/com/v2ray/ang/AppConfig.kt
index 0d96ac0238..7b099a48eb 100644
--- a/v2rayng/V2rayNG/app/src/main/kotlin/com/v2ray/ang/AppConfig.kt
+++ b/v2rayng/V2rayNG/app/src/main/kotlin/com/v2ray/ang/AppConfig.kt
@@ -63,7 +63,7 @@ object AppConfig {
const val TASKER_EXTRA_BUNDLE_GUID = "tasker_extra_bundle_guid"
const val TASKER_DEFAULT_GUID = "Default"
- const val TAG_AGENT = "proxy"
+ const val TAG_PROXY = "proxy"
const val TAG_DIRECT = "direct"
const val TAG_BLOCKED = "block"
const val TAG_FRAGMENT = "fragment"
@@ -78,8 +78,9 @@ object AppConfig {
const val promotionUrl = "aHR0cHM6Ly85LjIzNDQ1Ni54eXovYWJjLmh0bWw="
const val geoUrl = "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/"
- const val DNS_AGENT = "1.1.1.1"
+ const val DNS_PROXY = "1.1.1.1"
const val DNS_DIRECT = "223.5.5.5"
+ const val DNS_VPN = "1.1.1.1"
const val PORT_LOCAL_DNS = "10853"
const val PORT_SOCKS = "10808"
diff --git a/v2rayng/V2rayNG/app/src/main/kotlin/com/v2ray/ang/dto/ServerConfig.kt b/v2rayng/V2rayNG/app/src/main/kotlin/com/v2ray/ang/dto/ServerConfig.kt
index b4cd3e164e..1999c9770c 100644
--- a/v2rayng/V2rayNG/app/src/main/kotlin/com/v2ray/ang/dto/ServerConfig.kt
+++ b/v2rayng/V2rayNG/app/src/main/kotlin/com/v2ray/ang/dto/ServerConfig.kt
@@ -1,6 +1,6 @@
package com.v2ray.ang.dto
-import com.v2ray.ang.AppConfig.TAG_AGENT
+import com.v2ray.ang.AppConfig.TAG_PROXY
import com.v2ray.ang.AppConfig.TAG_BLOCKED
import com.v2ray.ang.AppConfig.TAG_DIRECT
import com.v2ray.ang.util.Utils
@@ -58,7 +58,7 @@ data class ServerConfig(
fun getAllOutboundTags(): MutableList {
if (configType != EConfigType.CUSTOM) {
- return mutableListOf(TAG_AGENT, TAG_DIRECT, TAG_BLOCKED)
+ return mutableListOf(TAG_PROXY, TAG_DIRECT, TAG_BLOCKED)
}
fullConfig?.let { config ->
return config.outbounds.map { it.tag }.toMutableList()
diff --git a/v2rayng/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/RoutingSettingsFragment.kt b/v2rayng/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/RoutingSettingsFragment.kt
index 88f65d4169..d4f772347a 100644
--- a/v2rayng/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/RoutingSettingsFragment.kt
+++ b/v2rayng/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/RoutingSettingsFragment.kt
@@ -127,7 +127,7 @@ class RoutingSettingsFragment : Fragment() {
var tag = ""
when (requireArguments().getString(routing_arg)) {
AppConfig.PREF_V2RAY_ROUTING_AGENT -> {
- tag = AppConfig.TAG_AGENT
+ tag = AppConfig.TAG_PROXY
}
AppConfig.PREF_V2RAY_ROUTING_DIRECT -> {
tag = AppConfig.TAG_DIRECT
diff --git a/v2rayng/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/SettingsActivity.kt b/v2rayng/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/SettingsActivity.kt
index 8bb9bea269..470540b5f9 100644
--- a/v2rayng/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/SettingsActivity.kt
+++ b/v2rayng/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/SettingsActivity.kt
@@ -120,7 +120,7 @@ class SettingsActivity : BaseActivity() {
remoteDns?.setOnPreferenceChangeListener { _, any ->
// remoteDns.summary = any as String
val nval = any as String
- remoteDns?.summary = if (nval == "") AppConfig.DNS_AGENT else nval
+ remoteDns?.summary = if (nval == "") AppConfig.DNS_PROXY else nval
true
}
domesticDns?.setOnPreferenceChangeListener { _, any ->
@@ -213,7 +213,7 @@ class SettingsActivity : BaseActivity() {
autoUpdateInterval?.isEnabled = defaultSharedPreferences.getBoolean(AppConfig.SUBSCRIPTION_AUTO_UPDATE, false)
if (TextUtils.isEmpty(remoteDnsString)) {
- remoteDnsString = AppConfig.DNS_AGENT
+ remoteDnsString = AppConfig.DNS_PROXY
}
if (TextUtils.isEmpty(domesticDns?.summary)) {
domesticDns?.summary = AppConfig.DNS_DIRECT
diff --git a/v2rayng/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/UserAssetActivity.kt b/v2rayng/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/UserAssetActivity.kt
index dfdbfcf196..e007fc7e37 100644
--- a/v2rayng/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/UserAssetActivity.kt
+++ b/v2rayng/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/UserAssetActivity.kt
@@ -177,7 +177,10 @@ class UserAssetActivity : BaseActivity() {
assets.forEach {
//toast(getString(R.string.msg_downloading_content) + it)
lifecycleScope.launch(Dispatchers.IO) {
- val result = downloadGeo(it.second, 60000, httpPort)
+ var result = downloadGeo(it.second, 60000, httpPort)
+ if (!result) {
+ result = downloadGeo(it.second, 60000, 0)
+ }
launch(Dispatchers.Main) {
if (result) {
toast(getString(R.string.toast_success) + " " + it.second.remarks)
@@ -197,12 +200,16 @@ class UserAssetActivity : BaseActivity() {
//Log.d(AppConfig.ANG_PACKAGE, url)
try {
- conn = URL(item.url).openConnection(
- Proxy(
- Proxy.Type.HTTP,
- InetSocketAddress("127.0.0.1", httpPort)
- )
- ) as HttpURLConnection
+ conn = if (httpPort == 0) {
+ URL(item.url).openConnection() as HttpURLConnection
+ } else {
+ URL(item.url).openConnection(
+ Proxy(
+ Proxy.Type.HTTP,
+ InetSocketAddress("127.0.0.1", httpPort)
+ )
+ ) as HttpURLConnection
+ }
conn.connectTimeout = timeout
conn.readTimeout = timeout
val inputStream = conn.inputStream
@@ -224,13 +231,14 @@ class UserAssetActivity : BaseActivity() {
}
private fun addBuiltInGeoItems(assets: List>): List> {
val list = mutableListOf>()
- builtInGeoFiles.forEach {
- list.add(Utils.getUuid() to AssetUrlItem(
- it,
- AppConfig.geoUrl + it
- )
- )
- }
+ builtInGeoFiles
+ .filter { geoFile -> assets.none { it.second.remarks == geoFile } }
+ .forEach {
+ list.add(Utils.getUuid() to AssetUrlItem(
+ it,
+ AppConfig.geoUrl + it
+ ))
+ }
return list + assets
}
@@ -263,7 +271,7 @@ class UserAssetActivity : BaseActivity() {
holder.itemUserAssetBinding.assetProperties.text = getString(R.string.msg_file_not_found)
}
- if (item.second.remarks in builtInGeoFiles) {
+ if (item.second.remarks in builtInGeoFiles && item.second.url == AppConfig.geoUrl + item.second.remarks) {
holder.itemUserAssetBinding.layoutEdit.visibility = GONE
holder.itemUserAssetBinding.layoutRemove.visibility = GONE
} else {
diff --git a/v2rayng/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/Utils.kt b/v2rayng/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/Utils.kt
index f2639db79f..4715363396 100644
--- a/v2rayng/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/Utils.kt
+++ b/v2rayng/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/Utils.kt
@@ -139,10 +139,10 @@ object Utils {
* get remote dns servers from preference
*/
fun getRemoteDnsServers(): List {
- val remoteDns = settingsStorage?.decodeString(AppConfig.PREF_REMOTE_DNS) ?: AppConfig.DNS_AGENT
+ val remoteDns = settingsStorage?.decodeString(AppConfig.PREF_REMOTE_DNS) ?: AppConfig.DNS_PROXY
val ret = remoteDns.split(",").filter { isPureIpAddress(it) || isCoreDNSAddress(it) }
if (ret.isEmpty()) {
- return listOf(AppConfig.DNS_AGENT)
+ return listOf(AppConfig.DNS_PROXY)
}
return ret
}
@@ -150,7 +150,7 @@ object Utils {
fun getVpnDnsServers(): List {
val vpnDns = settingsStorage?.decodeString(AppConfig.PREF_VPN_DNS)
?: settingsStorage?.decodeString(AppConfig.PREF_REMOTE_DNS)
- ?: AppConfig.DNS_AGENT
+ ?: AppConfig.DNS_VPN
return vpnDns.split(",").filter { isPureIpAddress(it) }
// allow empty, in that case dns will use system default
}
@@ -160,7 +160,7 @@ object Utils {
*/
fun getDomesticDnsServers(): List {
val domesticDns = settingsStorage?.decodeString(AppConfig.PREF_DOMESTIC_DNS) ?: AppConfig.DNS_DIRECT
- val ret = domesticDns.split(",").filter { isPureIpAddress(it) || isCoreDNSAddress(it) }
+ val ret = domesticDns.split(",").filter { isPureIpAddress(it) }
if (ret.isEmpty()) {
return listOf(AppConfig.DNS_DIRECT)
}
diff --git a/v2rayng/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/V2rayConfigUtil.kt b/v2rayng/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/V2rayConfigUtil.kt
index 2c4911c2b3..a549610b22 100644
--- a/v2rayng/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/V2rayConfigUtil.kt
+++ b/v2rayng/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/V2rayConfigUtil.kt
@@ -175,7 +175,7 @@ object V2rayConfigUtil {
try {
routingUserRule(
settingsStorage?.decodeString(AppConfig.PREF_V2RAY_ROUTING_AGENT)
- ?: "", AppConfig.TAG_AGENT, v2rayConfig
+ ?: "", AppConfig.TAG_PROXY, v2rayConfig
)
routingUserRule(
settingsStorage?.decodeString(AppConfig.PREF_V2RAY_ROUTING_DIRECT)
@@ -195,7 +195,7 @@ object V2rayConfigUtil {
// Hardcode googleapis.cn
val googleapisRoute = V2rayConfig.RoutingBean.RulesBean(
- outboundTag = AppConfig.TAG_AGENT,
+ outboundTag = AppConfig.TAG_PROXY,
domain = arrayListOf("domain:googleapis.cn")
)
@@ -225,6 +225,15 @@ object V2rayConfigUtil {
v2rayConfig.routing.rules.add(globalDirect)
}
}
+
+ if(routingMode != ERoutingMode.GLOBAL_DIRECT.value) {
+ v2rayConfig.routing.rules.add(
+ V2rayConfig.RoutingBean.RulesBean(
+ outboundTag = AppConfig.TAG_PROXY,
+ port = "0-65535"
+ ))
+ }
+
} catch (e: Exception) {
e.printStackTrace()
return false
@@ -340,7 +349,7 @@ object V2rayConfigUtil {
val remoteDns = Utils.getRemoteDnsServers()
if (v2rayConfig.inbounds.none { e -> e.protocol == "dokodemo-door" && e.tag == "dns-in" }) {
val dnsInboundSettings = V2rayConfig.InboundBean.InSettingsBean(
- address = if (Utils.isPureIpAddress(remoteDns.first())) remoteDns.first() else "1.1.1.1",
+ address = if (Utils.isPureIpAddress(remoteDns.first())) remoteDns.first() else AppConfig.DNS_PROXY,
port = 53,
network = "tcp,udp"
)
@@ -477,7 +486,7 @@ object V2rayConfigUtil {
if (Utils.isPureIpAddress(remoteDns.first())) {
v2rayConfig.routing.rules.add(
0, V2rayConfig.RoutingBean.RulesBean(
- outboundTag = AppConfig.TAG_AGENT,
+ outboundTag = AppConfig.TAG_PROXY,
port = "53",
ip = arrayListOf(remoteDns.first()),
domain = null
diff --git a/v2rayng/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml b/v2rayng/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml
index bb6add7d18..a517af0a47 100644
--- a/v2rayng/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml
+++ b/v2rayng/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml
@@ -135,7 +135,7 @@
预定义规则
自定义规则
- 远程DNS (可选)
+ 远程DNS (udp/tcp/https/quic)(可选)
DNS
VPN DNS (仅支持 IPv4/v6)
diff --git a/v2rayng/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml b/v2rayng/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml
index 86a56169e3..22c82d6ccd 100644
--- a/v2rayng/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml
+++ b/v2rayng/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml
@@ -135,7 +135,7 @@
轉送模式
自訂轉送
- 遠端 DNS (可選)
+ 遠端DNS (udp/tcp/https/quic)(可選)
DNS
VPN DNS (僅支援 IPv4/v6)
diff --git a/v2rayng/V2rayNG/app/src/main/res/values/strings.xml b/v2rayng/V2rayNG/app/src/main/res/values/strings.xml
index e8facceebc..3bfd95d0f9 100644
--- a/v2rayng/V2rayNG/app/src/main/res/values/strings.xml
+++ b/v2rayng/V2rayNG/app/src/main/res/values/strings.xml
@@ -148,7 +148,7 @@
Predefined rules
Custom rules
- Remote DNS (Optional)
+ Remote DNS (udp/tcp/https/quic)(Optional)
DNS
VPN DNS (only IPv4/v6)
diff --git a/xray-core/go.mod b/xray-core/go.mod
index cf63cbfd51..807dec1f1b 100644
--- a/xray-core/go.mod
+++ b/xray-core/go.mod
@@ -11,7 +11,7 @@ require (
github.com/pelletier/go-toml v1.9.5
github.com/pires/go-proxyproto v0.7.0
github.com/quic-go/quic-go v0.42.0
- github.com/refraction-networking/utls v1.6.3
+ github.com/refraction-networking/utls v1.6.4
github.com/sagernet/sing v0.3.8
github.com/sagernet/sing-shadowsocks v0.2.6
github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb
diff --git a/xray-core/go.sum b/xray-core/go.sum
index 4318384827..64362f4ed2 100644
--- a/xray-core/go.sum
+++ b/xray-core/go.sum
@@ -114,8 +114,8 @@ github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7q
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/quic-go/quic-go v0.42.0 h1:uSfdap0eveIl8KXnipv9K7nlwZ5IqLlYOpJ58u5utpM=
github.com/quic-go/quic-go v0.42.0/go.mod h1:132kz4kL3F9vxhW3CtQJLDVwcFe5wdWeJXXijhsO57M=
-github.com/refraction-networking/utls v1.6.3 h1:MFOfRN35sSx6K5AZNIoESsBuBxS2LCgRilRIdHb6fDc=
-github.com/refraction-networking/utls v1.6.3/go.mod h1:yil9+7qSl+gBwJqztoQseO6Pr3h62pQoY1lXiNR/FPs=
+github.com/refraction-networking/utls v1.6.4 h1:aeynTroaYn7y+mFtqv8D0bQ4bw0y9nJHneGxJ7lvRDM=
+github.com/refraction-networking/utls v1.6.4/go.mod h1:2VL2xfiqgFAZtJKeUTlf+PSYFs3Eu7km0gCtXJ3m8zs=
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg=
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
diff --git a/yass/.github/workflows/clang-tidy.yml b/yass/.github/workflows/clang-tidy.yml
index 8a29cb9d8f..19edf4ce2e 100644
--- a/yass/.github/workflows/clang-tidy.yml
+++ b/yass/.github/workflows/clang-tidy.yml
@@ -18,7 +18,7 @@ on:
schedule:
- cron: '0 16 * * *'
env:
- CACHE_EPOCH: 124-1
+ CACHE_EPOCH: 125-1
GOPROXY: direct
jobs:
win-clang-tidy:
diff --git a/yass/.github/workflows/compiler.yml b/yass/.github/workflows/compiler.yml
index 62956ea8c0..83337b33f6 100644
--- a/yass/.github/workflows/compiler.yml
+++ b/yass/.github/workflows/compiler.yml
@@ -33,7 +33,7 @@ concurrency:
group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }}
env:
- CACHE_EPOCH: 124-1
+ CACHE_EPOCH: 125-1
GOPROXY: direct
jobs:
win-compiler-compatible-2022:
diff --git a/yass/.github/workflows/releases-android-binary.yml b/yass/.github/workflows/releases-android-binary.yml
index 5b7909cdd9..b4717851ef 100644
--- a/yass/.github/workflows/releases-android-binary.yml
+++ b/yass/.github/workflows/releases-android-binary.yml
@@ -35,7 +35,7 @@ concurrency:
group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }}
env:
- CACHE_EPOCH: 124-1
+ CACHE_EPOCH: 125-1
GOPROXY: direct
jobs:
android-binary-release:
diff --git a/yass/.github/workflows/releases-deb.yml b/yass/.github/workflows/releases-deb.yml
index 89ff18d105..ba7d132686 100644
--- a/yass/.github/workflows/releases-deb.yml
+++ b/yass/.github/workflows/releases-deb.yml
@@ -35,7 +35,7 @@ concurrency:
group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }}
env:
- CACHE_EPOCH: 124-1
+ CACHE_EPOCH: 125-1
GOPROXY: direct
DH_QUIET: 1
jobs:
@@ -169,7 +169,7 @@ jobs:
path: |
/etc/schroot/chroot.d
/var/lib/schroot/chroots
- key: ${{ runner.os }}-22.04-schroot-${{ env.HOST_DISTRO }}-${{ env.HOST_ARCH }}-v1
+ key: ${{ runner.os }}-22.04-schroot-${{ env.HOST_DISTRO }}-${{ env.HOST_ARCH }}-v2
- name: Fix schroot permissions (restore root permissions)
run: |
sudo chown -R root:root /etc/schroot/chroot.d /var/lib/schroot/chroots
@@ -205,7 +205,7 @@ jobs:
if: ${{ steps.schroot-cache.outputs.cache-hit != 'true' }}
run: |
sudo schroot --chroot "source:${{ env.HOST_DISTRO }}-${{ env.BUILD_ARCH }}-${{ env.HOST_ARCH }}" --user root -- \
- apt-get install -y fakeroot advancecomp apt-utils file build-essential pkg-config debhelper lockfile-progs optipng pkg-config tzdata ucf
+ apt-get install -y fakeroot advancecomp apt-utils file build-essential pkg-config debhelper lockfile-progs optipng tzdata ucf
- name: Populate sysroot (amd64 runtime for clang)
if: ${{ steps.schroot-cache.outputs.cache-hit != 'true' && env.HOST_ARCH == 'i386' }}
run: |
@@ -267,12 +267,17 @@ jobs:
if: ${{ steps.schroot-cache.outputs.cache-hit != 'true' }}
run: |
sudo schroot --chroot "source:${{ env.HOST_DISTRO }}-${{ env.BUILD_ARCH }}-${{ env.HOST_ARCH }}" --user root -- \
- apt-get install -y perl gcc g++ ninja-build debhelper
+ apt-get install -y perl gcc g++ ninja-build
+ - name: Populate depedencie (zlib)
+ if: ${{ steps.schroot-cache.outputs.cache-hit != 'true' }}
+ run: |
+ sudo schroot --chroot "source:${{ env.HOST_DISTRO }}-${{ env.BUILD_ARCH }}-${{ env.HOST_ARCH }}" --user root -- \
+ apt-get install -y zlib1g-dev:${{ env.HOST_ARCH }}
- name: Populate depedencie (gui, exclude some arches)
if: ${{ steps.schroot-cache.outputs.cache-hit != 'true' && env.HOST_ARCH != 'armel' && env.HOST_ARCH != 'mipsel' && env.HOST_ARCH != 'mips64el' && env.HOST_ARCH != 'riscv64' }}
run: |
sudo schroot --chroot "source:${{ env.HOST_DISTRO }}-${{ env.BUILD_ARCH }}-${{ env.HOST_ARCH }}" --user root -- \
- apt-get install -y pkg-config libglib2.0-dev:${{ env.HOST_ARCH }} libgtk-3-dev:${{ env.HOST_ARCH }}
+ apt-get install -y libglib2.0-dev:${{ env.HOST_ARCH }} libgtk-3-dev:${{ env.HOST_ARCH }}
- name: Populate depedencie (curl, for test purpose, exclude some arches)
if: ${{ steps.schroot-cache.outputs.cache-hit != 'true' && env.HOST_ARCH != 'armel' && env.HOST_ARCH != 'mipsel' && env.HOST_ARCH != 'mips64el' && env.HOST_ARCH != 'riscv64' }}
run: |
diff --git a/yass/.github/workflows/releases-freebsd-binary.yml b/yass/.github/workflows/releases-freebsd-binary.yml
index 92f521cdb7..2ec6a925a0 100644
--- a/yass/.github/workflows/releases-freebsd-binary.yml
+++ b/yass/.github/workflows/releases-freebsd-binary.yml
@@ -35,7 +35,7 @@ concurrency:
group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }}
env:
- CACHE_EPOCH: 124-1
+ CACHE_EPOCH: 125-1
GOPROXY: direct
jobs:
freebsd-binary-release:
diff --git a/yass/.github/workflows/releases-ios.yml b/yass/.github/workflows/releases-ios.yml
index 7920456475..3051bba13a 100644
--- a/yass/.github/workflows/releases-ios.yml
+++ b/yass/.github/workflows/releases-ios.yml
@@ -21,7 +21,7 @@ concurrency:
group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }}
env:
- CACHE_EPOCH: 124-1
+ CACHE_EPOCH: 125-1
GOPROXY: direct
jobs:
ios-simulator-release:
diff --git a/yass/.github/workflows/releases-linux-binary.yml b/yass/.github/workflows/releases-linux-binary.yml
index 8ab1b92a2e..cc55a3c9db 100644
--- a/yass/.github/workflows/releases-linux-binary.yml
+++ b/yass/.github/workflows/releases-linux-binary.yml
@@ -35,7 +35,7 @@ concurrency:
group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }}
env:
- CACHE_EPOCH: 124-1
+ CACHE_EPOCH: 125-1
GOPROXY: direct
jobs:
linux-binary-release:
diff --git a/yass/.github/workflows/releases-macos.yml b/yass/.github/workflows/releases-macos.yml
index 7714b21c93..1b467c5aa2 100644
--- a/yass/.github/workflows/releases-macos.yml
+++ b/yass/.github/workflows/releases-macos.yml
@@ -35,7 +35,7 @@ concurrency:
group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }}
env:
- CACHE_EPOCH: 124-1
+ CACHE_EPOCH: 125-1
GOPROXY: direct
jobs:
mac-release:
diff --git a/yass/.github/workflows/releases-mingw-new.yml b/yass/.github/workflows/releases-mingw-new.yml
index b462ae8337..36799d24fa 100644
--- a/yass/.github/workflows/releases-mingw-new.yml
+++ b/yass/.github/workflows/releases-mingw-new.yml
@@ -35,7 +35,7 @@ concurrency:
group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }}
env:
- CACHE_EPOCH: 124-1
+ CACHE_EPOCH: 125-1
GOPROXY: direct
jobs:
mingw64-release:
diff --git a/yass/.github/workflows/releases-mingw.yml b/yass/.github/workflows/releases-mingw.yml
index b9d7aadaf5..5685f2f071 100644
--- a/yass/.github/workflows/releases-mingw.yml
+++ b/yass/.github/workflows/releases-mingw.yml
@@ -18,7 +18,7 @@ on:
schedule:
- cron: '0 16 * * *'
env:
- CACHE_EPOCH: 124-1
+ CACHE_EPOCH: 125-1
GOPROXY: direct
jobs:
mingw64-release:
diff --git a/yass/.github/workflows/releases-openwrt-binary.yml b/yass/.github/workflows/releases-openwrt-binary.yml
index f36a979cd4..e5c40ca14d 100644
--- a/yass/.github/workflows/releases-openwrt-binary.yml
+++ b/yass/.github/workflows/releases-openwrt-binary.yml
@@ -35,7 +35,7 @@ concurrency:
group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }}
env:
- CACHE_EPOCH: 124-1
+ CACHE_EPOCH: 125-1
GOPROXY: direct
jobs:
openwrt-binary-release:
diff --git a/yass/.github/workflows/releases-rpm.yml b/yass/.github/workflows/releases-rpm.yml
index 5d8cd6619b..5bd8677d94 100644
--- a/yass/.github/workflows/releases-rpm.yml
+++ b/yass/.github/workflows/releases-rpm.yml
@@ -35,7 +35,7 @@ concurrency:
group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }}
env:
- CACHE_EPOCH: 124-1
+ CACHE_EPOCH: 125-1
GOPROXY: direct
jobs:
docker_publish:
diff --git a/yass/.github/workflows/releases-windows.yml b/yass/.github/workflows/releases-windows.yml
index 3c25e9083a..50b790977b 100644
--- a/yass/.github/workflows/releases-windows.yml
+++ b/yass/.github/workflows/releases-windows.yml
@@ -24,7 +24,7 @@ defaults:
run:
shell: cmd
env:
- CACHE_EPOCH: 124-1
+ CACHE_EPOCH: 125-1
GOPROXY: direct
jobs:
windows-release:
diff --git a/yass/.github/workflows/sanitizers.yml b/yass/.github/workflows/sanitizers.yml
index 8b1280750c..0367262e1c 100644
--- a/yass/.github/workflows/sanitizers.yml
+++ b/yass/.github/workflows/sanitizers.yml
@@ -18,7 +18,7 @@ on:
schedule:
- cron: '0 16 * * *'
env:
- CACHE_EPOCH: 124-1
+ CACHE_EPOCH: 125-1
GOPROXY: direct
jobs:
sanitizer-linux:
diff --git a/yass/CLANG_REVISION b/yass/CLANG_REVISION
index 8db9309009..b13fa5faac 100644
--- a/yass/CLANG_REVISION
+++ b/yass/CLANG_REVISION
@@ -1 +1 @@
-llvmorg-19-init-2941-ga0b3dbaf-22
\ No newline at end of file
+llvmorg-19-init-7229-g315c88c5-2
\ No newline at end of file
diff --git a/yass/debian/control b/yass/debian/control
index 3f2972049b..f43ddf4157 100644
--- a/yass/debian/control
+++ b/yass/debian/control
@@ -12,7 +12,8 @@ Build-Depends:
ninja-build:native,
debhelper (>= 9),
ca-certificates,
- pkg-config ,
+ pkg-config,
+ zlib1g-dev,
libglib2.0-dev ,
libgtk-3-dev
Rules-Requires-Root: no
diff --git a/yass/debian/rules b/yass/debian/rules
index 9fc22cf576..e855226fdb 100755
--- a/yass/debian/rules
+++ b/yass/debian/rules
@@ -56,6 +56,7 @@ ifneq ($(filter cross,$(DEB_BUILD_PROFILES)),)
override_dh_auto_configure: PKG_CONFIG = ${DEB_HOST_GNU_TYPE}-pkg-config
endif
+override_dh_auto_configure: CMAKE_OPTIONS += -DUSE_SYSTEM_ZLIB=on
override_dh_auto_configure: CMAKE_OPTIONS += -DCMAKE_SYSTEM_NAME=Linux -DCMAKE_SYSTEM_PROCESSOR=$(DEB_HOST_ARCH)
override_dh_auto_configure: CMAKE_OPTIONS += -DUSE_OLD_SYSTEMD_SERVICE=on
diff --git a/yass/src/win32/yass.cpp b/yass/src/win32/yass.cpp
index ff56f18f2e..52e0f3aaaf 100644
--- a/yass/src/win32/yass.cpp
+++ b/yass/src/win32/yass.cpp
@@ -53,6 +53,21 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
return -1;
}
+ // This function is primarily useful to applications that were linked with /SUBSYSTEM:WINDOWS,
+ // which implies to the operating system that a console is not needed
+ // before entering the program's main method.
+ if (AttachConsole(ATTACH_PARENT_PROCESS) != 0) {
+ FILE* unusedFile;
+ // Swap to the new out/err streams
+ freopen_s(&unusedFile, "CONOUT$", "w", stdout);
+ freopen_s(&unusedFile, "CONOUT$", "w", stderr);
+ std::cout.clear();
+ std::clog.clear();
+ std::cerr.clear();
+ fprintf(stderr, "attached to parent process\n");
+ fflush(stderr);
+ }
+
if (!SetUTF8Locale()) {
LOG(WARNING) << "Failed to set up utf-8 locale";
}
diff --git a/yass/third_party/README.md b/yass/third_party/README.md
new file mode 100644
index 0000000000..d417cc4c43
--- /dev/null
+++ b/yass/third_party/README.md
@@ -0,0 +1,6 @@
+# Update Zlib
+
+```
+rsync -aPvx ~/chromium/src/third_party/zlib .
+rm -f zlib/BUILD.gn zlib/OWNERS
+```
diff --git a/yass/third_party/abseil-cpp/CMake/AbseilDll.cmake b/yass/third_party/abseil-cpp/CMake/AbseilDll.cmake
index 4beafd7af2..47f3beebd1 100644
--- a/yass/third_party/abseil-cpp/CMake/AbseilDll.cmake
+++ b/yass/third_party/abseil-cpp/CMake/AbseilDll.cmake
@@ -68,9 +68,7 @@ set(ABSL_INTERNAL_DLL_FILES
"container/btree_set.h"
"container/fixed_array.h"
"container/flat_hash_map.h"
- "container/flat_hash_map.cc"
"container/flat_hash_set.h"
- "container/flat_hash_set.cc"
"container/inlined_vector.h"
"container/internal/btree.h"
"container/internal/btree_container.h"
@@ -93,9 +91,7 @@ set(ABSL_INTERNAL_DLL_FILES
"container/internal/raw_hash_set.h"
"container/internal/tracked.h"
"container/node_hash_map.h"
- "container/node_hash_map.cc"
"container/node_hash_set.h"
- "container/node_hash_set.cc"
"crc/crc32c.cc"
"crc/crc32c.h"
"crc/internal/cpu_detect.cc"
diff --git a/yass/third_party/abseil-cpp/absl/abseil.podspec.gen.py b/yass/third_party/abseil-cpp/absl/abseil.podspec.gen.py
index e567e8790a..cbf7cb423b 100755
--- a/yass/third_party/abseil-cpp/absl/abseil.podspec.gen.py
+++ b/yass/third_party/abseil-cpp/absl/abseil.podspec.gen.py
@@ -47,6 +47,11 @@ Pod::Spec.new do |s|
s.osx.deployment_target = '10.11'
s.tvos.deployment_target = '9.0'
s.watchos.deployment_target = '2.0'
+ s.subspec 'xcprivacy' do |ss|
+ ss.resource_bundles = {
+ ss.module_name => 'PrivacyInfo.xcprivacy',
+ }
+ end
"""
# Rule object representing the rule of Bazel BUILD.
@@ -191,6 +196,12 @@ def write_podspec_rule(f, rule, depth):
name = get_spec_name(dep.replace(":", "/"))
f.write("{indent}{var}.dependency '{dep}'\n".format(
indent=indent, var=spec_var, dep=name))
+ # Writes dependency to xcprivacy
+ f.write(
+ "{indent}{var}.dependency '{dep}'\n".format(
+ indent=indent, var=spec_var, dep="abseil/xcprivacy"
+ )
+ )
def write_indented_list(f, leading, values):
diff --git a/yass/third_party/abseil-cpp/absl/base/dynamic_annotations.h b/yass/third_party/abseil-cpp/absl/base/dynamic_annotations.h
index 7ba8912ea6..f18b5e0a8f 100644
--- a/yass/third_party/abseil-cpp/absl/base/dynamic_annotations.h
+++ b/yass/third_party/abseil-cpp/absl/base/dynamic_annotations.h
@@ -252,25 +252,9 @@ ABSL_INTERNAL_END_EXTERN_C
#else // !defined(ABSL_HAVE_MEMORY_SANITIZER)
-// TODO(rogeeff): remove this branch
-#ifdef ABSL_HAVE_THREAD_SANITIZER
-#define ABSL_ANNOTATE_MEMORY_IS_INITIALIZED(address, size) \
- do { \
- (void)(address); \
- (void)(size); \
- } while (0)
-#define ABSL_ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) \
- do { \
- (void)(address); \
- (void)(size); \
- } while (0)
-#else
-
#define ABSL_ANNOTATE_MEMORY_IS_INITIALIZED(address, size) // empty
#define ABSL_ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) // empty
-#endif
-
#endif // ABSL_HAVE_MEMORY_SANITIZER
// -------------------------------------------------------------------------
diff --git a/yass/third_party/abseil-cpp/absl/base/internal/spinlock.h b/yass/third_party/abseil-cpp/absl/base/internal/spinlock.h
index 36f823ada8..301c3e3b43 100644
--- a/yass/third_party/abseil-cpp/absl/base/internal/spinlock.h
+++ b/yass/third_party/abseil-cpp/absl/base/internal/spinlock.h
@@ -202,6 +202,15 @@ class ABSL_LOCKABLE ABSL_ATTRIBUTE_WARN_UNUSED SpinLock {
// Corresponding locker object that arranges to acquire a spinlock for
// the duration of a C++ scope.
+//
+// TODO(b/176172494): Use only [[nodiscard]] when baseline is raised.
+// TODO(b/6695610): Remove forward declaration when #ifdef is no longer needed.
+#if ABSL_HAVE_CPP_ATTRIBUTE(nodiscard)
+class [[nodiscard]] SpinLockHolder;
+#else
+class ABSL_MUST_USE_RESULT ABSL_ATTRIBUTE_TRIVIAL_ABI SpinLockHolder;
+#endif
+
class ABSL_SCOPED_LOCKABLE SpinLockHolder {
public:
inline explicit SpinLockHolder(SpinLock* l) ABSL_EXCLUSIVE_LOCK_FUNCTION(l)
diff --git a/yass/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.cc b/yass/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.cc
index 05e0e7ba5e..a0bf3a65f7 100644
--- a/yass/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.cc
+++ b/yass/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.cc
@@ -121,18 +121,6 @@ double UnscaledCycleClock::Frequency() {
return aarch64_timer_frequency;
}
-#elif defined(__riscv)
-
-int64_t UnscaledCycleClock::Now() {
- int64_t virtual_timer_value;
- asm volatile("rdcycle %0" : "=r"(virtual_timer_value));
- return virtual_timer_value;
-}
-
-double UnscaledCycleClock::Frequency() {
- return base_internal::NominalCPUFrequency();
-}
-
#elif defined(_M_IX86) || defined(_M_X64)
#pragma intrinsic(__rdtsc)
diff --git a/yass/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock_config.h b/yass/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock_config.h
index 24b324ac99..43a3dabeea 100644
--- a/yass/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock_config.h
+++ b/yass/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock_config.h
@@ -21,8 +21,8 @@
// The following platforms have an implementation of a hardware counter.
#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__) || \
- defined(__powerpc__) || defined(__ppc__) || defined(__riscv) || \
- defined(_M_IX86) || (defined(_M_X64) && !defined(_M_ARM64EC))
+ defined(__powerpc__) || defined(__ppc__) || defined(_M_IX86) || \
+ (defined(_M_X64) && !defined(_M_ARM64EC))
#define ABSL_HAVE_UNSCALED_CYCLECLOCK_IMPLEMENTATION 1
#else
#define ABSL_HAVE_UNSCALED_CYCLECLOCK_IMPLEMENTATION 0
@@ -53,8 +53,8 @@
#if ABSL_USE_UNSCALED_CYCLECLOCK
// This macro can be used to test if UnscaledCycleClock::Frequency()
// is NominalCPUFrequency() on a particular platform.
-#if (defined(__i386__) || defined(__x86_64__) || defined(__riscv) || \
- defined(_M_IX86) || defined(_M_X64))
+#if (defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || \
+ defined(_M_X64))
#define ABSL_INTERNAL_UNSCALED_CYCLECLOCK_FREQUENCY_IS_CPU_FREQUENCY
#endif
#endif
diff --git a/yass/third_party/abseil-cpp/absl/base/macros.h b/yass/third_party/abseil-cpp/absl/base/macros.h
index 33c1cd1e8d..b318f11664 100644
--- a/yass/third_party/abseil-cpp/absl/base/macros.h
+++ b/yass/third_party/abseil-cpp/absl/base/macros.h
@@ -174,4 +174,16 @@ ABSL_NAMESPACE_END
#define ABSL_DEPRECATE_AND_INLINE()
#endif
+// Requires the compiler to prove that the size of the given object is at least
+// the expected amount.
+#if ABSL_HAVE_ATTRIBUTE(diagnose_if) && ABSL_HAVE_BUILTIN(__builtin_object_size)
+#define ABSL_INTERNAL_NEED_MIN_SIZE(Obj, N) \
+ __attribute__((diagnose_if(__builtin_object_size(Obj, 0) < N, \
+ "object size provably too small " \
+ "(this would corrupt memory)", \
+ "error")))
+#else
+#define ABSL_INTERNAL_NEED_MIN_SIZE(Obj, N)
+#endif
+
#endif // ABSL_BASE_MACROS_H_
diff --git a/yass/third_party/abseil-cpp/absl/container/BUILD.bazel b/yass/third_party/abseil-cpp/absl/container/BUILD.bazel
index 366bf3cd2e..12e27c21fd 100644
--- a/yass/third_party/abseil-cpp/absl/container/BUILD.bazel
+++ b/yass/third_party/abseil-cpp/absl/container/BUILD.bazel
@@ -242,7 +242,6 @@ NOTEST_TAGS_MOBILE = [
cc_library(
name = "flat_hash_map",
- srcs = ["flat_hash_map.cc"],
hdrs = ["flat_hash_map.h"],
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
@@ -250,9 +249,7 @@ cc_library(
":container_memory",
":hash_function_defaults",
":raw_hash_map",
- ":raw_hash_set",
"//absl/algorithm:container",
- "//absl/base:config",
"//absl/base:core_headers",
"//absl/memory",
],
@@ -282,7 +279,6 @@ cc_test(
cc_library(
name = "flat_hash_set",
- srcs = ["flat_hash_set.cc"],
hdrs = ["flat_hash_set.h"],
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
@@ -291,7 +287,6 @@ cc_library(
":hash_function_defaults",
":raw_hash_set",
"//absl/algorithm:container",
- "//absl/base:config",
"//absl/base:core_headers",
"//absl/memory",
],
@@ -323,7 +318,6 @@ cc_test(
cc_library(
name = "node_hash_map",
- srcs = ["node_hash_map.cc"],
hdrs = ["node_hash_map.h"],
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
@@ -332,9 +326,7 @@ cc_library(
":hash_function_defaults",
":node_slot_policy",
":raw_hash_map",
- ":raw_hash_set",
"//absl/algorithm:container",
- "//absl/base:config",
"//absl/base:core_headers",
"//absl/memory",
],
@@ -361,7 +353,6 @@ cc_test(
cc_library(
name = "node_hash_set",
- srcs = ["node_hash_set.cc"],
hdrs = ["node_hash_set.h"],
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
@@ -371,7 +362,6 @@ cc_library(
":node_slot_policy",
":raw_hash_set",
"//absl/algorithm:container",
- "//absl/base:config",
"//absl/base:core_headers",
"//absl/memory",
],
@@ -711,8 +701,10 @@ cc_test(
"//absl/base:config",
"//absl/base:core_headers",
"//absl/base:prefetch",
+ "//absl/functional:function_ref",
"//absl/hash",
"//absl/log",
+ "//absl/log:check",
"//absl/memory",
"//absl/meta:type_traits",
"//absl/strings",
@@ -734,6 +726,7 @@ cc_binary(
":hash_function_defaults",
":raw_hash_set",
"//absl/base:raw_logging_internal",
+ "//absl/random",
"//absl/strings:str_format",
"@com_github_google_benchmark//:benchmark_main",
],
@@ -1012,6 +1005,7 @@ cc_library(
":compressed_tuple",
":container_memory",
":layout",
+ "//absl/base:config",
"//absl/base:core_headers",
"//absl/base:raw_logging_internal",
"//absl/base:throw_delegate",
@@ -1020,7 +1014,6 @@ cc_library(
"//absl/strings",
"//absl/strings:cord",
"//absl/types:compare",
- "//absl/utility",
],
)
diff --git a/yass/third_party/abseil-cpp/absl/container/CMakeLists.txt b/yass/third_party/abseil-cpp/absl/container/CMakeLists.txt
index 8e64adb1a7..04055816cd 100644
--- a/yass/third_party/abseil-cpp/absl/container/CMakeLists.txt
+++ b/yass/third_party/abseil-cpp/absl/container/CMakeLists.txt
@@ -27,10 +27,11 @@ absl_cc_library(
LINKOPTS
${ABSL_DEFAULT_LINKOPTS}
DEPS
- absl::container_common
absl::common_policy_traits
absl::compare
absl::compressed_tuple
+ absl::config
+ absl::container_common
absl::container_memory
absl::cord
absl::core_headers
@@ -40,7 +41,6 @@ absl_cc_library(
absl::strings
absl::throw_delegate
absl::type_traits
- absl::utility
)
# Internal-only target, do not depend on directly.
@@ -283,17 +283,13 @@ absl_cc_library(
flat_hash_map
HDRS
"flat_hash_map.h"
- SRCS
- "flat_hash_map.cc"
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
- absl::config
absl::container_memory
absl::core_headers
absl::hash_function_defaults
absl::raw_hash_map
- absl::raw_hash_set
absl::algorithm_container
absl::memory
PUBLIC
@@ -325,12 +321,9 @@ absl_cc_library(
flat_hash_set
HDRS
"flat_hash_set.h"
- SRCS
- "flat_hash_set.cc"
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
- absl::config
absl::container_memory
absl::hash_function_defaults
absl::raw_hash_set
@@ -369,18 +362,14 @@ absl_cc_library(
node_hash_map
HDRS
"node_hash_map.h"
- SRCS
- "node_hash_map.cc"
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
- absl::config
absl::container_memory
absl::core_headers
absl::hash_function_defaults
absl::node_slot_policy
absl::raw_hash_map
- absl::raw_hash_set
absl::algorithm_container
absl::memory
PUBLIC
@@ -409,12 +398,9 @@ absl_cc_library(
node_hash_set
HDRS
"node_hash_set.h"
- SRCS
- "node_hash_set.cc"
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
- absl::config
absl::container_memory
absl::core_headers
absl::hash_function_defaults
@@ -767,11 +753,13 @@ absl_cc_test(
${ABSL_TEST_COPTS}
DEPS
absl::base
+ absl::check
absl::config
absl::container_memory
absl::core_headers
absl::flat_hash_map
absl::flat_hash_set
+ absl::function_ref
absl::hash
absl::hash_function_defaults
absl::hash_policy_testing
diff --git a/yass/third_party/abseil-cpp/absl/container/flat_hash_map.cc b/yass/third_party/abseil-cpp/absl/container/flat_hash_map.cc
deleted file mode 100644
index d5a2531703..0000000000
--- a/yass/third_party/abseil-cpp/absl/container/flat_hash_map.cc
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2024 The Abseil Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "absl/container/flat_hash_map.h"
-
-#include
-#include
-
-#include "absl/base/config.h"
-
-namespace absl {
-ABSL_NAMESPACE_BEGIN
-
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_MAP(template, int32_t, int32_t);
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_MAP(template, std::string, int32_t);
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_MAP(template, int32_t, std::string);
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_MAP(template, int64_t, int64_t);
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_MAP(template, std::string, int64_t);
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_MAP(template, int64_t, std::string);
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_MAP(template, uint32_t, uint32_t);
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_MAP(template, std::string, uint32_t);
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_MAP(template, uint32_t, std::string);
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_MAP(template, uint64_t, uint64_t);
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_MAP(template, std::string, uint64_t);
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_MAP(template, uint64_t, std::string);
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_MAP(template, std::string, std::string);
-
-ABSL_NAMESPACE_END
-} // namespace absl
diff --git a/yass/third_party/abseil-cpp/absl/container/flat_hash_map.h b/yass/third_party/abseil-cpp/absl/container/flat_hash_map.h
index a60b582987..a33c794fad 100644
--- a/yass/third_party/abseil-cpp/absl/container/flat_hash_map.h
+++ b/yass/third_party/abseil-cpp/absl/container/flat_hash_map.h
@@ -31,20 +31,15 @@
#define ABSL_CONTAINER_FLAT_HASH_MAP_H_
#include
-#include
-#include
#include
-#include
#include
#include
#include "absl/algorithm/container.h"
-#include "absl/base/config.h"
#include "absl/base/macros.h"
#include "absl/container/internal/container_memory.h"
#include "absl/container/internal/hash_function_defaults.h" // IWYU pragma: export
#include "absl/container/internal/raw_hash_map.h" // IWYU pragma: export
-#include "absl/container/internal/raw_hash_set.h" // IWYU pragma: export
#include "absl/memory/memory.h"
namespace absl {
@@ -637,42 +632,6 @@ struct IsUnorderedContainer<
} // namespace container_algorithm_internal
-// Explicit template instantiations for common map types in order to decrease
-// linker input size. Note that explicitly instantiating flat_hash_map itself
-// doesn't help because it has no non-alias members. If we need to decrease
-// linker input size more, we could potentially (a) add more key/value types,
-// e.g. string_view/Cord, (b) instantiate some template member functions, e.g.
-// operator[]/find. The EXTERN argument is `extern` for the declaration and
-// empty for the definition.
-#define ABSL_INTERNAL_TEMPLATE_FLAT_HASH_MAP(TEMPLATE, KEY, VALUE) \
- TEMPLATE class absl::container_internal::raw_hash_map< \
- absl::container_internal::FlatHashMapPolicy, \
- absl::container_internal::hash_default_hash, \
- absl::container_internal::hash_default_eq, \
- std::allocator>>; \
- TEMPLATE class absl::container_internal::raw_hash_set< \
- absl::container_internal::FlatHashMapPolicy, \
- absl::container_internal::hash_default_hash, \
- absl::container_internal::hash_default_eq, \
- std::allocator>>;
-
-// We use exact-width integer types rather than `int`/`long`/`long long` because
-// these are the types recommended in the Google C++ style guide and which are
-// commonly used in Google code.
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_MAP(extern template, int32_t, int32_t)
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_MAP(extern template, std::string, int32_t)
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_MAP(extern template, int32_t, std::string)
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_MAP(extern template, int64_t, int64_t)
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_MAP(extern template, std::string, int64_t)
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_MAP(extern template, int64_t, std::string)
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_MAP(extern template, uint32_t, uint32_t)
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_MAP(extern template, std::string, uint32_t)
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_MAP(extern template, uint32_t, std::string)
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_MAP(extern template, uint64_t, uint64_t)
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_MAP(extern template, std::string, uint64_t)
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_MAP(extern template, uint64_t, std::string)
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_MAP(extern template, std::string, std::string)
-
ABSL_NAMESPACE_END
} // namespace absl
diff --git a/yass/third_party/abseil-cpp/absl/container/flat_hash_set.cc b/yass/third_party/abseil-cpp/absl/container/flat_hash_set.cc
deleted file mode 100644
index d07081b8f1..0000000000
--- a/yass/third_party/abseil-cpp/absl/container/flat_hash_set.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2024 The Abseil Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "absl/container/flat_hash_set.h"
-
-#include
-#include
-
-#include "absl/base/config.h"
-
-namespace absl {
-ABSL_NAMESPACE_BEGIN
-
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_SET(template, int8_t);
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_SET(template, int16_t);
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_SET(template, int32_t);
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_SET(template, int64_t);
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_SET(template, uint8_t);
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_SET(template, uint16_t);
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_SET(template, uint32_t);
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_SET(template, uint64_t);
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_SET(template, std::string);
-
-ABSL_NAMESPACE_END
-} // namespace absl
diff --git a/yass/third_party/abseil-cpp/absl/container/flat_hash_set.h b/yass/third_party/abseil-cpp/absl/container/flat_hash_set.h
index 461526c0a8..5f72f9549e 100644
--- a/yass/third_party/abseil-cpp/absl/container/flat_hash_set.h
+++ b/yass/third_party/abseil-cpp/absl/container/flat_hash_set.h
@@ -30,14 +30,11 @@
#define ABSL_CONTAINER_FLAT_HASH_SET_H_
#include
-#include
#include
-#include
#include
#include
#include "absl/algorithm/container.h"
-#include "absl/base/config.h"
#include "absl/base/macros.h"
#include "absl/container/internal/container_memory.h"
#include "absl/container/internal/hash_function_defaults.h" // IWYU pragma: export
@@ -526,32 +523,6 @@ struct IsUnorderedContainer>
} // namespace container_algorithm_internal
-// Explicit template instantiations for common set types in order to decrease
-// linker input size. Note that explicitly instantiating flat_hash_set itself
-// doesn't help because it has no non-alias members. If we need to decrease
-// linker input size more, we could potentially (a) add more key types, e.g.
-// string_view/Cord, (b) instantiate some template member functions, e.g.
-// find/insert/emplace. The EXTERN argument is `extern` for the declaration and
-// empty for the definition.
-#define ABSL_INTERNAL_TEMPLATE_FLAT_HASH_SET(TEMPLATE, KEY) \
- TEMPLATE class absl::container_internal::raw_hash_set< \
- absl::container_internal::FlatHashSetPolicy, \
- absl::container_internal::hash_default_hash, \
- absl::container_internal::hash_default_eq, std::allocator>;
-
-// We use exact-width integer types rather than `int`/`long`/`long long` because
-// these are the types recommended in the Google C++ style guide and which are
-// commonly used in Google code.
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_SET(extern template, int8_t)
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_SET(extern template, int16_t)
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_SET(extern template, int32_t)
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_SET(extern template, int64_t)
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_SET(extern template, uint8_t)
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_SET(extern template, uint16_t)
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_SET(extern template, uint32_t)
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_SET(extern template, uint64_t)
-ABSL_INTERNAL_TEMPLATE_FLAT_HASH_SET(extern template, std::string)
-
ABSL_NAMESPACE_END
} // namespace absl
diff --git a/yass/third_party/abseil-cpp/absl/container/internal/btree.h b/yass/third_party/abseil-cpp/absl/container/internal/btree.h
index fd7860dacc..689e71a5ce 100644
--- a/yass/third_party/abseil-cpp/absl/container/internal/btree.h
+++ b/yass/third_party/abseil-cpp/absl/container/internal/btree.h
@@ -53,11 +53,11 @@
#include
#include
#include
-#include
#include
#include
#include
+#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/base/macros.h"
#include "absl/container/internal/common.h"
@@ -70,7 +70,6 @@
#include "absl/strings/cord.h"
#include "absl/strings/string_view.h"
#include "absl/types/compare.h"
-#include "absl/utility/utility.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
@@ -78,9 +77,10 @@ namespace container_internal {
#ifdef ABSL_BTREE_ENABLE_GENERATIONS
#error ABSL_BTREE_ENABLE_GENERATIONS cannot be directly set
-#elif defined(ABSL_HAVE_ADDRESS_SANITIZER) || \
- defined(ABSL_HAVE_HWADDRESS_SANITIZER) || \
- defined(ABSL_HAVE_MEMORY_SANITIZER)
+#elif (defined(ABSL_HAVE_ADDRESS_SANITIZER) || \
+ defined(ABSL_HAVE_HWADDRESS_SANITIZER) || \
+ defined(ABSL_HAVE_MEMORY_SANITIZER)) && \
+ !defined(NDEBUG_SANITIZER) // If defined, performance is important.
// When compiled in sanitizer mode, we add generation integers to the nodes and
// iterators. When iterators are used, we validate that the container has not
// been mutated since the iterator was constructed.
@@ -475,7 +475,7 @@ struct SearchResult {
// useful information.
template
struct SearchResult {
- SearchResult() {}
+ SearchResult() = default;
explicit SearchResult(V v) : value(v) {}
SearchResult(V v, MatchKind /*match*/) : value(v) {}
@@ -580,14 +580,12 @@ class btree_node {
using layout_type =
absl::container_internal::Layout;
+ using leaf_layout_type = typename layout_type::template WithStaticSizes<
+ /*parent*/ 1,
+ /*generation*/ BtreeGenerationsEnabled() ? 1 : 0,
+ /*position, start, finish, max_count*/ 4>;
constexpr static size_type SizeWithNSlots(size_type n) {
- return layout_type(
- /*parent*/ 1,
- /*generation*/ BtreeGenerationsEnabled() ? 1 : 0,
- /*position, start, finish, max_count*/ 4,
- /*slots*/ n,
- /*children*/ 0)
- .AllocSize();
+ return leaf_layout_type(/*slots*/ n, /*children*/ 0).AllocSize();
}
// A lower bound for the overhead of fields other than slots in a leaf node.
constexpr static size_type MinimumOverhead() {
@@ -619,27 +617,22 @@ class btree_node {
constexpr static size_type kNodeSlots =
kNodeTargetSlots >= kMinNodeSlots ? kNodeTargetSlots : kMinNodeSlots;
+ using internal_layout_type = typename layout_type::template WithStaticSizes<
+ /*parent*/ 1,
+ /*generation*/ BtreeGenerationsEnabled() ? 1 : 0,
+ /*position, start, finish, max_count*/ 4, /*slots*/ kNodeSlots,
+ /*children*/ kNodeSlots + 1>;
+
// The node is internal (i.e. is not a leaf node) if and only if `max_count`
// has this value.
constexpr static field_type kInternalNodeMaxCount = 0;
- constexpr static layout_type Layout(const size_type slot_count,
- const size_type child_count) {
- return layout_type(
- /*parent*/ 1,
- /*generation*/ BtreeGenerationsEnabled() ? 1 : 0,
- /*position, start, finish, max_count*/ 4,
- /*slots*/ slot_count,
- /*children*/ child_count);
- }
// Leaves can have less than kNodeSlots values.
- constexpr static layout_type LeafLayout(
+ constexpr static leaf_layout_type LeafLayout(
const size_type slot_count = kNodeSlots) {
- return Layout(slot_count, 0);
- }
- constexpr static layout_type InternalLayout() {
- return Layout(kNodeSlots, kNodeSlots + 1);
+ return leaf_layout_type(slot_count, 0);
}
+ constexpr static auto InternalLayout() { return internal_layout_type(); }
constexpr static size_type LeafSize(const size_type slot_count = kNodeSlots) {
return LeafLayout(slot_count).AllocSize();
}
diff --git a/yass/third_party/abseil-cpp/absl/container/internal/hash_policy_traits.h b/yass/third_party/abseil-cpp/absl/container/internal/hash_policy_traits.h
index ec08794a40..ad835d6fcd 100644
--- a/yass/third_party/abseil-cpp/absl/container/internal/hash_policy_traits.h
+++ b/yass/third_party/abseil-cpp/absl/container/internal/hash_policy_traits.h
@@ -168,7 +168,7 @@ struct hash_policy_traits : common_policy_traits {
#endif
}
- // Whether small object optimization is enabled. False by default.
+ // Whether small object optimization is enabled. True by default.
static constexpr bool soo_enabled() { return soo_enabled_impl(Rank1{}); }
private:
@@ -197,7 +197,7 @@ struct hash_policy_traits : common_policy_traits {
return P::soo_enabled();
}
- static constexpr bool soo_enabled_impl(Rank0) { return false; }
+ static constexpr bool soo_enabled_impl(Rank0) { return true; }
};
} // namespace container_internal
diff --git a/yass/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.cc b/yass/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.cc
index b21beef0df..fd21d966b7 100644
--- a/yass/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.cc
+++ b/yass/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.cc
@@ -18,13 +18,18 @@
#include
#include
#include
+#include
+#include
#include
#include
#include "absl/base/attributes.h"
#include "absl/base/config.h"
+#include "absl/base/internal/per_thread_tls.h"
#include "absl/base/internal/raw_logging.h"
+#include "absl/base/macros.h"
#include "absl/base/no_destructor.h"
+#include "absl/base/optimization.h"
#include "absl/debugging/stacktrace.h"
#include "absl/memory/memory.h"
#include "absl/profiling/internal/exponential_biased.h"
@@ -73,7 +78,10 @@ HashtablezInfo::HashtablezInfo() = default;
HashtablezInfo::~HashtablezInfo() = default;
void HashtablezInfo::PrepareForSampling(int64_t stride,
- size_t inline_element_size_value) {
+ size_t inline_element_size_value,
+ size_t key_size_value,
+ size_t value_size_value,
+ uint16_t soo_capacity_value) {
capacity.store(0, std::memory_order_relaxed);
size.store(0, std::memory_order_relaxed);
num_erases.store(0, std::memory_order_relaxed);
@@ -93,6 +101,9 @@ void HashtablezInfo::PrepareForSampling(int64_t stride,
depth = absl::GetStackTrace(stack, HashtablezInfo::kMaxStackDepth,
/* skip_count= */ 0);
inline_element_size = inline_element_size_value;
+ key_size = key_size_value;
+ value_size = value_size_value;
+ soo_capacity = soo_capacity_value;
}
static bool ShouldForceSampling() {
@@ -116,12 +127,13 @@ static bool ShouldForceSampling() {
}
HashtablezInfo* SampleSlow(SamplingState& next_sample,
- size_t inline_element_size) {
+ size_t inline_element_size, size_t key_size,
+ size_t value_size, uint16_t soo_capacity) {
if (ABSL_PREDICT_FALSE(ShouldForceSampling())) {
next_sample.next_sample = 1;
const int64_t old_stride = exchange(next_sample.sample_stride, 1);
- HashtablezInfo* result =
- GlobalHashtablezSampler().Register(old_stride, inline_element_size);
+ HashtablezInfo* result = GlobalHashtablezSampler().Register(
+ old_stride, inline_element_size, key_size, value_size, soo_capacity);
return result;
}
@@ -151,10 +163,12 @@ HashtablezInfo* SampleSlow(SamplingState& next_sample,
// that case.
if (first) {
if (ABSL_PREDICT_TRUE(--next_sample.next_sample > 0)) return nullptr;
- return SampleSlow(next_sample, inline_element_size);
+ return SampleSlow(next_sample, inline_element_size, key_size, value_size,
+ soo_capacity);
}
- return GlobalHashtablezSampler().Register(old_stride, inline_element_size);
+ return GlobalHashtablezSampler().Register(old_stride, inline_element_size,
+ key_size, value_size, soo_capacity);
#endif
}
diff --git a/yass/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.h b/yass/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.h
index e41ee2d747..d74acf8c6e 100644
--- a/yass/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.h
+++ b/yass/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.h
@@ -40,15 +40,20 @@
#define ABSL_CONTAINER_INTERNAL_HASHTABLEZ_SAMPLER_H_
#include
+#include
+#include
#include
#include
#include
+#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/internal/per_thread_tls.h"
#include "absl/base/optimization.h"
+#include "absl/base/thread_annotations.h"
#include "absl/profiling/internal/sample_recorder.h"
#include "absl/synchronization/mutex.h"
+#include "absl/time/time.h"
#include "absl/utility/utility.h"
namespace absl {
@@ -67,7 +72,9 @@ struct HashtablezInfo : public profiling_internal::Sample {
// Puts the object into a clean state, fills in the logically `const` members,
// blocking for any readers that are currently sampling the object.
- void PrepareForSampling(int64_t stride, size_t inline_element_size_value)
+ void PrepareForSampling(int64_t stride, size_t inline_element_size_value,
+ size_t key_size, size_t value_size,
+ uint16_t soo_capacity_value)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(init_mu);
// These fields are mutated by the various Record* APIs and need to be
@@ -91,8 +98,15 @@ struct HashtablezInfo : public profiling_internal::Sample {
static constexpr int kMaxStackDepth = 64;
absl::Time create_time;
int32_t depth;
+ // The SOO capacity for this table in elements (not bytes). Note that sampled
+ // tables are never SOO because we need to store the infoz handle on the heap.
+ // Tables that would be SOO if not sampled should have: soo_capacity > 0 &&
+ // size <= soo_capacity && max_reserve <= soo_capacity.
+ uint16_t soo_capacity;
void* stack[kMaxStackDepth];
- size_t inline_element_size; // How big is the slot?
+ size_t inline_element_size; // How big is the slot in bytes?
+ size_t key_size; // sizeof(key_type)
+ size_t value_size; // sizeof(value_type)
};
void RecordRehashSlow(HashtablezInfo* info, size_t total_probe_length);
@@ -117,7 +131,8 @@ struct SamplingState {
};
HashtablezInfo* SampleSlow(SamplingState& next_sample,
- size_t inline_element_size);
+ size_t inline_element_size, size_t key_size,
+ size_t value_size, uint16_t soo_capacity);
void UnsampleSlow(HashtablezInfo* info);
#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
@@ -204,16 +219,19 @@ class HashtablezInfoHandle {
extern ABSL_PER_THREAD_TLS_KEYWORD SamplingState global_next_sample;
#endif // defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
-// Returns an RAII sampling handle that manages registration and unregistation
-// with the global sampler.
+// Returns a sampling handle.
inline HashtablezInfoHandle Sample(
- size_t inline_element_size ABSL_ATTRIBUTE_UNUSED) {
+ ABSL_ATTRIBUTE_UNUSED size_t inline_element_size,
+ ABSL_ATTRIBUTE_UNUSED size_t key_size,
+ ABSL_ATTRIBUTE_UNUSED size_t value_size,
+ ABSL_ATTRIBUTE_UNUSED uint16_t soo_capacity) {
#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
if (ABSL_PREDICT_TRUE(--global_next_sample.next_sample > 0)) {
return HashtablezInfoHandle(nullptr);
}
- return HashtablezInfoHandle(
- SampleSlow(global_next_sample, inline_element_size));
+ return HashtablezInfoHandle(SampleSlow(global_next_sample,
+ inline_element_size, key_size,
+ value_size, soo_capacity));
#else
return HashtablezInfoHandle(nullptr);
#endif // !ABSL_PER_THREAD_TLS
diff --git a/yass/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler_test.cc b/yass/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler_test.cc
index 8ebb08da4a..24d3bc4818 100644
--- a/yass/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler_test.cc
+++ b/yass/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler_test.cc
@@ -15,8 +15,12 @@
#include "absl/container/internal/hashtablez_sampler.h"
#include
+#include
+#include
+#include
#include
#include
+#include
#include "gmock/gmock.h"
#include "gtest/gtest.h"
@@ -67,7 +71,11 @@ std::vector GetSizes(HashtablezSampler* s) {
HashtablezInfo* Register(HashtablezSampler* s, size_t size) {
const int64_t test_stride = 123;
const size_t test_element_size = 17;
- auto* info = s->Register(test_stride, test_element_size);
+ const size_t test_key_size = 3;
+ const size_t test_value_size = 5;
+ auto* info =
+ s->Register(test_stride, test_element_size, /*key_size=*/test_key_size,
+ /*value_size=*/test_value_size, /*soo_capacity=*/0);
assert(info != nullptr);
info->size.store(size);
return info;
@@ -77,9 +85,15 @@ TEST(HashtablezInfoTest, PrepareForSampling) {
absl::Time test_start = absl::Now();
const int64_t test_stride = 123;
const size_t test_element_size = 17;
+ const size_t test_key_size = 15;
+ const size_t test_value_size = 13;
+
HashtablezInfo info;
absl::MutexLock l(&info.init_mu);
- info.PrepareForSampling(test_stride, test_element_size);
+ info.PrepareForSampling(test_stride, test_element_size,
+ /*key_size=*/test_key_size,
+ /*value_size=*/test_value_size,
+ /*soo_capacity_value=*/1);
EXPECT_EQ(info.capacity.load(), 0);
EXPECT_EQ(info.size.load(), 0);
@@ -94,6 +108,9 @@ TEST(HashtablezInfoTest, PrepareForSampling) {
EXPECT_GE(info.create_time, test_start);
EXPECT_EQ(info.weight, test_stride);
EXPECT_EQ(info.inline_element_size, test_element_size);
+ EXPECT_EQ(info.key_size, test_key_size);
+ EXPECT_EQ(info.value_size, test_value_size);
+ EXPECT_EQ(info.soo_capacity, 1);
info.capacity.store(1, std::memory_order_relaxed);
info.size.store(1, std::memory_order_relaxed);
@@ -106,7 +123,10 @@ TEST(HashtablezInfoTest, PrepareForSampling) {
info.max_reserve.store(1, std::memory_order_relaxed);
info.create_time = test_start - absl::Hours(20);
- info.PrepareForSampling(test_stride * 2, test_element_size);
+ info.PrepareForSampling(test_stride * 2, test_element_size,
+ /*key_size=*/test_key_size,
+ /*value_size=*/test_value_size,
+ /*soo_capacity_value=*/0);
EXPECT_EQ(info.capacity.load(), 0);
EXPECT_EQ(info.size.load(), 0);
EXPECT_EQ(info.num_erases.load(), 0);
@@ -119,7 +139,10 @@ TEST(HashtablezInfoTest, PrepareForSampling) {
EXPECT_EQ(info.max_reserve.load(), 0);
EXPECT_EQ(info.weight, 2 * test_stride);
EXPECT_EQ(info.inline_element_size, test_element_size);
+ EXPECT_EQ(info.key_size, test_key_size);
+ EXPECT_EQ(info.value_size, test_value_size);
EXPECT_GE(info.create_time, test_start);
+ EXPECT_EQ(info.soo_capacity, 0);
}
TEST(HashtablezInfoTest, RecordStorageChanged) {
@@ -127,7 +150,13 @@ TEST(HashtablezInfoTest, RecordStorageChanged) {
absl::MutexLock l(&info.init_mu);
const int64_t test_stride = 21;
const size_t test_element_size = 19;
- info.PrepareForSampling(test_stride, test_element_size);
+ const size_t test_key_size = 17;
+ const size_t test_value_size = 15;
+
+ info.PrepareForSampling(test_stride, test_element_size,
+ /*key_size=*/test_key_size,
+ /*value_size=*/test_value_size,
+ /*soo_capacity_value=*/0);
RecordStorageChangedSlow(&info, 17, 47);
EXPECT_EQ(info.size.load(), 17);
EXPECT_EQ(info.capacity.load(), 47);
@@ -141,7 +170,13 @@ TEST(HashtablezInfoTest, RecordInsert) {
absl::MutexLock l(&info.init_mu);
const int64_t test_stride = 25;
const size_t test_element_size = 23;
- info.PrepareForSampling(test_stride, test_element_size);
+ const size_t test_key_size = 21;
+ const size_t test_value_size = 19;
+
+ info.PrepareForSampling(test_stride, test_element_size,
+ /*key_size=*/test_key_size,
+ /*value_size=*/test_value_size,
+ /*soo_capacity_value=*/0);
EXPECT_EQ(info.max_probe_length.load(), 0);
RecordInsertSlow(&info, 0x0000FF00, 6 * kProbeLength);
EXPECT_EQ(info.max_probe_length.load(), 6);
@@ -163,9 +198,15 @@ TEST(HashtablezInfoTest, RecordInsert) {
TEST(HashtablezInfoTest, RecordErase) {
const int64_t test_stride = 31;
const size_t test_element_size = 29;
+ const size_t test_key_size = 27;
+ const size_t test_value_size = 25;
+
HashtablezInfo info;
absl::MutexLock l(&info.init_mu);
- info.PrepareForSampling(test_stride, test_element_size);
+ info.PrepareForSampling(test_stride, test_element_size,
+ /*key_size=*/test_key_size,
+ /*value_size=*/test_value_size,
+ /*soo_capacity_value=*/1);
EXPECT_EQ(info.num_erases.load(), 0);
EXPECT_EQ(info.size.load(), 0);
RecordInsertSlow(&info, 0x0000FF00, 6 * kProbeLength);
@@ -174,14 +215,23 @@ TEST(HashtablezInfoTest, RecordErase) {
EXPECT_EQ(info.size.load(), 0);
EXPECT_EQ(info.num_erases.load(), 1);
EXPECT_EQ(info.inline_element_size, test_element_size);
+ EXPECT_EQ(info.key_size, test_key_size);
+ EXPECT_EQ(info.value_size, test_value_size);
+ EXPECT_EQ(info.soo_capacity, 1);
}
TEST(HashtablezInfoTest, RecordRehash) {
const int64_t test_stride = 33;
const size_t test_element_size = 31;
+ const size_t test_key_size = 29;
+ const size_t test_value_size = 27;
HashtablezInfo info;
absl::MutexLock l(&info.init_mu);
- info.PrepareForSampling(test_stride, test_element_size);
+ info.PrepareForSampling(test_stride, test_element_size,
+ /*key_size=*/test_key_size,
+ /*value_size=*/test_value_size,
+
+ /*soo_capacity_value=*/0);
RecordInsertSlow(&info, 0x1, 0);
RecordInsertSlow(&info, 0x2, kProbeLength);
RecordInsertSlow(&info, 0x4, kProbeLength);
@@ -201,6 +251,9 @@ TEST(HashtablezInfoTest, RecordRehash) {
EXPECT_EQ(info.num_erases.load(), 0);
EXPECT_EQ(info.num_rehashes.load(), 1);
EXPECT_EQ(info.inline_element_size, test_element_size);
+ EXPECT_EQ(info.key_size, test_key_size);
+ EXPECT_EQ(info.value_size, test_value_size);
+ EXPECT_EQ(info.soo_capacity, 0);
}
TEST(HashtablezInfoTest, RecordReservation) {
@@ -208,7 +261,14 @@ TEST(HashtablezInfoTest, RecordReservation) {
absl::MutexLock l(&info.init_mu);
const int64_t test_stride = 35;
const size_t test_element_size = 33;
- info.PrepareForSampling(test_stride, test_element_size);
+ const size_t test_key_size = 31;
+ const size_t test_value_size = 29;
+
+ info.PrepareForSampling(test_stride, test_element_size,
+ /*key_size=*/test_key_size,
+ /*value_size=*/test_value_size,
+
+ /*soo_capacity_value=*/0);
RecordReservationSlow(&info, 3);
EXPECT_EQ(info.max_reserve.load(), 3);
@@ -224,12 +284,19 @@ TEST(HashtablezInfoTest, RecordReservation) {
#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
TEST(HashtablezSamplerTest, SmallSampleParameter) {
const size_t test_element_size = 31;
+ const size_t test_key_size = 33;
+ const size_t test_value_size = 35;
+
SetHashtablezEnabled(true);
SetHashtablezSampleParameter(100);
for (int i = 0; i < 1000; ++i) {
SamplingState next_sample = {0, 0};
- HashtablezInfo* sample = SampleSlow(next_sample, test_element_size);
+ HashtablezInfo* sample =
+ SampleSlow(next_sample, test_element_size,
+ /*key_size=*/test_key_size, /*value_size=*/test_value_size,
+
+ /*soo_capacity=*/0);
EXPECT_GT(next_sample.next_sample, 0);
EXPECT_EQ(next_sample.next_sample, next_sample.sample_stride);
EXPECT_NE(sample, nullptr);
@@ -239,12 +306,17 @@ TEST(HashtablezSamplerTest, SmallSampleParameter) {
TEST(HashtablezSamplerTest, LargeSampleParameter) {
const size_t test_element_size = 31;
+ const size_t test_key_size = 33;
+ const size_t test_value_size = 35;
SetHashtablezEnabled(true);
SetHashtablezSampleParameter(std::numeric_limits::max());
for (int i = 0; i < 1000; ++i) {
SamplingState next_sample = {0, 0};
- HashtablezInfo* sample = SampleSlow(next_sample, test_element_size);
+ HashtablezInfo* sample =
+ SampleSlow(next_sample, test_element_size,
+ /*key_size=*/test_key_size, /*value_size=*/test_value_size,
+ /*soo_capacity=*/0);
EXPECT_GT(next_sample.next_sample, 0);
EXPECT_EQ(next_sample.next_sample, next_sample.sample_stride);
EXPECT_NE(sample, nullptr);
@@ -254,13 +326,20 @@ TEST(HashtablezSamplerTest, LargeSampleParameter) {
TEST(HashtablezSamplerTest, Sample) {
const size_t test_element_size = 31;
+ const size_t test_key_size = 33;
+ const size_t test_value_size = 35;
SetHashtablezEnabled(true);
SetHashtablezSampleParameter(100);
int64_t num_sampled = 0;
int64_t total = 0;
double sample_rate = 0.0;
for (int i = 0; i < 1000000; ++i) {
- HashtablezInfoHandle h = Sample(test_element_size);
+ HashtablezInfoHandle h =
+ Sample(test_element_size,
+ /*key_size=*/test_key_size, /*value_size=*/test_value_size,
+
+ /*soo_capacity=*/0);
+
++total;
if (h.IsSampled()) {
++num_sampled;
@@ -275,7 +354,12 @@ TEST(HashtablezSamplerTest, Handle) {
auto& sampler = GlobalHashtablezSampler();
const int64_t test_stride = 41;
const size_t test_element_size = 39;
- HashtablezInfoHandle h(sampler.Register(test_stride, test_element_size));
+ const size_t test_key_size = 37;
+ const size_t test_value_size = 35;
+ HashtablezInfoHandle h(sampler.Register(test_stride, test_element_size,
+ /*key_size=*/test_key_size,
+ /*value_size=*/test_value_size,
+ /*soo_capacity=*/0));
auto* info = HashtablezInfoHandlePeer::GetInfo(&h);
info->hashes_bitwise_and.store(0x12345678, std::memory_order_relaxed);
@@ -351,18 +435,28 @@ TEST(HashtablezSamplerTest, MultiThreaded) {
for (int i = 0; i < 10; ++i) {
const int64_t sampling_stride = 11 + i % 3;
const size_t elt_size = 10 + i % 2;
- pool.Schedule([&sampler, &stop, sampling_stride, elt_size]() {
+ const size_t key_size = 12 + i % 4;
+ const size_t value_size = 13 + i % 5;
+ pool.Schedule([&sampler, &stop, sampling_stride, elt_size, key_size,
+ value_size]() {
std::random_device rd;
std::mt19937 gen(rd());
std::vector infoz;
while (!stop.HasBeenNotified()) {
if (infoz.empty()) {
- infoz.push_back(sampler.Register(sampling_stride, elt_size));
+ infoz.push_back(sampler.Register(sampling_stride, elt_size,
+ /*key_size=*/key_size,
+ /*value_size=*/value_size,
+ /*soo_capacity=*/0));
}
switch (std::uniform_int_distribution<>(0, 2)(gen)) {
case 0: {
- infoz.push_back(sampler.Register(sampling_stride, elt_size));
+ infoz.push_back(sampler.Register(sampling_stride, elt_size,
+ /*key_size=*/key_size,
+ /*value_size=*/value_size,
+
+ /*soo_capacity=*/0));
break;
}
case 1: {
diff --git a/yass/third_party/abseil-cpp/absl/container/internal/layout.h b/yass/third_party/abseil-cpp/absl/container/internal/layout.h
index 1bf739cc75..384929af49 100644
--- a/yass/third_party/abseil-cpp/absl/container/internal/layout.h
+++ b/yass/third_party/abseil-cpp/absl/container/internal/layout.h
@@ -81,9 +81,30 @@
// }
//
// The layout we used above combines fixed-size with dynamically-sized fields.
-// This is quite common. Layout is optimized for this use case and generates
-// optimal code. All computations that can be performed at compile time are
-// indeed performed at compile time.
+// This is quite common. Layout is optimized for this use case and attempts to
+// generate optimal code. To help the compiler do that in more cases, you can
+// specify the fixed sizes using `WithStaticSizes`. This ensures that all
+// computations that can be performed at compile time are indeed performed at
+// compile time. Note that sometimes the `template` keyword is needed. E.g.:
+//
+// using SL = L::template WithStaticSizes<1, 1>;
+//
+// void Use(unsigned char* p) {
+// // First, extract N and M.
+// // Using `prefix` we can access the first three arrays but not more.
+// //
+// // More details: The first element always has offset 0. `SL`
+// // has offsets for the second and third array based on sizes of
+// // the first and second array, specified via `WithStaticSizes`.
+// constexpr auto prefix = SL::Partial();
+// size_t n = *prefix.Pointer<0>(p);
+// size_t m = *prefix.Pointer<1>(p);
+//
+// // Now we can get a pointer to the final payload.
+// const SL layout(n, m);
+// double* a = layout.Pointer(p);
+// int* b = layout.Pointer(p);
+// }
//
// Efficiency tip: The order of fields matters. In `Layout` try to
// ensure that `alignof(T1) >= ... >= alignof(TN)`. This way you'll have no
@@ -107,7 +128,7 @@
// CompactString(const char* s = "") {
// const size_t size = strlen(s);
// // size_t[1] followed by char[size + 1].
-// const L layout(1, size + 1);
+// const L layout(size + 1);
// p_.reset(new unsigned char[layout.AllocSize()]);
// // If running under ASAN, mark the padding bytes, if any, to catch
// // memory errors.
@@ -125,14 +146,13 @@
//
// const char* c_str() const {
// // Equivalent to reinterpret_cast(p.get() + sizeof(size_t)).
-// // The argument in Partial(1) specifies that we have size_t[1] in front
-// // of the characters.
-// return L::Partial(1).Pointer(p_.get());
+// return L::Partial().Pointer(p_.get());
// }
//
// private:
-// // Our heap allocation contains a size_t followed by an array of chars.
-// using L = Layout;
+// // Our heap allocation contains a single size_t followed by an array of
+// // chars.
+// using L = Layout::WithStaticSizes<1>;
// std::unique_ptr p_;
// };
//
@@ -146,11 +166,12 @@
//
// The interface exported by this file consists of:
// - class `Layout<>` and its public members.
-// - The public members of class `internal_layout::LayoutImpl<>`. That class
-// isn't intended to be used directly, and its name and template parameter
-// list are internal implementation details, but the class itself provides
-// most of the functionality in this file. See comments on its members for
-// detailed documentation.
+// - The public members of classes `internal_layout::LayoutWithStaticSizes<>`
+// and `internal_layout::LayoutImpl<>`. Those classes aren't intended to be
+// used directly, and their name and template parameter list are internal
+// implementation details, but the classes themselves provide most of the
+// functionality in this file. See comments on their members for detailed
+// documentation.
//
// `Layout::Partial(count1,..., countm)` (where `m` <= `n`) returns a
// `LayoutImpl<>` object. `Layout layout(count1,..., countn)`
@@ -164,13 +185,14 @@
#include
#include
-#include
+#include
#include
#include
#include
#include
#include
+#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/debugging/internal/demangle.h"
#include "absl/meta/type_traits.h"
@@ -209,9 +231,6 @@ struct NotAligned> {
template
using IntToSize = size_t;
-template
-using TypeToSize = size_t;
-
template
struct Type : NotAligned {
using type = T;
@@ -308,7 +327,8 @@ using IsLegalElementType = std::integral_constant<
!std::is_volatile::type>::value &&
adl_barrier::IsPow2(AlignOf::value)>;
-template
+template
class LayoutImpl;
// Public base class of `Layout` and the result type of `Layout::Partial()`.
@@ -316,31 +336,49 @@ class LayoutImpl;
// `Elements...` contains all template arguments of `Layout` that created this
// instance.
//
-// `SizeSeq...` is `[0, NumSizes)` where `NumSizes` is the number of arguments
-// passed to `Layout::Partial()` or `Layout::Layout()`.
+// `StaticSizeSeq...` is an index_sequence containing the sizes specified at
+// compile-time.
+//
+// `RuntimeSizeSeq...` is `[0, NumRuntimeSizes)`, where `NumRuntimeSizes` is the
+// number of arguments passed to `Layout::Partial()` or `Layout::Layout()`.
+//
+// `SizeSeq...` is `[0, NumSizes)` where `NumSizes` is `NumRuntimeSizes` plus
+// the number of sizes in `StaticSizeSeq`.
//
// `OffsetSeq...` is `[0, NumOffsets)` where `NumOffsets` is
// `Min(sizeof...(Elements), NumSizes + 1)` (the number of arrays for which we
// can compute offsets).
-template
-class LayoutImpl, absl::index_sequence,
- absl::index_sequence> {
+template
+class LayoutImpl<
+ std::tuple, absl::index_sequence,
+ absl::index_sequence, absl::index_sequence,
+ absl::index_sequence> {
private:
static_assert(sizeof...(Elements) > 0, "At least one field is required");
static_assert(absl::conjunction...>::value,
"Invalid element type (see IsLegalElementType)");
+ static_assert(sizeof...(StaticSizeSeq) <= sizeof...(Elements),
+ "Too many static sizes specified");
enum {
NumTypes = sizeof...(Elements),
+ NumStaticSizes = sizeof...(StaticSizeSeq),
+ NumRuntimeSizes = sizeof...(RuntimeSizeSeq),
NumSizes = sizeof...(SizeSeq),
NumOffsets = sizeof...(OffsetSeq),
};
// These are guaranteed by `Layout`.
+ static_assert(NumStaticSizes + NumRuntimeSizes == NumSizes, "Internal error");
+ static_assert(NumSizes <= NumTypes, "Internal error");
static_assert(NumOffsets == adl_barrier::Min(NumTypes, NumSizes + 1),
"Internal error");
static_assert(NumTypes > 0, "Internal error");
+ static constexpr std::array kStaticSizes = {
+ StaticSizeSeq...};
+
// Returns the index of `T` in `Elements...`. Results in a compilation error
// if `Elements...` doesn't contain exactly one instance of `T`.
template
@@ -363,7 +401,7 @@ class LayoutImpl, absl::index_sequence,
template
using ElementType = typename std::tuple_element::type;
- constexpr explicit LayoutImpl(IntToSize... sizes)
+ constexpr explicit LayoutImpl(IntToSize... sizes)
: size_{sizes...} {}
// Alignment of the layout, equal to the strictest alignment of all elements.
@@ -389,7 +427,7 @@ class LayoutImpl, absl::index_sequence,
constexpr size_t Offset() const {
static_assert(N < NumOffsets, "Index out of bounds");
return adl_barrier::Align(
- Offset() + SizeOf>::value * size_[N - 1],
+ Offset() + SizeOf>::value * Size(),
ElementAlignment::value);
}
@@ -411,8 +449,7 @@ class LayoutImpl, absl::index_sequence,
return {{Offset()...}};
}
- // The number of elements in the Nth array. This is the Nth argument of
- // `Layout::Partial()` or `Layout::Layout()` (zero-based).
+ // The number of elements in the Nth array (zero-based).
//
// // int[3], 4 bytes of padding, double[4].
// Layout x(3, 4);
@@ -420,10 +457,15 @@ class LayoutImpl, absl::index_sequence,
// assert(x.Size<1>() == 4);
//
// Requires: `N < NumSizes`.
- template
+ template = 0>
+ constexpr size_t Size() const {
+ return kStaticSizes[N];
+ }
+
+ template = NumStaticSizes)> = 0>
constexpr size_t Size() const {
static_assert(N < NumSizes, "Index out of bounds");
- return size_[N];
+ return size_[N - NumStaticSizes];
}
// The number of elements in the array with the specified element type.
@@ -500,13 +542,8 @@ class LayoutImpl, absl::index_sequence,
// std::tie(ints, doubles) = x.Pointers(p);
//
// Requires: `p` is aligned to `Alignment()`.
- //
- // Note: We're not using ElementType alias here because it does not compile
- // under MSVC.
template
- std::tuple::type>*...>
- Pointers(Char* p) const {
+ auto Pointers(Char* p) const {
return std::tuple>*...>(
Pointer(p)...);
}
@@ -559,15 +596,10 @@ class LayoutImpl, absl::index_sequence,
//
// Requires: `p` is aligned to `Alignment()`.
//
- // Note: We're not using ElementType alias here because it does not compile
- // under MSVC.
+ // Note: We mark the parameter as unused because GCC detects it is not used
+ // when `SizeSeq` is empty [-Werror=unused-but-set-parameter].
template
- std::tuple::type>>...>
- Slices(Char* p) const {
- // Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63875 (fixed
- // in 6.1).
- (void)p;
+ auto Slices(ABSL_ATTRIBUTE_UNUSED Char* p) const {
return std::tuple>>...>(
Slice(p)...);
}
@@ -582,7 +614,7 @@ class LayoutImpl, absl::index_sequence,
constexpr size_t AllocSize() const {
static_assert(NumTypes == NumSizes, "You must specify sizes of all fields");
return Offset() +
- SizeOf>::value * size_[NumTypes - 1];
+ SizeOf>::value * Size();
}
// If built with --config=asan, poisons padding bytes (if any) in the
@@ -606,7 +638,7 @@ class LayoutImpl, absl::index_sequence,
// The `if` is an optimization. It doesn't affect the observable behaviour.
if (ElementAlignment::value % ElementAlignment::value) {
size_t start =
- Offset() + SizeOf>::value * size_[N - 1];
+ Offset() + SizeOf>::value * Size();
ASAN_POISON_MEMORY_REGION(p + start, Offset() - start);
}
#endif
@@ -635,47 +667,66 @@ class LayoutImpl, absl::index_sequence,
adl_barrier::TypeName>()...};
std::string res = absl::StrCat("@0", types[0], "(", sizes[0], ")");
for (size_t i = 0; i != NumOffsets - 1; ++i) {
- absl::StrAppend(&res, "[", size_[i], "]; @", offsets[i + 1], types[i + 1],
- "(", sizes[i + 1], ")");
+ absl::StrAppend(&res, "[", DebugSize(i), "]; @", offsets[i + 1],
+ types[i + 1], "(", sizes[i + 1], ")");
}
// NumSizes is a constant that may be zero. Some compilers cannot see that
// inside the if statement "size_[NumSizes - 1]" must be valid.
int last = static_cast(NumSizes) - 1;
if (NumTypes == NumSizes && last >= 0) {
- absl::StrAppend(&res, "[", size_[last], "]");
+ absl::StrAppend(&res, "[", DebugSize(static_cast(last)), "]");
}
return res;
}
private:
+ size_t DebugSize(size_t n) const {
+ if (n < NumStaticSizes) {
+ return kStaticSizes[n];
+ } else {
+ return size_[n - NumStaticSizes];
+ }
+ }
+
// Arguments of `Layout::Partial()` or `Layout::Layout()`.
- size_t size_[NumSizes > 0 ? NumSizes : 1];
+ size_t size_[NumRuntimeSizes > 0 ? NumRuntimeSizes : 1];
};
-template
+// Defining a constexpr static class member variable is redundant and deprecated
+// in C++17, but required in C++14.
+template
+constexpr std::array LayoutImpl<
+ std::tuple, absl::index_sequence,
+ absl::index_sequence, absl::index_sequence,
+ absl::index_sequence>::kStaticSizes;
+
+template
using LayoutType = LayoutImpl<
- std::tuple, absl::make_index_sequence,
- absl::make_index_sequence>;
+ std::tuple, StaticSizeSeq,
+ absl::make_index_sequence,
+ absl::make_index_sequence,
+ absl::make_index_sequence>;
-} // namespace internal_layout
+template
+class LayoutWithStaticSizes
+ : public LayoutType {
+ private:
+ using Super =
+ LayoutType;
-// Descriptor of arrays of various types and sizes laid out in memory one after
-// another. See the top of the file for documentation.
-//
-// Check out the public API of internal_layout::LayoutImpl above. The type is
-// internal to the library but its methods are public, and they are inherited
-// by `Layout`.
-template
-class Layout : public internal_layout::LayoutType {
public:
- static_assert(sizeof...(Ts) > 0, "At least one field is required");
- static_assert(
- absl::conjunction...>::value,
- "Invalid element type (see IsLegalElementType)");
-
// The result type of `Partial()` with `NumSizes` arguments.
template
- using PartialType = internal_layout::LayoutType;
+ using PartialType =
+ internal_layout::LayoutType;
// `Layout` knows the element types of the arrays we want to lay out in
// memory but not the number of elements in each array.
@@ -701,14 +752,18 @@ class Layout : public internal_layout::LayoutType {
// Note: The sizes of the arrays must be specified in number of elements,
// not in bytes.
//
- // Requires: `sizeof...(Sizes) <= sizeof...(Ts)`.
+ // Requires: `sizeof...(Sizes) + NumStaticSizes <= sizeof...(Ts)`.
// Requires: all arguments are convertible to `size_t`.
template
static constexpr PartialType Partial(Sizes&&... sizes) {
- static_assert(sizeof...(Sizes) <= sizeof...(Ts), "");
- return PartialType(std::forward(sizes)...);
+ static_assert(sizeof...(Sizes) + StaticSizeSeq::size() <= sizeof...(Ts),
+ "");
+ return PartialType(
+ static_cast(std::forward(sizes))...);
}
+ // Inherit LayoutType's constructor.
+ //
// Creates a layout with the sizes of all arrays specified. If you know
// only the sizes of the first N arrays (where N can be zero), you can use
// `Partial()` defined above. The constructor is essentially equivalent to
@@ -717,8 +772,69 @@ class Layout : public internal_layout::LayoutType {
//
// Note: The sizes of the arrays must be specified in number of elements,
// not in bytes.
- constexpr explicit Layout(internal_layout::TypeToSize... sizes)
- : internal_layout::LayoutType(sizes...) {}
+ //
+ // Implementation note: we do this via a `using` declaration instead of
+ // defining our own explicit constructor because the signature of LayoutType's
+ // constructor depends on RuntimeSizeSeq, which we don't have access to here.
+ // If we defined our own constructor here, it would have to use a parameter
+ // pack and then cast the arguments to size_t when calling the superclass
+ // constructor, similar to what Partial() does. But that would suffer from the
+ // same problem that Partial() has, which is that the parameter types are
+ // inferred from the arguments, which may be signed types, which must then be
+ // cast to size_t. This can lead to negative values being silently (i.e. with
+ // no compiler warnings) cast to an unsigned type. Having a constructor with
+ // size_t parameters helps the compiler generate better warnings about
+ // potential bad casts, while avoiding false warnings when positive literal
+ // arguments are used. If an argument is a positive literal integer (e.g.
+ // `1`), the compiler will understand that it can be safely converted to
+ // size_t, and hence not generate a warning. But if a negative literal (e.g.
+ // `-1`) or a variable with signed type is used, then it can generate a
+ // warning about a potentially unsafe implicit cast. It would be great if we
+ // could do this for Partial() too, but unfortunately as of C++23 there seems
+ // to be no way to define a function with a variable number of parameters of a
+ // certain type, a.k.a. homogeneous function parameter packs. So we're forced
+ // to choose between explicitly casting the arguments to size_t, which
+ // suppresses all warnings, even potentially valid ones, or implicitly casting
+ // them to size_t, which generates bogus warnings whenever literal arguments
+ // are used, even if they're positive.
+ using Super::Super;
+};
+
+} // namespace internal_layout
+
+// Descriptor of arrays of various types and sizes laid out in memory one after
+// another. See the top of the file for documentation.
+//
+// Check out the public API of internal_layout::LayoutWithStaticSizes and
+// internal_layout::LayoutImpl above. Those types are internal to the library
+// but their methods are public, and they are inherited by `Layout`.
+template
+class Layout : public internal_layout::LayoutWithStaticSizes<
+ absl::make_index_sequence<0>, Ts...> {
+ private:
+ using Super =
+ internal_layout::LayoutWithStaticSizes,
+ Ts...>;
+
+ public:
+ // If you know the sizes of some or all of the arrays at compile time, you can
+ // use `WithStaticSizes` or `WithStaticSizeSequence` to create a `Layout` type
+ // with those sizes baked in. This can help the compiler generate optimal code
+ // for calculating array offsets and AllocSize().
+ //
+ // Like `Partial()`, the N sizes you specify are for the first N arrays, and
+ // they specify the number of elements in each array, not the number of bytes.
+ template
+ using WithStaticSizeSequence =
+ internal_layout::LayoutWithStaticSizes;
+
+ template
+ using WithStaticSizes =
+ WithStaticSizeSequence>;
+
+ // Inherit LayoutWithStaticSizes's constructor, which requires you to specify
+ // all the array sizes.
+ using Super::Super;
};
} // namespace container_internal
diff --git a/yass/third_party/abseil-cpp/absl/container/internal/layout_benchmark.cc b/yass/third_party/abseil-cpp/absl/container/internal/layout_benchmark.cc
index 3af35e33ed..d6f2669760 100644
--- a/yass/third_party/abseil-cpp/absl/container/internal/layout_benchmark.cc
+++ b/yass/third_party/abseil-cpp/absl/container/internal/layout_benchmark.cc
@@ -15,6 +15,9 @@
// Every benchmark should have the same performance as the corresponding
// headroom benchmark.
+#include
+#include
+
#include "absl/base/internal/raw_logging.h"
#include "absl/container/internal/layout.h"
#include "benchmark/benchmark.h"
@@ -28,6 +31,8 @@ using ::benchmark::DoNotOptimize;
using Int128 = int64_t[2];
+constexpr size_t MyAlign(size_t n, size_t m) { return (n + m - 1) & ~(m - 1); }
+
// This benchmark provides the upper bound on performance for BM_OffsetConstant.
template
void BM_OffsetConstantHeadroom(benchmark::State& state) {
@@ -36,6 +41,15 @@ void BM_OffsetConstantHeadroom(benchmark::State& state) {
}
}
+template
+void BM_OffsetConstantStatic(benchmark::State& state) {
+ using L = typename Layout::template WithStaticSizes<3, 5, 7>;
+ ABSL_RAW_CHECK(L::Partial().template Offset<3>() == Offset, "Invalid offset");
+ for (auto _ : state) {
+ DoNotOptimize(L::Partial().template Offset<3>());
+ }
+}
+
template
void BM_OffsetConstant(benchmark::State& state) {
using L = Layout;
@@ -46,14 +60,74 @@ void BM_OffsetConstant(benchmark::State& state) {
}
}
+template
+void BM_OffsetConstantIndirect(benchmark::State& state) {
+ using L = Layout;
+ auto p = L::Partial(3, 5, 7);
+ ABSL_RAW_CHECK(p.template Offset<3>() == Offset, "Invalid offset");
+ for (auto _ : state) {
+ DoNotOptimize(p);
+ DoNotOptimize(p.template Offset<3>());
+ }
+}
+
+template
+size_t PartialOffset(size_t k);
+
+template <>
+size_t PartialOffset(size_t k) {
+ constexpr size_t o = MyAlign(MyAlign(3 * 1, 2) + 5 * 2, 4);
+ return MyAlign(o + k * 4, 8);
+}
+
+template <>
+size_t PartialOffset(size_t k) {
+ // No alignment is necessary.
+ return 3 * 16 + 5 * 4 + k * 2;
+}
+
+// This benchmark provides the upper bound on performance for BM_OffsetVariable.
+template
+void BM_OffsetPartialHeadroom(benchmark::State& state) {
+ size_t k = 7;
+ ABSL_RAW_CHECK(PartialOffset(k) == Offset, "Invalid offset");
+ for (auto _ : state) {
+ DoNotOptimize(k);
+ DoNotOptimize(PartialOffset(k));
+ }
+}
+
+template
+void BM_OffsetPartialStatic(benchmark::State& state) {
+ using L = typename Layout::template WithStaticSizes<3, 5>;
+ size_t k = 7;
+ ABSL_RAW_CHECK(L::Partial(k).template Offset<3>() == Offset,
+ "Invalid offset");
+ for (auto _ : state) {
+ DoNotOptimize(k);
+ DoNotOptimize(L::Partial(k).template Offset<3>());
+ }
+}
+
+template
+void BM_OffsetPartial(benchmark::State& state) {
+ using L = Layout;
+ size_t k = 7;
+ ABSL_RAW_CHECK(L::Partial(3, 5, k).template Offset<3>() == Offset,
+ "Invalid offset");
+ for (auto _ : state) {
+ DoNotOptimize(k);
+ DoNotOptimize(L::Partial(3, 5, k).template Offset<3>());
+ }
+}
+
template
size_t VariableOffset(size_t n, size_t m, size_t k);
template <>
size_t VariableOffset(size_t n, size_t m,
size_t k) {
- auto Align = [](size_t n, size_t m) { return (n + m - 1) & ~(m - 1); };
- return Align(Align(Align(n * 1, 2) + m * 2, 4) + k * 4, 8);
+ return MyAlign(MyAlign(MyAlign(n * 1, 2) + m * 2, 4) + k * 4, 8);
}
template <>
@@ -94,6 +168,75 @@ void BM_OffsetVariable(benchmark::State& state) {
}
}
+template
+size_t AllocSize(size_t x);
+
+template <>
+size_t AllocSize(size_t x) {
+ constexpr size_t o =
+ Layout::Partial(3, 5, 7)
+ .template Offset();
+ return o + sizeof(Int128) * x;
+}
+
+template <>
+size_t AllocSize(size_t x) {
+ constexpr size_t o =
+ Layout::Partial(3, 5, 7)
+ .template Offset();
+ return o + sizeof(int8_t) * x;
+}
+
+// This benchmark provides the upper bound on performance for BM_AllocSize
+template
+void BM_AllocSizeHeadroom(benchmark::State& state) {
+ size_t x = 9;
+ ABSL_RAW_CHECK(AllocSize(x) == Size, "Invalid size");
+ for (auto _ : state) {
+ DoNotOptimize(x);
+ DoNotOptimize(AllocSize(x));
+ }
+}
+
+template
+void BM_AllocSizeStatic(benchmark::State& state) {
+ using L = typename Layout::template WithStaticSizes<3, 5, 7>;
+ size_t x = 9;
+ ABSL_RAW_CHECK(L(x).AllocSize() == Size, "Invalid offset");
+ for (auto _ : state) {
+ DoNotOptimize(x);
+ DoNotOptimize(L(x).AllocSize());
+ }
+}
+
+template