ARST打卡第266周
lc3040_相同分数的最大操作数目II USENIX ATC ‘23 - RubbleDB:CPU-Efficient Replication with NVMe-oF 链抽象/互操作性/全链 raft_apply慢导致业务不可用的情况分析
Algorithm
lc3040_相同分数的最大操作数目II
思路:
这里把删除看成左右双指针移动。
然后最开始有3种操作选择导致有3种值,选择了值之后, 后面的操作都根据值来选定记忆回溯即可。
|
|
其中一开始报错:
Line 2: Char 40: note: default constructor of ‘Solution’ is implicitly deleted because field ‘cache’ has a deleted default constructor 2 | unordered_map<pair<int, int>, int> cache;
问GPT4o:
The error you’re encountering arises because the default constructor of
unordered_mapcannot handle thepair<int, int>type directly as a key without a custom hash function. This issue can be resolved by defining a custom hash function for thepair<int, int>.Here’s how you can resolve this:
- Define a custom hash function for
pair<int, int>.- Specify this custom hash function in the
unordered_map.Here’s an example of how you can do it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29#include <iostream> #include <unordered_map> #include <utility> // For std::pair #include <functional> // For std::hash // Define a custom hash function for pair<int, int> struct pair_hash { template <class T1, class T2> std::size_t operator() (const std::pair<T1, T2> &pair) const { return std::hash<T1>()(pair.first) ^ std::hash<T2>()(pair.second); } }; class Solution { public: std::unordered_map<std::pair<int, int>, int, pair_hash> cache; Solution() = default; // Other member functions... }; int main() { Solution sol; // Example usage sol.cache[std::make_pair(1, 2)] = 42; std::cout << sol.cache[std::make_pair(1, 2)] << std::endl; return 0; }In this example,
pair_hashis defined to hash astd::pair<int, int>. This hash function is then used in theunordered_mapdeclaration in theSolutionclass. This way, theunordered_mapcan properly handlepair<int, int>keys, and the default constructor ofSolutionwill work correctly.Explanation:
pair_hash: A custom hash function struct that uses thestd::hashfunctions for the elements of the pair and combines them with XOR.cache: Declared as anunordered_mapwithstd::pair<int, int>as the key type andintas the value type, usingpair_hashfor hashing.Solution() = default: Explicitly defaulted constructor forSolutionclass.By applying this custom hash function, you enable the
unordered_mapto handlestd::pair<int, int>keys properly, resolving the compilation error.
后面 TLE 了… 全是 1000.. 确实没有考虑到这种 corner case.
超出时间限制 : 520 / 549 个通过的测试用例
最后执行的输入: nums = [1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,
感觉这个 cornor case 在提醒我,是不是可以服用一下缓存?
先试一下不严谨的假设所有的 l,r 的 key 都是相同的 sum.
不行,还是 TLE 在这里,所以不用尝试 l,r,sum 的 key 的 cache 了。
看了答案,发现差不了太多,所以再剪枝试试。
吐血,因为用容器导致卡 TLE 了,然后用数组就能过…基本和题解一样,但还是学习一下题解写法
|
|
Review
USENIX ATC ‘23 - RubbleDB:CPU-Efficient Replication with NVMe-oF
通过 Nvme-oF 远程复制其他副本的 rocksdb 的 compaction 完成的 SST 来节约 CPU 和 CPU-IO.
也就是通过更复杂的管理程序+网络IO来换取 CPU 和 CPU-IO.
在 CPU 限制的复制集群是有效的。
但是在 IO 限制的集群,可能效果不是那么明显。
而且个人认为对于 Raft + Rocksdb 3副本的场景。 这种虽然有点像 Install Snapshot,但是又好像需要和 Rocksdb 内部状态进行耦合,导致了更复杂的管理问题。 并且让三副本的独立性变得关联起来了,对网络故障的抗风险能力估计又得重新评估了。
因此个人决定性能提升不是很大,以及CPU不是瓶颈的话,还是不建议采用这种方案。 但是这种方案的探索,用网络IO换取CPU和CPU-IO的行为和思路还是值得肯定和学习的。
Tips
其实本质还是统一平台。
Share
raft apply慢导致业务不可用的情况分析
如果 raft 中 leader 因为一些因素导致程序运行很慢,可能 apply 比 follower 慢 (follower,leader 一起异步 apply ),导致业务写超时。
但是这种情况又不会产生 leader 转换,因此需要及时排查其他卡慢因素(cpu被其他程序占用等), 防止因 leader apply 慢而出现的业务不可用的现象。