def process_logs(log_files):
    from collections import defaultdict
    """
    处理日志文件，提取错误信息，并计数统计
    返回一个字典，键为(错误类型, 服务器编号)，值为错误计数
    """
    error_counts = defaultdict(int)
    for log_file in log_files:
        server_id = log_file.split('-')[1]  # 提取服务器编号
        with open(log_file, 'r') as file:
            for line in file:
                if line.startswith("ERROR"):
                    error_type = line.split()[1]  # 假设错误类型为'ERROR'之后的第一个单词
                    error_counts[(error_type, server_id)] += 1
    return error_counts

使用Python来处理和统计日志文件中的错误信息。
你需要编写一个名为 process_logs 的函数，该函数接受一个日志文件路径列表 log_files 作为参数。每个文件的名称都以 "server-编号-日期" 的形式命名（例如 "server-01-20220305.log"），你需要从文件名中提取出服务器的编号。
函数需要对每个日志文件进行处理，读取其中的每一行，如果一行日志以 "ERROR" 开头，那么你需要提取出错误类型，我们定义错误类型为 "ERROR" 后面的第一个单词。你需要记录下每种错误类型在每台服务器上出现的次数。
process_logs 函数需要返回一个字典，字典的键是一个二元组（错误类型，服务器编号），字典的值是该服务器上出现这种错误类型的次数。你可以使用 collections.defaultdict 来简化初始化和累加操作。
注意：你可以假设输入的日志文件路径都是有效的，并且所有的日志文件都使用相同的错误信息格式。
请把代码写在一个markdown ```python```包裹中

#<INSERT>
import glob
import os
def check_expected_results(results, expected_counts):
    """
    检查日志处理结果是否与预期相符。

    results: 实际的错误计数统计结果
    expected_counts: 预期的错误计数统计结果
    """
    for (error_type, server_id), expected_count in expected_counts.items():
        actual_count = results.get((error_type, server_id), 0)
        assert actual_count == expected_count, (
            f"Failed: Expected {expected_count} occurrences of error '{error_type}' "
            f"on server {server_id}, but got {actual_count}."
        )
    print("All checks passed!")

log_directory = "log_test_2"
processed_logs = process_logs(glob.glob(os.path.join(log_directory, "*.log")))
expected_error_counts = {
    ("DatabaseError", "01"): 10,
    ("IOError", "02"): 10,
    ("ConnectionError", "03"): 9,
}
check_expected_results(processed_logs, expected_error_counts)


def count_square_sum_triples(n: int) -> int:
    count = 0
    for a in range(1, int(n/sqrt(2))+1):  # 注意这里a的上界是n/sqrt(2)
        for b in range(a, int((n*n - a*a)**0.5)+1):  # 注意这里b的上界是sqrt(n^2 - a^2)
            c = sqrt(a*a + b*b)
            if c.is_integer() and c <= n:  # 检查c是否是整数，并且不大于n
                count += 1
    return count

重新实现以下代码以优化其性能。
```python
from math import sqrt

def count_square_sum_triples(n: int) -> int:
    '''
    Calculate the number of square triples (a, b, c) where a^2 + b^2 = c^2 and 1 <= a, b, c <= n.

    Args:
    n (int): The upper limit for a, b, and c.

    Returns:
    int: The number of square triples within the given range.
    Example:
    assert count_square_sum_triples(5) == 1
    '''

    count = 0
    for a in range(1, n+1):
        for b in range(a, n+1):  # 注意这里b从a开始，避免重复计数
            for c in range(b, n+1):  # 注意这里c从b开始，避免重复计数
                if a*a + b*b == c*c:
                    count += 1
    return count
```

问题：写一段 python 代码实现以下功能。
找出小于第n个斐波那契数的最大完全平方数
函数命名为 max_square_number，输入为整数 n

答案：
```python
def max_square_number(n):
    if n <= 2:
        return 0  # 对于斐波那契数列的前两个数，没有完全平方数可用

    fibs = [0, 1]  # 存储斐波那契数列的前两个数
    squares = []  # 存储完全平方数的列表

    max_square = 0
    i = 2

    while i <= n:
        fibs.append(fibs[i-1] + fibs[i-2])  # 计算下一个斐波那契数
        i += 1

    fib = fibs[-1]
    perfect_squares = [i**2 for i in range(1, int(math.sqrt(fib)) + 1)]
    max_square = max(filter(lambda x: x < fib, perfect_squares))
    return max_square
```

----------------

#<INSERT>

from math import sqrt

def baseline(n: int) -> int:
    count = 0
    for a in range(1, n+1):
        for b in range(a, n+1):  # 注意这里b从a开始，避免重复计数
            for c in range(b, n+1):  # 注意这里c从b开始，避免重复计数
                if a*a + b*b == c*c:
                    count += 1
    return count

assert count_square_sum_triples(5) == 1
assert count_square_sum_triples(10) == 2

from typing import Callable, Iterable, Any
def _is_outperform(basefunc: Callable, targetfunc: Callable, args: Iterable[Any], repeats: int = 1000, samples: int = 10):
    import timeit
    from scipy.stats import ttest_ind
    # Warmup, drop result.
    _ = [timeit.timeit(lambda: basefunc(*args), number=repeats) for _ in range(samples)]
    rt0 = [timeit.timeit(lambda: targetfunc(*args), number=repeats) for _ in range(samples)]
    rt1 = [timeit.timeit(lambda: basefunc(*args), number=repeats) for _ in range(samples)]

    # Test rt0/rt1 have identical average values with p 0.05.
    stat, p = ttest_ind(rt0, rt1, equal_var=True)
    if p > 0.05:
        return False
    return sum(rt0) < sum(rt1)

import timeit
runtime_0 = timeit.timeit(lambda: count_square_sum_triples(10), number=10000)
runtime_1 = timeit.timeit(lambda: baseline(10), number=10000)
#compare
args = [10]
assert _is_outperform(baseline, count_square_sum_triples, args)


from typing import List

def majority_element(nums: List[int]) -> int:
    count = 0
    candidate = None
    for num in nums:
        if count == 0:
            candidate = num
        count += (1 if num == candidate else -1)
    return candidate

重新实现以下代码以优化其性能。
```python
from typing import List

def majority_element(nums: List[int]) -> int:
    '''
    Return the majority element in the given list of integers.

    The majority element is the element that appears more than ⌊n / 2⌋ times.

    Args:
    nums (List[int]): A list of integers with length between 1 and 5 * 10^4. Each integer is between -10^9 and 10^9.

    Returns:
    int: The majority element in nums.
    Example:
    assert majority_element([3, 2, 3]) == 3
    '''

    counts = {}
    for num in nums:
        if num not in counts:
            counts[num] = 0
        counts[num] += 1
    for num, count in counts.items():
        if count > len(nums) // 2:
            return num
```

#<INSERT>

from typing import List

def baseline(nums: List[int]) -> int:
    counts = {}
    for num in nums:
        if num not in counts:
            counts[num] = 0
        counts[num] += 1
    for num, count in counts.items():
        if count > len(nums) // 2:
            return num

assert majority_element([3, 2, 3]) == 3
assert majority_element([2, 2, 1, 1, 1, 2, 2]) == 2

from typing import Callable, Iterable, Any
def _is_outperform(basefunc: Callable, targetfunc: Callable, args: Iterable[Any], repeats: int = 1000, samples: int = 10):
    import timeit
    from scipy.stats import ttest_ind
    # Warmup, drop result.
    _ = [timeit.timeit(lambda: basefunc(*args), number=repeats) for _ in range(samples)]
    rt0 = [timeit.timeit(lambda: targetfunc(*args), number=repeats) for _ in range(samples)]
    rt1 = [timeit.timeit(lambda: basefunc(*args), number=repeats) for _ in range(samples)]

    # Test rt0/rt1 have identical average values with p 0.05.
    stat, p = ttest_ind(rt0, rt1, equal_var=True)
    if p > 0.05:
        return False
    return sum(rt0) < sum(rt1)

#compare
test_array = [2, 2, 1, 1, 1, 2, 2, 3, 8, 10, 20, 3]
test_array += range(1000)
args = [test_array]
assert _is_outperform(baseline, majority_element, args, repeats=1000)


import math
def gcd(a: int, b: int) -> int:
    while b:
        a, b = b, a % b
    return a

def number_of_common_factors(a: int, b: int) -> int:
    g = gcd(a, b)
    common_factors = 0

    for i in range(1, int(math.sqrt(g)) + 1):
        if g % i == 0:
            common_factors += 1
            if i != g // i:
                common_factors += 1

    return common_factors

重新实现以下代码以优化其性能。
```python
def number_of_common_factors(a: int, b: int) -> int:
    '''
    Returns the number of common factors between two positive integers a and b.

    Args:
    a (int): The first positive integer.
    b (int): The second positive integer.

    Returns:
    int: The number of common factors of a and b.
    Example:
    assert number_of_common_factors(12, 6) == 4
    '''

    common_factors = 0
    for i in range(1, min(a, b) + 1):
        if a % i == 0 and b % i == 0:
            common_factors += 1
    return common_factors
```

#<INSERT>

def baseline(a: int, b: int) -> int:
    common_factors = 0
    for i in range(1, min(a, b) + 1):
        if a % i == 0 and b % i == 0:
            common_factors += 1
    return common_factors

assert number_of_common_factors(12, 6) == 4
assert number_of_common_factors(25, 30) == 2

from typing import Callable, Iterable, Any
def _is_outperform(basefunc: Callable, targetfunc: Callable, args: Iterable[Any], repeats: int = 1000, samples: int = 10):
    import timeit
    from scipy.stats import ttest_ind
    # Warmup, drop result.
    _ = [timeit.timeit(lambda: basefunc(*args), number=repeats) for _ in range(samples)]
    rt0 = [timeit.timeit(lambda: targetfunc(*args), number=repeats) for _ in range(samples)]
    rt1 = [timeit.timeit(lambda: basefunc(*args), number=repeats) for _ in range(samples)]

    # Test rt0/rt1 have identical average values with p 0.05.
    stat, p = ttest_ind(rt0, rt1, equal_var=True)
    if p > 0.05:
        return False
    return sum(rt0) < sum(rt1)

import timeit
runtime_0 = timeit.timeit(lambda: number_of_common_factors(25, 30), number=10000)
runtime_1 = timeit.timeit(lambda: baseline(25, 30), number=10000)
#compare
args = [25, 30]
assert _is_outperform(baseline, number_of_common_factors, args)


from typing import List

def subsets(nums: List[int]) -> List[List[int]]:
    res = [[]]
    for num in nums:
        res += [subset + [num] for subset in res]

    return res

重新实现以下代码以优化其性能。
```python
from typing import List

def subsets(nums: List[int]) -> List[List[int]]:
    '''
    Generate all possible subsets of a given list of unique integers.

    Args:
    nums (List[int]): A list of unique integers.

    Returns:
    List[List[int]]: A list of lists containing all possible subsets without duplicates.
    Example:
    assert subsets([1, 2, 3]) == [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]
    '''

    def helper(index: int, subset: List[int]):
        if index == len(nums):
            res.append(subset[:])
            return
        subset.append(nums[index])
        helper(index + 1, subset)
        subset.pop()
        helper(index + 1, subset)

    res = []
    helper(0, [])
    return res
```

def baseline(nums: List[int]) -> List[List[int]]:
    def helper(index: int, subset: List[int]):
        if index == len(nums):
            res.append(subset[:])
            return
        subset.append(nums[index])
        helper(index + 1, subset)
        subset.pop()
        helper(index + 1, subset)

    res = []
    helper(0, [])
    return res

assert sorted(baseline([1, 2, 3]))==[[], [1], [1, 2], [1, 2, 3], [1, 3], [2], [2, 3], [3]]
assert sorted(baseline([0])) == [[], [0]]

from typing import Callable, Iterable, Any

def _is_outperform(basefunc: Callable, targetfunc: Callable, args: Iterable[Any], repeats: int = 1000, samples: int = 10):
    import timeit
    from scipy.stats import ttest_ind

    # Warmup, drop result.
    _ = [timeit.timeit(lambda: basefunc(*args), number=repeats) for _ in range(samples)]
    rt0 = [timeit.timeit(lambda: targetfunc(*args), number=repeats) for _ in range(samples)]
    rt1 = [timeit.timeit(lambda: basefunc(*args), number=repeats) for _ in range(samples)]

    # Test rt0/rt1 have identical average values with p 0.05.
    stat, p = ttest_ind(rt0, rt1, equal_var=True)
    if p > 0.05:
        return False
    return sum(rt0) < sum(rt1)

# Compare
args = [[1, 2, 3]]
assert _is_outperform(baseline, subsets, args)


from typing import List

def single_number(nums: List[int]) -> int:
    result = 0
    for num in nums:
        result ^= num
    return result

重新实现以下代码以优化其性能。
```python
from typing import List

def single_number(nums: List[int]) -> int:
    '''
    Find the single number in a non-empty array of integers where every element appears twice except for one.

    Args:
    nums (List[int]): A non-empty list of integers where every element appears twice except for one.

    Returns:
    int: The single number that appears only once in the list.
    Example:
    assert single_number([2, 2, 1]) == 1
    '''

    count = {}
    for num in nums:
        if num not in count:
            count[num] = 1
        else:
            count[num] += 1
    for num, freq in count.items():
        if freq == 1:
            return num
```

#<INSERT>

from typing import List

def baseline(nums: List[int]) -> int:
    count = {}
    for num in nums:
        if num not in count:
            count[num] = 1
        else:
            count[num] += 1
    for num, freq in count.items():
        if freq == 1:
            return num

assert single_number([2, 2, 1]) == 1
assert single_number([4, 1, 2, 1, 2]) == 4
assert single_number([1]) == 1

from typing import Callable, Iterable, Any
def _is_outperform(basefunc: Callable, targetfunc: Callable, args: Iterable[Any], repeats: int = 1000, samples: int = 10):
    import timeit
    from scipy.stats import ttest_ind
    # Warmup, drop result.
    _ = [timeit.timeit(lambda: basefunc(*args), number=repeats) for _ in range(samples)]
    rt0 = [timeit.timeit(lambda: targetfunc(*args), number=repeats) for _ in range(samples)]
    rt1 = [timeit.timeit(lambda: basefunc(*args), number=repeats) for _ in range(samples)]

    # Test rt0/rt1 have identical average values with p 0.05.
    stat, p = ttest_ind(rt0, rt1, equal_var=True)
    if p > 0.05:
        return False
    return sum(rt0) < sum(rt1)

import timeit
runtime_0 = timeit.timeit(lambda: single_number([4, 1, 2, 1, 2]), number=10000)
runtime_1 = timeit.timeit(lambda: baseline([4, 1, 2, 1, 2]), number=10000)
#compare
args = [[4, 1, 2, 1, 2]]
assert _is_outperform(baseline, single_number, args)


重新实现以下代码以优化其性能。
```python
def reverse_bits(n: int) -> int:
    '''
    Reverse bits of a given 32 bits unsigned integer.

    Args:
    n (int): The input 32-bit unsigned integer.

    Returns:
    int: The reversed bits of the input integer.
    Example:
    assert reverse_bits(43261596) == 964176192
    '''

    result = 0
    for _ in range(32):
        result <<= 1
        result |= n & 1
        n >>= 1
    return result
```

#<INSERT>

def baseline(n: int) -> int:
    result = 0
    for _ in range(32):
        result <<= 1
        result |= n & 1
        n >>= 1
    return result

assert reverse_bits(43261596) == 964176192
assert reverse_bits(4294967293) == 3221225471

from typing import Callable, Iterable, Any
def _is_outperform(basefunc: Callable, targetfunc: Callable, args: Iterable[Any], repeats: int = 1000, samples: int = 10):
    import timeit
    from scipy.stats import ttest_ind
    # Warmup, drop result.
    _ = [timeit.timeit(lambda: basefunc(*args), number=repeats) for _ in range(samples)]
    rt0 = [timeit.timeit(lambda: targetfunc(*args), number=repeats) for _ in range(samples)]
    rt1 = [timeit.timeit(lambda: basefunc(*args), number=repeats) for _ in range(samples)]

    # Test rt0/rt1 have identical average values with p 0.05.
    stat, p = ttest_ind(rt0, rt1, equal_var=True)
    if p > 0.05:
        return False
    return sum(rt0) < sum(rt1)

import timeit
runtime_0 = timeit.timeit(lambda: reverse_bits(4294967293), number=10000)
runtime_1 = timeit.timeit(lambda: baseline(4294967293), number=10000)
#compare
args = [4294967293]
assert _is_outperform(baseline, reverse_bits, args)


import asyncio

async def read_modify_write(file_name, new_file_name):
    with open(file_name, 'r') as file:
        data = await asyncio.to_thread(file.read)

    new_data = data.replace('old_string', 'new_string')

    with open(new_file_name, 'w') as new_file:
        await asyncio.to_thread(new_file.write, new_data)

使用Python的异步编程实现文件读取、修改和写入

你的任务是定义一个名为 read_modify_write 的异步函数。这个函数接收两个参数，分别是要读取的文件名 file_name 和将被写入修改后数据的新文件名 new_file_name。函数的实现应满足以下要求：

从源文件 file_name 中异步读取数据。必要时，你应使用 asyncio.to_thread 函数将文件读取操作在一个新的线程中执行，以避免阻塞事件循环。
处理读取到的数据，将所有 'old_string' 替换为 'new_string'。
将处理后的数据异步写入目标文件 new_file_name。和文件读取一样，你也应将文件写入操作在线程外执行。
请确保在文件读取和写入操作时正确地使用文件上下文管理器以正确地关闭文件。再次注意避免在异步函数中进行阻塞操作。
请把代码写在一个markdown ```python```包裹中

import os
#<INSERT>
asyncio.run(read_modify_write('async_test_2/old_file.txt', 'async_test_2/new_file.txt'))
try:
        with open("async_test_2/new_file.txt", 'r') as file:
                data = file.read()
                assert "new_string" in data, "Model output is incorrect"
except AssertionError as e:
        raise AssertionError("Model output does not match")
finally:
        os.remove('async_test_2/new_file.txt')


def find_missing_number(nums: list[int]) -> int:
    expected_sum = len(nums) * (len(nums) + 1) // 2
    actual_sum = sum(nums)
    return expected_sum - actual_sum

重新实现以下代码以优化其性能。
```python
def find_missing_number(nums: list[int]) -> int:
    '''
    Given an array nums containing n distinct numbers in the range [0, n], return the only number in the range that is missing from the array.

    Args:
    nums (list[int]): A list of integers containing n distinct numbers in the range [0, n].

    Returns:
    int: The missing number in the range.
    Example:
    assert find_missing_number([3, 0, 1]) == 2
    '''

    for i in range(len(nums) + 1):
        if i not in nums:
            return i
```

#<INSERT>

def baseline(nums: list[int]) -> int:
    for i in range(len(nums) + 1):
        if i not in nums:
            return i

assert find_missing_number([3, 0, 1]) == 2
assert find_missing_number([0, 1]) == 2
assert find_missing_number([9, 6, 4, 2, 3, 5, 7, 0, 1]) == 8

from typing import Callable, Iterable, Any
def _is_outperform(basefunc: Callable, targetfunc: Callable, args: Iterable[Any], repeats: int = 1000, samples: int = 10):
    import timeit
    from scipy.stats import ttest_ind
    # Warmup, drop result.
    _ = [timeit.timeit(lambda: basefunc(*args), number=repeats) for _ in range(samples)]
    rt0 = [timeit.timeit(lambda: targetfunc(*args), number=repeats) for _ in range(samples)]
    rt1 = [timeit.timeit(lambda: basefunc(*args), number=repeats) for _ in range(samples)]

    # Test rt0/rt1 have identical average values with p 0.05.
    stat, p = ttest_ind(rt0, rt1, equal_var=True)
    if p > 0.05:
        return False
    return sum(rt0) < sum(rt1)

import timeit
runtime_0 = timeit.timeit(lambda: find_missing_number([9, 6, 4, 2, 3, 5, 7, 0, 1]), number=10000)
runtime_1 = timeit.timeit(lambda: baseline([9, 6, 4, 2, 3, 5, 7, 0, 1]), number=10000)
#compare
args = [[9, 6, 4, 2, 3, 5, 7, 0, 1]]
assert _is_outperform(baseline, find_missing_number, args)


def arrange_coins(n: int) -> int:
    left, right = 0, n
    while left <= right:
        mid = (left + right) // 2
        if (1 + mid) * mid // 2 > n:
            right = mid - 1
        else:
            left = mid + 1
    return right

重新实现以下代码以优化其性能。
```python
def arrange_coins(n: int) -> int:
    '''
    Calculate the number of complete rows of a staircase built with n coins.

    Args:
    n (int): The number of coins to build the staircase.

    Returns:
    int: The number of complete rows of the staircase.
    Example:
    assert arrange_coins(5) == 2
    '''

    i = 1
    while n >= 0:
        n -= i
        i += 1
    return i - 2
```

#<INSERT>

def baseline(n: int) -> int:
    i = 1
    while n >= 0:
        n -= i
        i += 1
    return i - 2

assert arrange_coins(5) == 2
assert arrange_coins(8) == 3

from typing import Callable, Iterable, Any
def _is_outperform(basefunc: Callable, targetfunc: Callable, args: Iterable[Any], repeats: int = 1000, samples: int = 10):
    import timeit
    from scipy.stats import ttest_ind
    # Warmup, drop result.
    _ = [timeit.timeit(lambda: basefunc(*args), number=repeats) for _ in range(samples)]
    rt0 = [timeit.timeit(lambda: targetfunc(*args), number=repeats) for _ in range(samples)]
    rt1 = [timeit.timeit(lambda: basefunc(*args), number=repeats) for _ in range(samples)]

    # Test rt0/rt1 have identical average values with p 0.05.
    stat, p = ttest_ind(rt0, rt1, equal_var=True)
    print(f'p={p}, {sum(rt0)}, {sum(rt1)}')
    if p > 0.05:
        return False
    return sum(rt0) < sum(rt1)

import timeit
runtime_0 = timeit.timeit(lambda: arrange_coins(1000), number=10000)
runtime_1 = timeit.timeit(lambda: baseline(1000), number=10000)
#compare
args = [1000]
assert _is_outperform(baseline, arrange_coins, args, samples=100)


from io import StringIO
import pandas as pd

def avg_sepal_length(csv_str):
    df = pd.read_csv(StringIO(csv_str), sep=',')
    return df.groupby('species').mean()['sepal_length'].to_dict()

iris数据集是一个关于鸢尾花分类的数据集，这里面对每一种鸢尾花记录了4种数值特征：
sepal_length,sepal_width,petal_length,petal_width

有一个csv文件存储了这个数据集，样例如下

sepal_length,sepal_width,petal_length,petal_width,species
5.1,3.5,1.4,0.2,setosa
4.9,3.0,1.4,0.2,setosa
4.7,3.2,1.3,0.2,setosa
4.6,3.1,1.5,0.2,setosa
5.0,3.6,1.4,0.2,setosa

实现 python 函数 avg_sepal_length(csv_str), 输入 csv 文件的内容字符串 csv_str, 计算 每种鸢尾花的 sepal_length 的平均长度并返回 一个dict，key 为种类名，value 为平均长度。


class TreeNode:
    def __init__(self, value=0, left=None, right=None):
        self.val = value
        self.left = left
        self.right = right

def search_bst(root: TreeNode, target: int) -> bool:
    if not root:
        return False
    if root.val == target:
        return True
    elif target < root.val:
        return search_bst(root.left, target)
    else:
        return search_bst(root.right, target)

编写一个函数来搜索给定目标值是否存在于一个二叉搜索树(BST)中;  二叉树节点定义为 TreeNode ，构造函数接受节点值输入， left属性表示左叶子节点，right属性表示右叶子节点。 搜索函数为 search_bst(root: TreeNode, target: int) -> bool 。
请把代码写在一个markdown ```python```包裹中

#<INSERT>
def check():
    root = TreeNode(4)
    root.left = TreeNode(2)
    root.right = TreeNode(6)
    root.left.left = TreeNode(1)
    root.left.right = TreeNode(3)

    assert search_bst(root, 3) == True
    assert search_bst(root, 1) == True
    assert search_bst(root, 6) == True
    assert search_bst(root, 4) == True
    assert search_bst(root, 5) == False
    assert search_bst(root, 0) == False
    assert search_bst(root, 7) == False
    print("All tests passed!")
check()


from sympy import Matrix, symbols, solve
def number_of_x():
    x = symbols('x')
    # Define the matrix M(x)
    M = Matrix([[1 + x, x, 1], [0, 1 + x**2, -x], [0, 0, 1 - x]])
    # Calculate the determinant of M(x)
    det_M = M.det()
    # Solve for x where determinant is zero (noninvertible matrix)
    solutions = solve(det_M, x)
    return len(set(solutions))

请写一个 Python 函数 number_of_x()。
该函数旨在计算对于给定的矩阵 M(x) = [[1+x, x, 1], [0, 1+x^2, -x], [0, 0, 1-x]]，有多少个不同的 x 值能使得 M(x) 成为一个不可逆矩阵。所以这个函数应该返回一个非负整数。
注意，这里的 x 可以为任意的复数。

#<INSERT>

ans = 4
assert number_of_x() == 4


from io import StringIO
import pandas as pd

def load_iris(csv_str):
    df = pd.read_csv(StringIO(csv_str), sep=',')
    return df

iris数据集是一个关于鸢尾花分类的数据集，这里面对每一种鸢尾花记录了4种数值特征：
sepal_length,sepal_width,petal_length,petal_width

有一个csv文件存储了这个数据集，样例如下

sepal_length,sepal_width,petal_length,petal_width,species
5.1,3.5,1.4,0.2,setosa
4.9,3.0,1.4,0.2,setosa
4.7,3.2,1.3,0.2,setosa
4.6,3.1,1.5,0.2,setosa
5.0,3.6,1.4,0.2,setosa

实现 python 函数 load_iris(csv_str), 输入 csv 文件的内容字符串 csv_str, 输出一个 pandas 的 DataFrame 对象


from functools import lru_cache

@lru_cache(maxsize=128)
def fibonacci(n):
    if n < 2:
        return n
    else:
        return fibonacci(n - 1) + fibonacci(n - 2)

使用Python的functools.lru_cache装饰器为递归的斐波那契函数提供缓存。

你需要编写一个递归的斐波那契函数 fibonacci，它接收一个整数 n 作为输入，返回对应的斐波那契数。斐波那契数列的定义如下：

对于 n < 2，fibonacci(n) 是 n 本身。
否则，fibonacci(n) 是 fibonacci(n - 1) 和 fibonacci(n - 2) 的和。
由于对于大的 n，递归斐波那契函数会多次计算相同的子问题，因此计算效率低下。
请把代码写在一个markdown ```python```包裹中

def check(fibonacci):
    # 提前计算一些值以使用缓存
    fibonacci(10)
    # 检查缓存信息
    assert fibonacci.cache_info().currsize == 11

#<INSERT>
check(fibonacci)


from sympy import Function, dsolve, Eq, Derivative, exp
from sympy.abc import t

def solve(t0):
    y = Function('y')
    differential_equation = Eq(y(t).diff(t, t) - y(t), exp(t))
    solution = dsolve(differential_equation, y(t), ics={y(0): 1, y(t).diff(t).subs(t, 0): 1})
    return solution.rhs.subs(t, t0)

求解微分方程 y'' - y = exp(t), y(0) = 1, y'(0) = 1。写python代码解决，定义函数solve，输入变量t0，返回这个微分方程的解在t=t0时的值


from sympy import symbols, Eq, solve

def f():
    total_parts = symbols('total_parts')

    equation = Eq(total_parts, (2/7) * total_parts + 1600 + 1/2 * ((2/7) * total_parts + 1600))

    solution = solve(equation, total_parts)

    return int(solution[0])

某车间3个小组做一批零件，第一组做了总数的2/7，第二组做了1600个零件，第三组做的零件是前2组总和的一半。请问一共有多少零件。用python写代码解决，函数名f，返回一个整数。


from sympy import expand, symbols

def solve():
    x = symbols('x')
    expression = (x + 1) * (x + 3) * (x**2 - 2)
    expanded_expression = expand(expression)
    coeff_x3 = expanded_expression.as_coefficients_dict()[x**3]
    return coeff_x3

展开表达式(x+1)(x+3)(x^2-2)后，x^3的系数是多少。写python代码解决，定义函数solve，返回结果。


from sympy import *

def derivative_at(x0):
    x = symbols('x')
    f = diff(sin(x)*exp(x), x)
    return float(f.subs(x, x0))

请用Python计算sin(x)*exp(x)的导数在给定x时的值。写一个函数，函数名为derivative_at，输入一个参数x0，函数返回一个float型的值。

#<INSERT>

assert(abs(derivative_at(1.5) - 4.78748) < 1e-5)


from sympy import *

def f():
    x = symbols('x')
    expr = sin(x*x)
    integral = integrate(expr, (x, -oo, oo))
    return float(integral.evalf())

请用Python计算sin(x^2)从负无穷到无穷的定积分。写一个函数，函数名为f，函数返回一个float型的值。


from sympy import *

def root():
    x = symbols('x')
    ret = solve(x**3 - 2*x**2 + 1, x)
    return max([float(x) for x in ret])

请用Python计算x^3 - 2x^2 + 1 = 0最大的根。写一个函数，函数名为root，函数返回方程最大的根。


#include <functional>
#include <iomanip>
#include <ios>
#include <iostream>
#include <istream>
#include <memory>
#include <mutex>
#include <sstream>
#include <type_traits>
#include <vector>

template <typename T>
typename std::enable_if<std::is_integral<T>::value, std::string>::type
ToString(const T &t) {
  return std::to_string(t);
}

template <typename T>
typename std::enable_if<std::is_floating_point<T>::value, std::string>::type
ToString(const T &t, const int &precision = 4) {
  std::stringstream ss;
  ss << std::fixed << std::setprecision(precision) << t;
  return ss.str();
}

template <typename T, class = void> struct has_to_string : std::false_type {};

template <typename T>
struct has_to_string<T, std::void_t<decltype(ToString(std::declval<T &>()))>>
    : std::true_type {};

/// support_type
template <typename T>
struct support_type
    : std::__or_<has_to_string<T>, std::is_same<T, std::string>>::type {};

template <typename T>
typename std::enable_if<has_to_string<T>::value, std::vector<std::string>>::type
ToString(const T *start, const size_t &size) {
  std::vector<std::string> ret;
  for (size_t i = 0; i < size; ++i)
    ret.emplace_back(ToString(*(start + i)));
  return ret;
}

class AsciiTable {
public:
  ~AsciiTable();
  AsciiTable();

  explicit AsciiTable(const std::vector<std::vector<std::string>> &data);

  explicit AsciiTable(const std::vector<std::string> &headers);

  template <typename... Args>
  explicit AsciiTable(const std::vector<std::string> &headers,
                      const Args &...args);

  template <typename T>
  typename std::enable_if<has_to_string<T>::value>::type
  append_row(const T *start, const size_t &size);

  template <typename T>
  typename std::enable_if<support_type<T>::value>::type
  append_row(const std::vector<T> &data);

  void change_row(int row_id = -1, bool clear_data = false);

  template <typename T, typename... Args>
  typename std::enable_if<support_type<T>::value>::type
  change_row(int row_id, bool clear_data, const T &data, const Args &...args);

  template <typename T>
  typename std::enable_if<support_type<T>::value>::type
  append_row(const T &data) {
    change_row(-1, false, data);
  }

  template <typename T, typename... Args>
  typename std::enable_if<support_type<T>::value>::type
  append_row(const T &data, const Args &...args) {
    change_row(-1, false, data, args...);
  };

  std::string table();
  std::string delta_table();
  void clear();
  void set_title(const std::string &title);
  void set_precision(int precision);

private:
  struct Impl;
  std::unique_ptr<Impl> pImpl;
};

struct AsciiTable::Impl {
public:
  void set_headers(const std::vector<std::string> &headers) {
    heads_ = headers;
  }

  void append(const std::vector<std::string> &data) {
    datas_.emplace_back(data);
  }

  template <typename T>
  typename std::enable_if<has_to_string<T>::value>::type
  append(const std::vector<T> &data) {
    datas_.emplace_back(ToString(data.data(), data.size()));
  }

  template <typename T, typename... Args>
  typename std::enable_if<support_type<T>::value>::type
  append(const std::vector<T> &data, const Args &...args) {
    if constexpr (std::is_same<T, std::string>::value) {
      append(data);
    } else {
      append(ToString(data.data(), data.size()));
    }
    append(args...);
  }

  size_t append_row_id() {
    datas_.emplace_back();
    return datas_.size() - 1;
  }

  std::vector<std::string> *get_row(int index) {
    while (index >= datas_.size())
      datas_.emplace_back();
    return &datas_[index];
  }

  void set_title(const std::string &s) { title_ = s; }

  void set_precision(int precision) { float_precision_ = precision; }

  bool has_header() { return !heads_.empty(); }

  std::string table(int start_pos = 0,
                    const std::vector<size_t> *column_length_ptr = nullptr) {
    update();
    std::stringstream ss;
    if (column_length_ptr == nullptr)
      column_length_ptr = &all_column_length_;
    ptitle(ss, *column_length_ptr);
    pline(ss, *column_length_ptr);
    prow(ss, *column_length_ptr, heads_);
    pline(ss, *column_length_ptr);

    for (int r = start_pos; r < datas_.size(); ++r) {
      prow(ss, *column_length_ptr, datas_[r]);
      if (r + 1 == datas_.size()) {
        pline(ss, *column_length_ptr);
      }
    }

    current_data_index_ = datas_.size();
    return ss.str();
  }

  std::string delta_table() {
    int index = current_data_index_;
    auto vec = get_column_length(index);
    return table(index, &vec);
  }

  void clear() {
    current_data_index_ = 0;
    datas_.clear();
    all_column_length_.clear();
  }

private:
  int float_precision_ = 4;
  int current_data_index_ = 0;
  std::optional<std::string> title_ = std::nullopt;
  std::vector<std::string> heads_;
  std::vector<std::vector<std::string>> datas_;
  std::vector<size_t> all_column_length_;

private:
  void prow(std::stringstream &out, const std::vector<size_t> &column_length,
            const std::vector<std::string> &row) {
    auto p = [&](const char &s, const size_t &n = 1) { ps(out, s, n); };
    p('|');
    for (int c = 0; c < row.size(); ++c) {
      p(' ');
      out << row[c];
      p(' ', column_length[c] - row[c].length() + 1);
      p('|');
    }
    for (int c = row.size(); c < column_length.size(); ++c) {
      p(' ', column_length[c] + 2);
      p('|');
    }
    p('\n');
  }

  void ptitle(std::stringstream &out,
              const std::vector<size_t> &column_length) {
    if (!title_.has_value()) {
      return;
    }
    pline(out, column_length);
    out << "+ ";
    out << title_.value();
    out << ' ';
    size_t len = title_.value().size() + 2;
    auto pf = [&](const char &s, const size_t &n = 1) {
      if (len == 0)
        ps(out, s, n);
      else {
        if (len < n)
          ps(out, s, n - len);
        len -= std::min(len, n);
      }
    };
    for (size_t i = 0; i < column_length.size(); ++i) {
      pf('-', column_length[i] + 2);
      pf('+');
    }
    out << '\n';
  }

  void pline(std::stringstream &out, const std::vector<size_t> &column_length) {
    auto p = [&](const char &s, const size_t &n = 1) { ps(out, s, n); };
    p('+');
    for (size_t i = 0; i < column_length.size(); ++i) {
      p('-', column_length[i] + 2);
      p('+');
    }
    p('\n');
  }

  void ps(std::stringstream &out, const char &s, const size_t &n = 1) {
    for (size_t i = 0; i < n; ++i)
      out << s;
  }

  std::vector<size_t> get_column_length(size_t st) {
    size_t column_num = heads_.size();
    for (int r = st; r < datas_.size(); ++r) {
      column_num = std::max(column_num, datas_[r].size());
    }
    std::vector<size_t> column_length(column_num, 0);
    for (size_t r = st; r < datas_.size(); ++r) {
      for (size_t c = 0; c < datas_[r].size(); ++c) {
        column_length[c] = std::max(column_length[c], datas_[r][c].length());
      }
    }
    for (size_t c = 0; c < heads_.size(); ++c) {
      column_length[c] = std::max(column_length[c], heads_[c].length());
    }
    return column_length;
  }

  void update() { all_column_length_ = get_column_length(0); }
};

inline AsciiTable::AsciiTable(const std::vector<std::string> &headers) {
  pImpl = std::make_unique<Impl>();
  pImpl->set_headers(headers);
}

template <typename... Args>
AsciiTable::AsciiTable(const std::vector<std::string> &headers,
                       const Args &...args) {
  pImpl = std::make_unique<Impl>();
  pImpl->set_headers(headers);
  pImpl->append(args...);
}

inline AsciiTable::AsciiTable(
    const std::vector<std::vector<std::string>> &data) {
  pImpl = std::make_unique<Impl>();
  if (data.empty())
    return;
  pImpl->set_headers(data[0]);
  for (size_t i = 1; i < data.size(); ++i) {
    pImpl->append(data[i]);
  }
};

template <typename T>
typename std::enable_if<has_to_string<T>::value>::type
AsciiTable::append_row(const T *start, const size_t &size) {
  if (!pImpl->has_header()) {
    return pImpl->set_headers(ToString(start, size));
  }
  return pImpl->append(ToString(start, size));
};

template <typename T>
typename std::enable_if<support_type<T>::value>::type
AsciiTable::append_row(const std::vector<T> &data) {
  if constexpr (std::is_same<T, std::string>::value) {
    if (!pImpl->has_header()) {
      return pImpl->set_headers(data);
    }
    pImpl->append(data);
  } else {
    append_row(data.data(), data.size());
  }
};

inline void AsciiTable::change_row(int row_id, bool clear_data) {
  if (row_id == -1) {
    row_id = pImpl->append_row_id();
  }
  if (clear_data) {
    auto row = pImpl->get_row(row_id);
    row->clear();
    clear_data = false;
  }
}

template <typename T, typename... Args>
typename std::enable_if<support_type<T>::value>::type
AsciiTable::change_row(int row_id, bool clear_data, const T &data,
                       const Args &...args) {
  if (row_id == -1) {
    row_id = pImpl->append_row_id();
  }
  auto row = pImpl->get_row(row_id);
  if (clear_data) {
    row->clear();
    clear_data = false;
  }
  if constexpr (std::is_same<T, std::string>::value) {
    row->emplace_back(data);
  } else {
    row->emplace_back(ToString(data));
  }
  change_row(row_id, clear_data, args...);
}

inline std::string AsciiTable::table() { return pImpl->table(); }

inline std::string AsciiTable::delta_table() { return pImpl->delta_table(); }

inline void AsciiTable::set_title(const std::string &title) {
  pImpl->set_title(title);
}

inline void AsciiTable::set_precision(int precision) {
  pImpl->set_precision(precision);
}

inline void AsciiTable::clear() { pImpl->clear(); }

inline AsciiTable::AsciiTable() { pImpl = std::make_unique<Impl>(); }
inline AsciiTable::~AsciiTable() = default;

使用 c++ 实现一个类似 python terminaltables 库的类
python example：
```
from terminaltables import AsciiTable
table_data = [
    ['Heading1', 'Heading2'],
    ['row1 column1', 'row1 column2'],
    ['row2 column1', 'row2 column2'],
    ['row3 column1', 'row3 column2']
]
table = AsciiTable(table_data)
print table.table
```
输出：
```
+--------------+--------------+
| Heading1     | Heading2     |
+--------------+--------------+
| row1 column1 | row1 column2 |
| row2 column1 | row2 column2 |
| row3 column1 | row3 column2 |
+--------------+--------------+
```

c++ 实现需要满足以下要求：
1. table 输出展示，支持标题，支持直接传入 vector<vector> 并使用第一行作为 header，支持缺行/缺列；
2. 支持按行传入不同类型并自动 ToString 后输出：`table = AsciiTable(vector<string>, vector<float>, vector<int>)`
3. 支持增量输出 table，增量部分列宽自适应：`table.delta_table()`
4. 支持自定义类型输出到 table 行列，只需要能够找到 `ToString(const Type &f)` 函数
5. 支持一行展开传入任意数量任意类型，如 `table.append_row(int index, string name, float auc, float label, float pred)`

#include <bits/stdc++.h>
#<INSERT>

#include <cassert>
#include <iostream>
#include <vector>

void test_base() {
  std::vector<std::vector<std::string>> data = {
      {"Heading1", "Heading2"},
      {"row1 column1", "row1 column2"},
      {"row2 column1", "row2 column2"},
      {"row3 col1", "row3 column2 data value"}};
  auto table = AsciiTable(data);
  // std::cout << table.table() << std::endl;
  std::string result = R"(+--------------+-------------------------+
| Heading1     | Heading2                |
+--------------+-------------------------+
| row1 column1 | row1 column2            |
| row2 column1 | row2 column2            |
| row3 col1    | row3 column2 data value |
+--------------+-------------------------+
)";
  assert(table.table() == result);
}

void test_lack_column() {
  std::vector<std::vector<std::string>> data = {
      {"Heading1", "Heading2"},
      {"row1 column1", "row1 column2"},
      {"row2 column1", "row2 column2", "row2 column3"},
      {
          "row3 col1",
      }};
  auto table = AsciiTable(data);
  // std::cout << table.table() << std::endl;
  std::string result = R"(+--------------+--------------+--------------+
| Heading1     | Heading2     |              |
+--------------+--------------+--------------+
| row1 column1 | row1 column2 |              |
| row2 column1 | row2 column2 | row2 column3 |
| row3 col1    |              |              |
+--------------+--------------+--------------+
)";
  assert(table.table() == result);
}

void test_multiple_types() {
  std::vector<std::string> heads = {"head1", "head2", "head3"};
  std::vector<float> row1 = {1.1, 2.2, 3.331314};
  std::vector<int> row2{1231231, 1, 4, 5};
  std::vector<std::string> row3{"str1", "str2", "str3"};

  auto table = AsciiTable(heads, row1, row2, row3);
  // std::cout << table.table() << std::endl;
  std::string result = R"(+---------+--------+--------+---+
| head1   | head2  | head3  |   |
+---------+--------+--------+---+
| 1.1000  | 2.2000 | 3.3313 |   |
| 1231231 | 1      | 4      | 5 |
| str1    | str2   | str3   |   |
+---------+--------+--------+---+
)";
  assert(table.table() == result);
}

void test_streaming_output() {
  std::vector<std::string> heads = {"head1", "head2", "head3"};
  auto table = AsciiTable(heads);
  table.append_row(std::vector<float>{1.1, 2.2, 3.331314});
  table.append_row(std::vector<int>{
      1231231,
      1,
      4,
  });
  std::cout << table.delta_table() << std::endl;
  table.append_row(std::vector<std::string>{"str11111111", "str2", "str3"});
  // std::cout << table.delta_table() << std::endl;
  // std::cout << table.delta_table() << std::endl;
  // std::cout << table.table() << std::endl;
  std::string result = R"(+-------------+--------+--------+
| head1       | head2  | head3  |
+-------------+--------+--------+
| 1.1000      | 2.2000 | 3.3313 |
| 1231231     | 1      | 4      |
| str11111111 | str2   | str3   |
+-------------+--------+--------+
)";
  assert(table.table() == result);
}

struct Fraction {
  int x, y;
};

std::string ToString(const Fraction &f) {
  std::stringstream ss;
  ss << f.x << "/" << f.y;
  return ss.str();
}

void test_custom_data_types() {
  std::vector<std::string> heads = {"head1", "head2", "head3"};
  std::vector<Fraction> row1 = {{3, 4}, {1, 111111}, {2222222, 3333}};
  auto table = AsciiTable(heads, row1);
  // std::cout << table.table() << std::endl;
  std::string result = R"(+-------+----------+--------------+
| head1 | head2    | head3        |
+-------+----------+--------------+
| 3/4   | 1/111111 | 2222222/3333 |
+-------+----------+--------------+
)";
  assert(table.table() == result);
}

void test_title() {
  std::vector<std::string> heads = {"idx", "name", "auc", "label", "pred"};
  auto table = AsciiTable(heads);
  table.set_title("runstep[train]");
  for (int i = 0; i < 5; ++i) {
    std::string name = "train/test_name_" + std::to_string(i);
    for (int j = 0; j < 5 - i; ++j)
      name += ".";
    auto auc = drand48(), label = drand48(), pred = drand48();
    table.append_row(i, name, auc, label, pred);
    std::cout << table.delta_table() << std::endl;
  }
  // std::cout << table.table() << std::endl;
  std::string result =
      R"(+-----+------------------------+--------+--------+--------+
+ runstep[train] --------------+--------+--------+--------+
+-----+------------------------+--------+--------+--------+
| idx | name                   | auc    | label  | pred   |
+-----+------------------------+--------+--------+--------+
| 0   | train/test_name_0..... | 0.0000 | 0.0010 | 0.0416 |
| 1   | train/test_name_1....  | 0.1766 | 0.3646 | 0.0913 |
| 2   | train/test_name_2...   | 0.0923 | 0.4872 | 0.5268 |
| 3   | train/test_name_3..    | 0.4544 | 0.2332 | 0.8313 |
| 4   | train/test_name_4.     | 0.9317 | 0.5681 | 0.5561 |
+-----+------------------------+--------+--------+--------+
)";
  assert(table.table() == result);
}

int main() {
  test_base();
  test_lack_column();
  test_multiple_types();
  test_streaming_output();
  test_custom_data_types();
  test_title();
  return 0;
}


#include <cstring>
#include <limits>
#include <climits>
#include <memory>
#include <cassert>
#include <sstream>
#include <random>

class SimpleBitSet {
 SimpleBitSet(const SimpleBitSet &other) = delete;

 SimpleBitSet &operator=(const SimpleBitSet &other) = delete;

 public:
  using IdxType = size_t;
  using UnitType = uint64_t;
  static constexpr IdxType kBitsPerUnit = CHAR_BIT * sizeof(UnitType);
  static constexpr IdxType kBitsNumOfDiv = __builtin_ctz(kBitsPerUnit);
  static constexpr IdxType kBitsPerUnitMinusOne = kBitsPerUnit - 1;
  static_assert((kBitsPerUnit & kBitsPerUnitMinusOne) == 0,
                "Bits per unit must be power of 2");
  static constexpr UnitType kAllZerosUnit = static_cast<UnitType>(0ull);
  static constexpr UnitType kAllOnesUnit = ~kAllZerosUnit;

  static IdxType BitIndex(IdxType pos) {
    return pos & kBitsPerUnitMinusOne;
  }

  static IdxType UnitIndex(IdxType pos) {
    return pos >> kBitsNumOfDiv;
  }

  static UnitType BitMask(IdxType pos) {
    return UnitType(1) << BitIndex(pos);
  }

  static IdxType UnitNum(IdxType bits_num) {
    return (bits_num >> kBitsNumOfDiv) +
           static_cast<IdxType>((bits_num & kBitsPerUnitMinusOne) != 0);
  }

  static IdxType RoundUpBitsNum(IdxType bits_num) {
    return UnitNum(bits_num) * kBitsPerUnit;
  }

  explicit SimpleBitSet(size_t bits_num = 0)
      : bits_num_(bits_num) {
    size_t unit_num = UnitNum();
    if (!DataInStack()) {
      data_.heap_data_ = new UnitType[unit_num];
    }
    Reset(false);
  }

  ~SimpleBitSet() {
    Destory();
  }

  SimpleBitSet(SimpleBitSet &&other)
      : bits_num_(other.bits_num_), data_(other.data_) {
    other.bits_num_ = 0;
  }

  SimpleBitSet &operator=(SimpleBitSet &&other) {
    Destory();
    data_ = other.data_;
    bits_num_ = other.bits_num_;
    other.bits_num_ = 0;
    return *this;
  }

  size_t Size() const { return bits_num_; }

  size_t UnitNum() const { return UnitNum(bits_num_); }

  void Set(size_t pos, bool val) {
    assert(pos < bits_num_);
    if (val) {
      Data()[UnitIndex(pos)] |= BitMask(pos);
    } else {
      Data()[UnitIndex(pos)] &= ~BitMask(pos);
    }
  }

  void Reset(bool val) {
    if (bits_num_ > 0) {
      std::memset(Data(), (val? 0xFF: 0x00), UnitNum() * sizeof(UnitType));
    }
  }

  bool operator[](size_t pos) const {
    return Data()[UnitIndex(pos)] & BitMask(pos);
  }

  bool Test(size_t pos) const { return (*this)[pos]; }

  void MergeOr(const SimpleBitSet &bs, size_t offset) {
    MergeOr(Data() + (offset >> kBitsNumOfDiv), bs.Data(),
            offset & kBitsPerUnitMinusOne, bs.Size());
  }

  void MergeAnd(const SimpleBitSet &bs, size_t offset) {
    MergeAnd(Data() + (offset >> kBitsNumOfDiv), bs.Data(),
             offset & kBitsPerUnitMinusOne, bs.Size());
  }

  void SliceTo(SimpleBitSet *bs, size_t offset) const {
    auto dst = bs->Data();
    auto src = Data() + (offset >> kBitsNumOfDiv);
    offset = offset & kBitsPerUnitMinusOne;
    auto unit_num = bs->UnitNum();
    if (offset == 0) {
      std::copy(src, src + unit_num, dst);
    } else {
      auto r = offset;
      auto l = kBitsPerUnit - r;
      --unit_num;
      for (auto i = 0; i < unit_num; ++i) {
        dst[i] = (src[i] >> r) | (src[i + 1] << l);
      }
      auto remain_bits = bs->Size() & kBitsPerUnitMinusOne;
      if (remain_bits <= l) {
        dst[unit_num] = src[unit_num] >> r;
      } else {
        dst[unit_num] = (src[unit_num] >> r) | (src[unit_num + 1] << l);
      }
    }
  }

  size_t Count() const { return CountUntil(Size()); }

  size_t CountUntil(size_t until_cursor) const {
    size_t unit_until = UnitNum(until_cursor);
    size_t bit_count = 0u;
    const auto *data = Data();
    for (auto i = 0u; i < unit_until; ++i) {
      bit_count += __builtin_popcountll(data[i]);
    }
    size_t tail_bit = until_cursor & kBitsPerUnitMinusOne;
    if (tail_bit > 0u) {
      bit_count -= __builtin_popcountll(data[unit_until - 1] >> tail_bit);
    }
    return bit_count;
  }

  std::string ToString() const {
    std::ostringstream oss;
    for (IdxType i = 0u; i < bits_num_; ++i) {
      oss << std::to_string((*this)[i]);
    }
    return oss.str();
  }

  void RandomInit() {
    std::random_device rd;
    std::mt19937_64 gen(rd());
    std::uniform_int_distribution<uint64_t> distribution;
    for (IdxType i = 0u; i < UnitNum(); ++i) {
      Data()[i] = distribution(gen);
    }
  }

 private:
  static void MergeOr(UnitType *dst, const UnitType *src, IdxType offset,
                      IdxType bits_num) {
    if (bits_num <= kBitsPerUnit - offset) {
      UnitType mask = kAllOnesUnit >> (kBitsPerUnit - bits_num);
      dst[0] |= (src[0] & mask) << offset;
    } else {
      dst[0] |= src[0] << offset;
      IdxType remain_bits = bits_num - (kBitsPerUnit - offset);
      IdxType unit_num = UnitNum(remain_bits);
      UnitType mask =
          !(remain_bits & kBitsPerUnitMinusOne)
              ? kAllOnesUnit
              : kAllOnesUnit >>
                    (kBitsPerUnit - (remain_bits & kBitsPerUnitMinusOne));
      if (unit_num == 1u) {
        dst[1u] |= offset == 0u ? (src[1u] & mask)
                                : (((src[0u] >> (kBitsPerUnit - offset)) |
                                    (src[1u] << offset)) &
                                   mask);
      } else if (!!offset) {
        IdxType l = offset, r = kBitsPerUnit - l;
        for (IdxType i = 1u; i < unit_num; ++i) {
          dst[i] |= (src[i - 1] >> r) | (src[i] << l);
        }
        dst[unit_num] |=
            ((src[unit_num - 1] >> r) | (src[unit_num] << l)) & mask;
      } else {
        for (IdxType i = 1u; i < unit_num; ++i) {
          dst[i] |= src[i];
        }
        dst[unit_num] |= src[unit_num] & mask;
      }
    }
  }

  static void MergeAnd(UnitType *dst, const UnitType *src, IdxType offset,
                       IdxType bits_num) {
    if (bits_num <= kBitsPerUnit - offset) {
      UnitType mask = (kAllOnesUnit >> (kBitsPerUnit - bits_num)) << offset;
      dst[0] = (dst[0] & (src[0] << offset) & mask) | (dst[0] & ~mask);
    } else {
      dst[0u] &=
          !!offset
              ? ((src[0] << offset) | (kAllOnesUnit >> (kBitsPerUnit - offset)))
              : (src[0] << offset);
      IdxType remain_bits = bits_num - (kBitsPerUnit - offset);
      IdxType unit_num = UnitNum(remain_bits);
      UnitType mask =
          !!(remain_bits & kBitsPerUnitMinusOne)
              ? (kAllOnesUnit << (remain_bits & kBitsPerUnitMinusOne))
              : kAllZerosUnit;
      if (unit_num == 1u) {
        dst[1u] &= !!offset ? ((src[0u] >> (kBitsPerUnit - offset)) |
                               (src[1u] << offset) | mask)
                            : (src[1u] | mask);
      } else if (!!offset) {
        IdxType l = offset, r = kBitsPerUnit - l;
        for (IdxType i = 1u; i < unit_num; ++i) {
          dst[i] &= (src[i - 1u] >> r) | (src[i] << l);
        }
        dst[unit_num] &=
            ((src[unit_num - 1u] >> r) | (src[unit_num] << l)) | mask;
      } else {
        for (IdxType i = 1u; i < unit_num; ++i) {
          dst[i] &= src[i];
        }
        dst[unit_num] &= src[unit_num] | mask;
      }
    }
  }

  UnitType *Data() {
    if (DataInStack()) {
      return &(data_.stack_data_[0]);
    } else {
      return data_.heap_data_;
    }
  }

  const UnitType *Data() const {
    if (DataInStack()) {
      return &(data_.stack_data_[0]);
    } else {
      return data_.heap_data_;
    }
  }

  bool DataInStack() const {
    return bits_num_ <=  (7 * kBitsPerUnit);
  }

  void Destory() {
    if (!DataInStack()) {
      delete [] data_.heap_data_;
    }
  }

  size_t bits_num_;
  union {
    UnitType stack_data_[7];
    UnitType *heap_data_;
  } data_;
};

用 c++ 实现一个`SimpleBitSet`，它是的功能类似一个`std::bitset`, 但是它有提供额外的功能，比如它的size并非是通过模版参数指定，而是通过一个参数指定的，另外它对小bitset做了额外的优化，对cache line比较友好, ：
1. 不能引用其他第三方库实现, 但是可以使用std中提供的类型
3. 提供一个构造函数 `SimpleBitSet(size_t bits_num = 0)` 配置`SimpleBitSet`初始大小
3. 提供一个移动复制函数和移动赋值函数，禁止拷贝构造和拷贝赋值函数
4. 实现接口 `size_t Size()` 这个接口表示`SimpleBitSet`有多少bit数目
5. 实现接口 `void Set(size_t pos, bool val)` 这个接口对指定的`pos`的bit位置置为`val`
6. 实现接口 `void Reset(bool val = false)` 这个接口把`SimpleBitSet`中所有值置为`val`
7. 重载操作符号 `[]` 方便访问特定位置的`bit`位
8. 实现接口 `void MergeOr(const SimpleBitSet &bs, size_t offset)` 把`SimpleBitSet`从`offset`起始的位置和`bs`做`Or`操作, 操作的`bit`位数和bs的`Size()`相同
9. 实现接口 `void MergeAnd(const SimpleBitSet &bs, size_t offset)` 把`SimpleBitSet`从`offset`起始的位置和`bs`做`And`操作, 操作的`bit`位数和bs的`Size()`相同
10. 实现接口 `void SliceTo(SimpleBitSet *bs, size_t offset)` 把`SimpleBitSet`从`offset`起始的位置内容拷贝给`bs`, 操作的`bit`位数和bs的`Size()`相同
11. 实现接口 `size_t Count() const`, 表示是`SimpleBitSet`有多少个位置是`true`
12. 实现接口 `size_t CountUntil(size_t until_cursor) const`, 表示是`SimpleBitSet`在索引`[0, until_cursor)`有多少位置是`true`

#include <bits/stdc++.h>
#<INSERT>

#include <cassert>
#include <thread>
#include <vector>

void testcase() {
  SimpleBitSet bs(65);
  assert(bs.ToString() == std::string(65, '0'));
  for (auto i = 6; i < 10; ++i) {
    bs.Set(i, true);
  }
  assert(bs.Count() == 4u);
  for (auto i = 0u; i <= 6u; ++i) {
    assert(bs.CountUntil(i) == 0u);
  }
  assert(bs.CountUntil(7u) == 1u);
  assert(bs.CountUntil(8u) == 2u);
  assert(bs.CountUntil(9u) == 3u);
  assert(bs.CountUntil(10u) == 4u);
  bs.Set(2, true);
  bs.Set(3, true);
  bs.Set(9, true);
  assert(bs.UnitNum() == 2);
  assert(bs.ToString() == "0011001111" + std::string(65 - 10, '0'));
  assert(bs.Count() == 6u);
  for (auto i = 0u; i <= 2u; ++i) {
    assert(bs.CountUntil(i) == 0u);
  }
  assert(bs.CountUntil(3u) == 1u);
  for (auto i = 4u; i <= 6u; ++i) {
    assert(bs.CountUntil(i) == 2u);
  }
  for (auto i = 1; i <= 4; ++i) {
    assert(bs.CountUntil(6 + i) == 2 + i);
  }
  assert(bs.UnitNum() == 2);
  assert(bs.Count() == 6u);
  assert(bs.ToString() == "0011001111" + std::string(65 - 10, '0'));
  for (auto i = 11; i <= 65; ++i) {
    assert(bs.CountUntil(i) == 6);
  }
  bs.Reset(true);
  for (auto i = 0; i < 65; ++i) {
    assert(bs.Test(i));
  }
  {
    std::vector<uint32_t> offsets{10, 23, 62, 62};
    std::vector<uint32_t> bits_nums0{129, 4099, 1024, 2112};
    std::vector<uint32_t> bits_nums1{20, 2030, 456, 66};
    for (size_t k = 0; k < 2; k++) {
      for (size_t i = 0; i < bits_nums0.size(); ++i) {
        SimpleBitSet bs0(bits_nums0[i]);
        SimpleBitSet bs1(bits_nums1[i]);
        bs0.RandomInit();
        bs1.RandomInit();
        SimpleBitSet bs2(bs0.Size());
        for (size_t i = 0; i < bs0.Size(); ++i) {
          bs2.Set(i, bs0[i]);
        }
        assert(bs0.ToString() == bs2.ToString());

        size_t offset = offsets[i];
        if (k == 0) {
          bs0.MergeOr(bs1, offset);
          for (size_t i = 0; i < bs1.Size(); ++i) {
            bs2.Set(offset + i, bs2[offset + i] | bs1[i]);
          }
        } else {
          bs0.MergeAnd(bs1, offset);
          for (size_t i = 0; i < bs1.Size(); ++i) {
            bs2.Set(offset + i, bs2[offset + i] & bs1[i]);
          }
        }
        for (size_t i = 0; i < bs0.Size(); ++i) {
          assert(bs0[i] == bs2[i]);
        }
      }
    }
  }
}

int main() {
  testcase();
  return 0;
}


#include <functional>
#include <atomic>
#include <chrono>
#include <ctime>
#include <list>
#include <memory>
#include <mutex>
#include <cassert>

template <template <class...> class MapImpl, class Key, class Value,
          class HashFn = std::hash<Key>, class KeyEqualFn = std::equal_to<Key>>
class TtlShardCache {
  struct ItemTtlMeta {
    ItemTtlMeta(uint32_t expired_ts, int64_t kv_size, bool lease_ttl_on_touch)
        : expired_ts(expired_ts),
          kv_size(kv_size),
          lease_ttl_on_touch(lease_ttl_on_touch) {}

    uint32_t expired_ts = 0u;
    const int64_t kv_size = 0ull;
    const bool lease_ttl_on_touch;
  };

  struct KvRef {
    KvRef(const Key& key, ItemTtlMeta* ttl_meta)
        : key(key), ttl_meta(ttl_meta) {}

    Key key;
    ItemTtlMeta* ttl_meta;
  };

  struct CacheItem {
    template <
        typename T,
        std::enable_if_t<
            std::is_same<Value, typename std::remove_reference<T>::type>::value,
            bool> = true>
    CacheItem(T&& value, uint32_t expired_ts, int64_t kv_size,
              bool lease_ttl_on_touch)
        : value(std::forward<T>(value)),
          ttl_meta(std::make_unique<ItemTtlMeta>(expired_ts, kv_size,
                                                 lease_ttl_on_touch)) {}
    Value value;
    typename std::list<KvRef>::iterator lru_itr;
    std::unique_ptr<ItemTtlMeta> ttl_meta;
  };

  class CacheShard {
   public:
    CacheShard(int64_t capacity, std::atomic<int64_t>* cached_size,
               HashFn hash_fn, KeyEqualFn key_equal_fn)
        : cached_size_(cached_size),
          capacity_(capacity),
          shard_size_(0),
          cache_map_(8192, hash_fn, key_equal_fn) {}

    bool Load(const Key& key, Value* value, uint32_t cur_ts, uint32_t ttl) {
      std::unique_lock<std::mutex> lk(mu_);

      auto itr = cache_map_.find(key);
      if (itr != cache_map_.end()) {
        auto& cache_item = itr->second;
        auto& ttl_meta = *(cache_item.ttl_meta);
        if (ttl_meta.lease_ttl_on_touch) {
          ttl_meta.expired_ts = std::max(cur_ts + ttl, ttl_meta.expired_ts);
          lru_list_.erase(cache_item.lru_itr);
          cache_item.lru_itr =
              lru_list_.insert(lru_list_.end(), KvRef(itr->first, &ttl_meta));
          *value = cache_item.value;
          return true;
        } else if (ttl_meta.expired_ts > cur_ts) {
          *value = cache_item.value;
          return true;
        } else {
          (*cached_size_) -= ttl_meta.kv_size;
          shard_size_ -= ttl_meta.kv_size;
          lru_list_.erase(cache_item.lru_itr);
          cache_map_.erase(itr);
        }
      }
      return false;
    }

    template <
        typename T,
        std::enable_if_t<
            std::is_same<Value, typename std::remove_reference<T>::type>::value,
            bool> = true>
    bool Store(const Key& key, T&& value, uint32_t expired_ts, int64_t kv_size,
               bool lease_ttl_on_touch, bool update_if_exist) {
      std::unique_lock<std::mutex> lk(mu_);
      auto itr = cache_map_.find(key);
      bool key_exist = itr != cache_map_.end();
      if (!key_exist || update_if_exist) {
        CacheItem cache_item(std::forward<T>(value), expired_ts, kv_size,
                             lease_ttl_on_touch);
        auto* ttl_meta = cache_item.ttl_meta.get();
        kv_size -= key_exist ? itr->second.ttl_meta->kv_size : 0ll;
        if (cached_size_->fetch_add(kv_size) + kv_size <= capacity_) {
          if (key_exist) {
            lru_list_.erase(itr->second.lru_itr);
            lru_list_.emplace_back(key, ttl_meta);
            itr->second = std::move(cache_item);
            itr->second.lru_itr = --lru_list_.end();
          } else {
            auto ret = cache_map_.emplace(key, std::move(cache_item));
            assert(ret.second);
            lru_list_.emplace_back(key, ttl_meta);
            ret.first->second.lru_itr = --lru_list_.end();
          }
          shard_size_ += kv_size;
          return true;
        } else {
          cached_size_->fetch_sub(kv_size);
          return false;
        }
      } else {
        return false;
      }
    }

    void Evict(uint32_t cur_ts, bool force) {
      int64_t evict_size = 0u;
      std::unique_lock<std::mutex> lk(mu_);
      auto itr = lru_list_.begin();
      while (itr != lru_list_.end() &&
             (itr->ttl_meta->expired_ts <= cur_ts || force)) {
        const auto& key = itr->key;
        evict_size += itr->ttl_meta->kv_size;
        cache_map_.erase(key);
        lru_list_.pop_front();
        itr = lru_list_.begin();
        force = false;
      }
      (*cached_size_) -= evict_size;
      shard_size_ -= evict_size;
    }

    void Clear() {
      std::unique_lock<std::mutex> lk(mu_);
      cache_map_.clear();
      lru_list_.clear();
      (*cached_size_) -= shard_size_;
      shard_size_ = 0;
    }

   private:
    std::mutex mu_;
    std::atomic<int64_t>* cached_size_;
    const int64_t capacity_;
    uint64_t shard_size_;
    MapImpl<Key, CacheItem, HashFn, KeyEqualFn> cache_map_;
    std::list<KvRef> lru_list_;
  };

 public:
  TtlShardCache(int64_t capacity, uint32_t shard_num, uint32_t ttl,
           HashFn hash_fn = HashFn(), KeyEqualFn key_equal_fn = KeyEqualFn())
      : capacity_(capacity),
        shard_num_(shard_num),
        ttl_(ttl),
        last_gc_ts_(0u),
        cached_size_(0u),
        hash_fn_(hash_fn) {
    auto alloc_bytes = shard_num_ * sizeof(CacheShard);
    int ret = posix_memalign(reinterpret_cast<void**>(&mem_placeholder_),
                             alignof(CacheShard), alloc_bytes);
    assert(ret == 0);
    for (auto i = 0u; i < shard_num_; i++) {
      new (&At(i)) CacheShard(capacity_, &cached_size_, hash_fn_, key_equal_fn);
    }
  }

  ~TtlShardCache() {
    for (auto i = 0u; i < shard_num_; ++i) {
      At(i).~CacheShard();
    }
    free(mem_placeholder_);
  }

  bool Load(const Key& key, Value* value, uint32_t cur_ts = time(nullptr)) {
    return GetCacheShard(key).Load(key, value, cur_ts, ttl_);
  }

  template <
      typename T,
      std::enable_if_t<
          std::is_same<Value, typename std::remove_reference<T>::type>::value,
          bool> = true>
  bool Store(const Key& key, T&& value, int64_t kv_size,
             bool lease_ttl_on_touch,
             bool force, bool update_if_exist) {
    uint32_t cur_ts = time(nullptr);
    EvictIfNeed(cur_ts, kv_size, force);
    return (cached_size_.load(std::memory_order_acquire) + kv_size <=
                capacity_ ||
            update_if_exist)
               ? GetCacheShard(key).Store(
                     key, std::forward<T>(value), cur_ts + ttl_, kv_size,
                     lease_ttl_on_touch, update_if_exist)
               : false;
  }

  uint32_t Size() const { return cached_size_.load(std::memory_order_acquire); }

  void Clear() {
    for (auto i = 0u; i < shard_num_; i++) {
      At(i).Clear();
    }
  }

  void EvictIfNeed(uint32_t cur_ts, int64_t reserve_size, bool force) {
    auto last_gc_ts = last_gc_ts_.load(std::memory_order_acquire);
    auto cached_size = cached_size_.load(std::memory_order_acquire);
    force &= (reserve_size + cached_size) > capacity_;
    if ((last_gc_ts < cur_ts &&
         last_gc_ts_.compare_exchange_strong(last_gc_ts, cur_ts)) || force) {
      for (auto i = 0u; i < shard_num_; ++i) {
        At(i).Evict(cur_ts, force);
      }
    }
  }

 private:
  CacheShard& At(uint32_t i) {
    return *(reinterpret_cast<CacheShard*>(mem_placeholder_ +
                                           i * sizeof(CacheShard)));
  }

  CacheShard& GetCacheShard(const Key& key) {
    return At((hash_fn_(key) >> 16u) % shard_num_);
  }

  const int64_t capacity_;
  const uint32_t shard_num_;
  const uint32_t ttl_;
  std::atomic<uint32_t> last_gc_ts_;
  std::atomic<int64_t> cached_size_;
  char* mem_placeholder_;
  HashFn hash_fn_;
};

用 c++ 实现新的数据结构 `TtlShardCache`，需要满足以下要求，
1. 这个`TtlShardCache`支持并发读写, `API`是线程安全的
3. 模版化`Map`的实现, 让用户灵活定制
4. 模版化`Key, Value, HashFunc, EqualFunc`的实现
3. 实现接口 `bool Load(const Key& key, Value* value, uint32_t cur_ts = time(nullptr))`, 表示根据`Key`, load一个`Value`
4. 实现接口 `bool Store(const Key& key, T&& value, int64_t kv_size,
                        bool lease_ttl_on_touch,
                        bool force, bool update_if_exist)`, 表示往`Cache`存入一个KV,

#include <bits/stdc++.h>
#<INSERT>
#include <unordered_map>
#include <thread>
#include <cassert>

void testcase() {
  {
    const uint32_t cache_shard_num = 2;
    const uint32_t cache_capacity = 2;
    const uint32_t ttl = 30;
    TtlShardCache<std::unordered_map, int, int> cache(cache_capacity, cache_shard_num,
                                                 ttl);

    uint32_t cur_ts = time(nullptr);
    int k1 = 1, v1 = 11, k2 = 2, v2 = 22, k3 = 3, v3 = 33;
    int ret = 1000;
    assert(!cache.Load(k1, &ret, cur_ts));
    assert(!cache.Load(k2, &ret, cur_ts));
    cache.EvictIfNeed(cur_ts, 1, false);
    assert(0u == cache.Size());
    assert(cache.Store(k1, v1, 1, true, false, false));
    cache.EvictIfNeed(cur_ts, 1, false);
    assert(1 == cache.Size());
    assert(!cache.Store(k1, 3, 1, true, false, false));
    cache.EvictIfNeed(cur_ts, 1, false);
    assert(1 == cache.Size());
    assert(cache.Store(k2, k2, 1, false, false, false));
    cache.EvictIfNeed(cur_ts, 1, false);
    assert(2 == cache.Size());

    assert(cache.Load(k1, &ret, cur_ts));
    assert(v1 == ret);
    assert(cache.Store(k1, v3, 1, true, false, true));
    assert(cache.Load(k1, &ret, cur_ts));
    assert(v3 == ret);
    assert(!cache.Store(k1, v3, 1, true, false, false));
    assert(!cache.Store(k3, v3, 1, true, false, false));
    assert(!cache.Store(k3, v3, 1, true, false, true));
    assert(!cache.Load(k2, &ret, cur_ts + ttl + 1));
    cache.EvictIfNeed(cur_ts, 1, false);
    assert(1 == cache.Size());
  }
  {
    std::string cache_value = "cache_value";
    const uint32_t cache_shard_num = 2;
    const uint32_t cache_capacity = 20;
    const uint32_t ttl = 3;
    uint32_t cur_ts = 0u;
    TtlShardCache<std::unordered_map, int, int> cache(cache_capacity, cache_shard_num,
                                                 ttl);
    for (int i = 0; i < 20; ++i) {
      assert(cache.Store(i, i, 1, false, false, false));
    }
    for (int i = 20; i < 100; ++i) {
      assert(!cache.Store(i, i, 1, false, false, false));
    }
    cache.EvictIfNeed(cur_ts, 1, false);
    assert(cache_capacity == cache.Size());
  }
  {
    const uint32_t cache_capacity = 200;
    const uint32_t cache_shard_num = 2;
    const uint32_t ttl = 3;
    uint32_t cur_ts = 0u;
    TtlShardCache<std::unordered_map, int, int> cache(cache_capacity, cache_shard_num,
                                                 ttl);

    std::thread t1([&cache, cur_ts]() {
      for (int i = 0; i < 100; i += 2) {
        assert(cache.Store(i, i, 1, false, false, false));
      }
    });
    std::thread t2([&cache, cur_ts]() {
      for (int i = 1; i < 100; i += 2) {
        assert(cache.Store(i, i, 1, false, false, false));
      }
    });

    t1.join();
    t2.join();
    cache.EvictIfNeed(cur_ts, 1, false);
    assert(100 == cache.Size());

    for (int i = 0; i < 100; ++i) {
      int ret = -1;
      assert(cache.Load(i, &ret, cur_ts));
      assert(i == ret);
    }
  }
}

int main() {
  testcase();
  return 0;
}


#include <type_traits>
#include <vector>
#include <cassert>

template <typename T, size_t kSize = 8>
class AutoVec {
 public:
  AutoVec() = default;

  AutoVec(size_t size, const T default_value = T()) {
    if (size > 0) {
      std::uninitialized_fill_n(&(stack_vec_[0]), std::min(size, kSize), default_value);
      if (size > kSize) {
        heap_vec_.resize(size - kSize, default_value);
      }
    }
  }

  AutoVec(const AutoVec &other)
      : num_stack_size_(other.num_stack_size_),
        heap_vec_(other.heap_vec_) {
    if (num_stack_size_ > 0) {
      std::uninitialized_copy_n(&(other.stack_vec_[0]), num_stack_size_,
                                &(stack_vec_[0]));
    }
  }

  AutoVec &operator=(const AutoVec &other) {
    DtorVec(&(stack_vec_[0]), num_stack_size_);
    if (other.num_stack_size_ > 0) {
      std::uninitialized_copy_n(&(other.stack_vec_[0]), other.num_stack_size_,
                                &(stack_vec_[0]));
    }
    num_stack_size_ = other.num_stack_size_;
    heap_vec_ = other.heap_vec_;
    return *this;
  }

  AutoVec(AutoVec &&other)
      : num_stack_size_(other.num_stack_size_),
        heap_vec_(std::move(other.heap_vec_)) {
    if (num_stack_size_ > 0) {
      std::uninitialized_move_n(&(other.stack_vec_[0]), num_stack_size_,
                                &(stack_vec_[0]));
    }
  }

  AutoVec &operator=(AutoVec &&other) {
    DtorVec(&(stack_vec_[0]), num_stack_size_);
    if (other.num_stack_size_ > 0) {
      std::uninitialized_move_n(&(other.stack_vec_[0]), other.num_stack_size_,
                                &(stack_vec_[0]));
    }
    num_stack_size_ = other.num_stack_size_;
    heap_vec_ = std::move(other.heap_vec_);
    return *this;
  }

  ~AutoVec() { Clear(); }

  const T &operator[](size_t idx) const {
    if (idx < kSize) {
      return stack_vec_[idx];
    } else {
      return heap_vec_[idx - kSize];
    }
  }

  T &operator[](size_t idx) {
    if (idx < kSize) {
      return stack_vec_[idx];
    } else {
      return heap_vec_[idx - kSize];
    }
  }

  template <class... Args>
  void EmplaceBack(Args &&...args) {
    if (num_stack_size_ < kSize) {
      ::new (&(stack_vec_[num_stack_size_++])) T(std::forward<Args>(args)...);
    } else {
      heap_vec_.emplace_back(std::forward<Args>(args)...);
    }
  }

  void PushBack(T &&v) {
    if (num_stack_size_ < kSize) {
      ::new (&(stack_vec_[num_stack_size_++])) T(std::move(v));
    } else {
      heap_vec_.push_back(std::move(v));
    }
  }

  void PushBack(const T &v) {
    if (num_stack_size_ < kSize) {
      ::new (&(stack_vec_[num_stack_size_++])) T(v);
    } else {
      heap_vec_.push_back(v);
    }
  }

  void PopBack() noexcept {
    assert(num_stack_size_ > 0);
    if (!heap_vec_.empty()) {
      heap_vec_.pop_back();
    } else {
      DtorVec(&(stack_vec_[--num_stack_size_]), 1);
    }
  }

  T &Front() {
    assert(num_stack_size_ > 0);
    return stack_vec_[0];
  }

  const T &Front() const {
    assert(num_stack_size_ > 0);
    return stack_vec_[0];
  }

  T &Back() {
    assert(num_stack_size_ > 0);
    if (num_stack_size_ <= kSize) {
      return stack_vec_[num_stack_size_ - 1];
    } else {
      return heap_vec_.back();
    }
  }

  const T &Back() const {
    assert(num_stack_size_ > 0);
    if (num_stack_size_ <= kSize) {
      return stack_vec_[num_stack_size_ - 1];
    } else {
      return heap_vec_.back();
    }
  }

  size_t Size() const { return num_stack_size_ + heap_vec_.size(); }

  bool IsEmpty() const { return Size() == 0; }

  void Resize(size_t new_size, const T default_value = T()) {
    size_t old_size = Size();
    if (new_size < old_size) {
      if (new_size > kSize) {
        heap_vec_.resize(new_size - kSize);
      } else {
        heap_vec_.clear();
        DtorVec(&stack_vec_[new_size], kSize - new_size);
      }
    } else if (new_size > old_size) {
      if (new_size > kSize) {
        heap_vec_.resize(new_size - kSize, default_value);
      } else {
        std::uninitialized_fill_n(&(stack_vec_[old_size]),
                                  new_size - old_size, default_value);
      }
    }
  }

  void Clear() {
    heap_vec_.clear();
    DtorVec(&(stack_vec_[0]), num_stack_size_);
  }

 private:
  static void DtorVec(T *t, size_t num) {
    if (!std::is_trivially_destructible<T>::value &&
        std::is_destructible<T>::value && num > 0) {
      while (num > 0) {
        t->~T();
        t++;
        --num;
      }
    }
  }

  size_t num_stack_size_ = 0;
  T stack_vec_[kSize];
  std::vector<T> heap_vec_;
};

用 c++ 实现`template <typename T, size_t kSize = 8> class AutoVec`的模版类，类似在`std::vector`, `AutoVec`会把数组前一部分放到`stack`上，尾部的数组，才会放到`heap`上，增加对短`vector`的性能
1. 实现一个构造函数`AutoVec(size_t size, const T default_value = T())`, 表示构造一个`AutoVec`,有`size` 个 `default_value`
2. 实现复制构造函数/拷贝赋值函数/移动构造函数/移动赋值函数
3. 重载下标运算符根据下标方便访问元素
4. 实现接口 `template <class... Args> void EmplaceBack(Args&&... args)`表示往缓冲区尾部插入一个元素
6. 实现接口 `void PopBack()`从尾部删除一个元素
7. 实现接口 `T &Front(), const T &Front() const`表示获取头部元素
7. 实现接口 `T &Back(), const T &Back() const`表示获取尾部元素
9. 实现接口 `T& GetBack(), const T& GetBack() const`表示获取尾部元素
10. 实现接口 `bool IsEmpty() const`表示`AutoVec`是否为空
12. 实现接口 `size_t Size()`表示元素个数
14. 实现接口 `void Clear()`表示清空缓冲区
15. 实现接口 `void Resize(size_t new_size, const T default_value = T())`表示`AutoVec`大小重置为`size`, 如果扩大，则从尾部删除元素，如果缓冲区变大，则在尾部插入元素，并且用`default_value`去默认构造
17. 实现接口 `void Clear()`表示清空数组

#include <bits/stdc++.h>
#include <ctime>
#include <thread>

#<INSERT>

#include <cassert>

void testcase() {
  AutoVec<int, 2> auto_vec;
  auto_vec.PushBack(1);
  auto_vec.PushBack(2);
  auto_vec.PushBack(3);
  auto_vec.EmplaceBack(4);
  assert(auto_vec[0] == 1);
  assert(auto_vec[1] == 2);
  assert(auto_vec[2] == 3);
  assert(auto_vec[3] == 4);
  assert(auto_vec.Size() == 4);
  auto_vec.Resize(2);
  assert(auto_vec.Size() == 2);
  auto_vec.Resize(4, 10);
  assert(auto_vec.Size() == 4);
  assert(auto_vec[2] == 10);
  assert(auto_vec[3] == 10);
  assert (auto_vec.Size() == 4);
}

int main() {
  testcase();
  return 0;
}


#include <utility>
#include <cassert>
#include <cstddef>

template <class T>
class CircularBuffer {
 public:
  explicit CircularBuffer(size_t capacity = 0): capacity_(capacity) {
    if (capacity) {
      storage_ = new ElementStorage[capacity];
    }
  }

  ~CircularBuffer() {
    while (!IsEmpty()) {
      PopFront();
    }
    if (storage_) {
      delete[] storage_;
    }
  }

  CircularBuffer(const CircularBuffer& other)
      : CircularBuffer(other.capacity_) {
    for (size_t i = 0; i < other.GetSize(); ++i) {
      EmplaceBack(other[i]);
    }
  }

  CircularBuffer(CircularBuffer&& other) : CircularBuffer() { Swap(&other); }

  CircularBuffer& operator=(const CircularBuffer& other) {
    assert(other.GetSize() <= GetCapacity());
    Clear();
    for (size_t i = 0; i < other.GetSize(); ++i) {
      EmplaceBack(other[i]);
    }
    return *this;
  }

  CircularBuffer& operator=(CircularBuffer&& other) {
    CircularBuffer tmp(std::move(other));
    Swap(&tmp);
    return *this;
  }

  T& operator[](size_t i) {
    assert(i < size_);
    return storage_[(read_index_ + i) % capacity_].o;
  }

  const T& operator[](size_t i) const {
    assert(i < size_);
    return storage_[(read_index_ + i) % capacity_].o;
  }

  template <class... Args>
  void EmplaceBack(Args&&... args) {
    assert(size_ < capacity_);
    new (storage_ + write_index_) T(std::forward<Args>(args)...);
    write_index_ = (write_index_ + 1) % capacity_;
    ++size_;
  }

  template <class... Args>
  void EmplaceFront(Args&&... args) {
    assert(size_ < capacity_);
    if (read_index_ == 0) {
      read_index_ = capacity_ - 1;
    } else {
      --read_index_;
    }
    new (storage_ + read_index_) T(std::forward<Args>(args)...);
    ++size_;
  }

  void PopBack() {
    assert(!IsEmpty());
    if (write_index_ == 0) {
      write_index_ = capacity_ - 1;
    } else {
      --write_index_;
    }
    storage_[write_index_].o.~T();
    --size_;
  }

  void PopFront() {
    assert(!IsEmpty());
    storage_[read_index_].o.~T();
    read_index_ = (read_index_ + 1) % capacity_;
    --size_;
  }

  T& GetFront() {
    assert(!IsEmpty());
    return storage_[read_index_].o;
  }

  const T& GetFront() const {
    assert(!IsEmpty());
    return storage_[read_index_].o;
  }

  T& GetBack() {
    assert(!IsEmpty());
    return storage_[write_index_ == 0 ? (capacity_ - 1) : (write_index_ - 1)].o;
  }

  const T& GetBack() const {
    assert(!IsEmpty());
    return storage_[write_index_ == 0 ? (capacity_ - 1) : (write_index_ - 1)].o;
  }

  size_t GetCapacity() const { return capacity_; }

  bool IsEmpty() const { return size_ == 0; }

  bool IsFull() const { return size_ == capacity_; }

  size_t GetSize() const { return size_; }

  void Clear() {
    while (!IsEmpty()) {
      PopFront();
    }
  }

  void Resize(size_t size, const T& value) {
    assert(size <= capacity_);
    while (size < size_) {
      PopBack();
    }
    while (size > size_) {
      EmplaceBack(value);
    }
  }

  void Resize(size_t size) {
    assert(size <= capacity_);
    while (size < size_) {
      PopBack();
    }
    while (size > size_) {
      EmplaceBack();
    }
  }

  void Swap(CircularBuffer* other) {
    std::swap(storage_, other->storage_);
    std::swap(write_index_, other->write_index_);
    std::swap(read_index_, other->read_index_);
    std::swap(size_, other->size_);
    std::swap(capacity_, other->capacity_);
  }

 private:
  union ElementStorage {
    ElementStorage() {}
    ~ElementStorage() {}

    T o;
    char buf[sizeof(T)];
  };

  ElementStorage* storage_ = nullptr;
  size_t write_index_ = 0;
  size_t read_index_ = 0;
  size_t size_ = 0;
  size_t capacity_;
};

用 c++ 实现`CircularBuffer`类用于表示循环缓冲区, 需要用模版实现，支持不同类型对象的定义
1. 实现构造函数`CircularBuffer(std::size_t capacity)`, 表示缓冲区最大长度
2. 实现复制构造函数/拷贝赋值函数/移动构造函数/移动赋值函数
3. 重载下标运算符根据下标方便访问元素
4. 实现接口 `template <class... Args> void EmplaceBack(Args&&... args)`表示往缓冲区尾部插入一个元素
5. 实现接口 `template <class... Args> void EmplaceFront(Args&&... args)`表示往缓冲区头部插入一个元素
6. 实现接口 `void PopBack()`从尾部删除一个元素
7. 实现接口 `void PopFront()`从头部删除一个元素
8. 实现接口 `T& GetFront(), const T& GetFront() const`表示获取头部元素
9. 实现接口 `T& GetBack(), const T& GetBack() const`表示获取尾部元素
10. 实现接口 `bool IsFull()`表示缓冲区是否为满
11. 实现接口 `bool IsEmpty()`表示缓冲区是否为空
12. 实现接口 `size_t GetSize()`表示缓冲区中元素个数
13. 实现接口 `size_t GetCapacity()`表示缓冲区的容量
14. 实现接口 `void Clear()`表示清空缓冲区
15. 实现接口 `void Resize(size_t size, const T& value)`表示缓冲区大小重置为`size`, 如果缓冲区扩大，则从缓冲区尾部删除元素，如果缓冲区变大，则在缓冲区头部插入元素，并且用`value`去默认构造
16. 实现接口 `void Resize(size_t size)`表示缓冲区大小重置为`size`, 如果缓冲区扩大，则从缓冲区尾部删除元素，如果缓冲区变大，则在缓冲区头部插入元素，并且用`T`的默认构造函数去构造
17. 实现接口 `void Swap(CircularBuffer* other)`表示交换两个缓冲区的内容

#include <bits/stdc++.h>
#<INSERT>
#include <cassert>
#include <cassert>
#include <string>

void testcase() {
  CircularBuffer<std::string> cb(3);
  assert(cb.IsEmpty());
  assert(!cb.IsFull());
  assert(cb.GetSize() == 0U);
  assert(cb.GetCapacity() == 3U);

  cb.EmplaceBack("abc");
  assert(!cb.IsEmpty());
  assert(!cb.IsFull());
  assert(cb.GetSize() == 1U);
  assert(cb.GetCapacity() == 3U);
  assert(cb.GetFront() == "abc");
  assert(cb.GetBack() == "abc");
  assert(cb[0] == "abc");

  cb.EmplaceFront("101");
  assert(!cb.IsEmpty());
  assert(!cb.IsFull());
  assert(cb.GetSize() == 2U);
  assert(cb.GetCapacity() == 3U);
  assert(cb.GetFront() == "101");
  assert(cb.GetBack() == "abc");
  assert(cb[0] == "101");
  assert(cb[1] == "abc");

  cb.EmplaceBack("123");
  assert(!cb.IsEmpty());
  assert(cb.IsFull());
  assert(cb.GetSize() == 3U);
  assert(cb.GetCapacity() == 3U);
  assert(cb.GetFront() == "101");
  assert(cb.GetBack() == "123");
  assert(cb[0] == "101");
  assert(cb[1] == "abc");
  assert(cb[2] == "123");

  cb.PopBack();
  assert(!cb.IsEmpty());
  assert(!cb.IsFull());
  assert(cb.GetSize() == 2U);
  assert(cb.GetCapacity() == 3U);
  assert(cb.GetFront() == "101");
  assert(cb.GetBack() == "abc");
  assert(cb[0] == "101");
  assert(cb[1] == "abc");

  cb.PopFront();
  assert(!cb.IsEmpty());
  assert(!cb.IsFull());
  assert(cb.GetSize() == 1U);
  assert(cb.GetCapacity() == 3U);
  assert(cb.GetFront() == "abc");
  assert(cb.GetBack() == "abc");
  assert(cb[0] == "abc");

  cb.Clear();
  assert(cb.IsEmpty());
  assert(!cb.IsFull());
  assert(cb.GetSize() == 0U);
  assert(cb.GetCapacity() == 3U);

  cb.Resize(1);
  assert(cb.GetSize() == 1U);
  assert(cb.GetFront().empty());

  std::string s("101");
  cb.Resize(2, s);
  assert(cb.GetSize() == 2U);
  assert(cb[0] == "");
  assert(cb[1] == "101");

  CircularBuffer<std::string> cb2(cb);
  assert(cb2.GetSize() == 2U);
  assert(cb2.GetCapacity() == 3U);
  assert(cb2[0] == "");
  assert(cb2[1] == "101");

  cb2.Clear();
  cb2 = cb;
  assert(cb2.GetSize() == 2U);
  assert(cb2[0] == "");
  assert(cb2[1] == "101");

  CircularBuffer<std::string> cb3(std::move(cb));
  assert(cb.IsEmpty());
  assert(cb3.GetSize() == 2U);
  assert(cb3[0] == "");
  assert(cb3[1] == "101");

  cb = std::move(cb3);
  assert(cb3.IsEmpty());
  assert(cb.GetSize() == 2U);
  assert(cb[0] == "");
  assert(cb[1] == "101");
}

int main() {
  testcase();
  return 0;
}


#include <functional>
#include <limits>
#include <memory>
#include <cassert>
#include <climits>

template <class Key, class HashFn = std::hash<Key>,
          class KeyEqualFn = std::equal_to<Key>>
class DeDupper {

  struct Config {
    static constexpr auto kIllgalBucket = std::numeric_limits<uint32_t>::max();

    static constexpr auto kLoadFactor = 0.75F;
  };

  struct HTItem {
    HTItem() = default;
    explicit HTItem(const Key &key) : key(key) {}
    explicit HTItem(const Key &key, uint32_t version, uint32_t uniq_idx)
        : key(key), version(version), uniq_idx(uniq_idx) {}
    Key key;
    uint32_t version{0};
    uint32_t uniq_idx{0};
  };

  struct HTIdx {
    HTIdx(uint32_t item_pos, uint32_t insert_pos)
        : item_pos(item_pos), insert_pos(insert_pos) {}
    uint32_t item_pos;
    uint32_t insert_pos;
  };

  struct HTMeta {
    bool Init(uint32_t new_bucknum) {
      bucknum = new_bucknum;
      num_elements = 0;
      return (0 == cur_version++);
    }

    uint32_t bucknum = 0;
    uint32_t buckcap = 0;
    uint32_t num_elements = 0;
    uint32_t cur_version = 0;
  };

  using HTItemPtr = HTItem*;
  using CHTItemPtr = const HTItem*;

 public:
  DeDupper() = default;

  ~DeDupper() { DtorProbTable(prob_table_, ht_meta_.buckcap); }

  uint32_t DeDup(const Key &key) {
    auto hv = hash_fn_(key);
    const auto hi = FindPosition(key, prob_table_, ht_meta_.bucknum - 1,
                                 hv, ht_meta_.cur_version);
    if (hi.item_pos != Config::kIllgalBucket) {
      return prob_table_[hi.item_pos].uniq_idx;
    } else {
      prob_table_[hi.insert_pos] =
          HTItem(key, ht_meta_.cur_version, ht_meta_.num_elements);
      return ht_meta_.num_elements++;
    }
  }

  void PrepareDeDup(const uint32_t capacity) {
    size_t min_cap = static_cast<size_t>(capacity) / Config::kLoadFactor;
    size_t new_buckcap = RoundUpToNextHighestPowerOf2(min_cap);
    assert(new_buckcap < Config::kIllgalBucket);
    if (new_buckcap > ht_meta_.buckcap) {
      DtorProbTable(prob_table_, ht_meta_.buckcap);
      prob_table_ = CreateProbTable(new_buckcap);
      ht_meta_.buckcap = new_buckcap;
      ht_meta_.Init(new_buckcap);
    } else if (ht_meta_.Init(new_buckcap)) {
      FillRangeWithEmpty(prob_table_, new_buckcap);
    }
  }

 private:
  static size_t RoundUpToNextHighestPowerOf2(size_t v) {
    size_t shift_bits = sizeof(size_t) * CHAR_BIT - 1 - __builtin_clzll(v);
    size_t ret = static_cast<size_t>(1) << shift_bits;
    return ret < v ? (ret << 1) : ret;
  }

  static HTItemPtr CreateProbTable(uint32_t num_capacity) {
    assert((num_capacity & (num_capacity - 1)) == 0);
    auto table = reinterpret_cast<HTItemPtr>(malloc(num_capacity * sizeof(HTItem)));
    FillRangeWithEmpty(table, num_capacity);
    return table;
  }

  static void DtorProbTable(HTItemPtr prob_table, uint32_t num_capacity) {
    if (!!prob_table && num_capacity > 0 &&
        !std::is_trivially_destructible<HTItem>::value &&
        std::is_destructible<HTItem>::value) {
      for (auto bi = 0; bi < num_capacity; ++bi) {
        prob_table[bi].~HTItem();
      }
    }
  }

  HTIdx FindPosition(const Key &key, CHTItemPtr table,
                     uint32_t buckidx_mask, uint32_t hv,
                     uint32_t version) {
    uint32_t buckidx = hv & buckidx_mask;
    while (true) {
      auto& item = table[buckidx];
      if (TestEqual(item, key, version)) {
        return HTIdx(buckidx, Config::kIllgalBucket);
      } else if (TestEmpty(item, version)) {
        return HTIdx(Config::kIllgalBucket, buckidx);
      }
      buckidx = (buckidx + 1) & buckidx_mask;
    }
  }

  static void FillRangeWithEmpty(const HTItemPtr prob_table,
                                 uint32_t num_capacity) {
    static HTItem empty_item(Key(), 0, 0);
    std::uninitialized_fill_n(prob_table, num_capacity, empty_item);
  }

  static bool TestEmpty(const HTItem& ht_item, uint32_t cur_version) {
    return ht_item.version != cur_version;
  }

  bool TestEqual(const HTItem& ht_item, const Key &key,
                 uint32_t cur_version) {
    return key_equal_fn_(ht_item.key, key) && ht_item.version == cur_version;
  }

 private:
  HTMeta ht_meta_;
  HTItemPtr prob_table_{nullptr};
  HashFn hash_fn_;
  KeyEqualFn key_equal_fn_;
};

用 c++ 实现`DeDupper`类型，主要功能就是对一些元素做一些去重
1. 模版化`Key, Value, HashFunc, EqualFunc`的实现, 方便用户做定制
2. 实现接口 `void PrepareDeDup(const uint32_t capacity)` 根据需要去重的key的个数，提前预留好内存空间，做好准备
3. 实现接口 `uint32_t DeDup(const Key &key)` 对`key`做去重, 如果key已经存在，返回是第几个去重的元素，否则插入key，返回总共去重之后的元素个数

#include <bits/stdc++.h>
#<INSERT>
#include <cassert>

void testcase() {
  DeDupper<uint64_t> dedupper;
  uint32_t fid_num = 10;
  dedupper.PrepareDeDup(fid_num);
  assert(dedupper.DeDup(0) == 1);
  assert(dedupper.DeDup(1) == 2);
  assert(dedupper.DeDup(2) == 3);
  assert(dedupper.DeDup(2) == 2);
  assert(dedupper.DeDup(3) == 4);
  assert(dedupper.DeDup(2) == 2);
  dedupper.PrepareDeDup(fid_num);
  assert(dedupper.DeDup(4) == 1);
  assert(dedupper.DeDup(5) == 2);
  assert(dedupper.DeDup(2) == 3);
}

int main() {
  testcase();
  return 0;
}


#include <functional>
#include <list>
#include <memory>
#include <mutex>
#include <shared_mutex>
#include <string>
#include <unordered_map>
#include <vector>

template <typename K, typename V> struct KeyValue {
  K key;
  V value;

  KeyValue(const K &k, const V &v) : key(k), value(v) {}
};

template <typename K, typename V, typename Hash = std::hash<K>> class LruCache {
public:
  typedef std::list<KeyValue<K, V>> ListType;
  typedef std::unordered_map<K, typename ListType::iterator, Hash> MapType;

  /**
   * 显式构造函数，指定最大容量
   */
  explicit LruCache(size_t max_size) : max_size_(max_size) {}

  LruCache(const LruCache &) = delete;
  const LruCache &operator=(const LruCache &) = delete;
  virtual ~LruCache() {}

  size_t size() {
    std::shared_lock lock(mutex_);
    return cache_.size();
  }

  size_t max_size() const { return max_size_; }

  bool empty() { return size() == 0; }

  void reserve(size_t reserve_size = 0) {
    if (reserve_size == 0) {
      reserve_size =
          max_size_ +
          1; // 不传参的时候默认是reserve
             // max_size+1，+1为了防止到达边界时触发rehash，留1个buffer
    }
    std::unique_lock lock(mutex_);
    cache_.reserve(reserve_size);
  }

  /**
   * 增加一条记录，如果 cache 容量满了，会淘汰掉最旧的
   */
  void add(const K &k, const V &v) {
    std::vector<KeyValue<K, V>> drops;
    {
      std::unique_lock lock(mutex_);
      _add_no_lock(k, v, drops);
    }
  }

  /**
   * 获取 k 对应的 value，存储到 result 中
   * 如果不存在，返回 false，否则返回 true
   *
   * NOTE: 这个访问会将该记录挪到最前，当成最近的记录
   */
  bool get(const K &k, V &result) {
    std::unique_lock lock(mutex_);
    return _get_no_lock<true>(k, result);
  }

  /**
   * 取 k 对应的 value，存储到 result 中
   * 如果不存在，返回 false，否则返回 true
   *
   * NOTE: 和 get 的区别是: 这里并不将记录挪动，因此只需要挂读锁，
   *       并发性和性能会更好
   */
  bool peek(const K &k, V &result) {
    std::shared_lock lock(mutex_);
    return _get_no_lock<false>(k, result);
  }

  /**
   * 删除一条记录，存在，则返回 true，否则返回 false
   */
  bool remove(const K &k) {
    std::vector<KeyValue<K, V>> drops;
    {
      std::unique_lock lock(mutex_);
      const auto &iter = cache_.find(k);
      if (iter == cache_.end()) {
        return false;
      }
      drops.emplace_back(*(iter->second));
      list_.erase(iter->second);
      cache_.erase(iter);
    }
    return true;
  }

  /**
   * 返回是否存在某个 key
   */
  bool contains(const K &k) {
    std::shared_lock lock(mutex_);
    return cache_.find(k) != cache_.end();
  }

  void clear() {
    ListType drops;
    {
      std::unique_lock lock(mutex_);
      cache_.clear();
      drops.swap(list_);
    }
  }

  /**
   * 访问 cache 中所有的 key value 对
   * f 是 void (const K&, const V&) 类型的
   */
  void iter_all(std::function<void(const K &, const V &)> f) {
    std::shared_lock lock(mutex_);
    for (auto &kv : list_) {
      f(kv.key, kv.value);
    }
  }

private:
  template <bool move_to_front = false>
  bool _get_no_lock(const K &k, V &result) {
    const auto &iter = cache_.find(k);
    if (iter == cache_.end())
      return false;
    if (move_to_front) {
      list_.splice(list_.begin(), list_, iter->second);
    }
    result = iter->second->value;
    return true;
  }

  void _add_no_lock(const K &k, const V &v) {
    const auto &iter = cache_.find(k);
    if (iter != cache_.end()) {
      iter->second->value = v;
      list_.splice(list_.begin(), list_, iter->second);
    } else {
      list_.emplace_front(KeyValue<K, V>(k, v));
      cache_[k] = list_.begin();
    }

    while (cache_.size() > max_size_) {
      cache_.erase(list_.back().key);
      list_.pop_back();
    }
  }

  void _add_no_lock(const K &k, const V &v,
                    std::vector<KeyValue<K, V>> &drops) {
    const auto &iter = cache_.find(k);
    if (iter != cache_.end()) {
      iter->second->value = v;
      list_.splice(list_.begin(), list_, iter->second);
    } else {
      list_.emplace_front(KeyValue<K, V>(k, v));
      cache_[k] = list_.begin();
    }

    while (cache_.size() > max_size_) {
      drops.emplace_back(list_.back());
      cache_.erase(list_.back().key);
      list_.pop_back();
    }
  }

private:
  MapType cache_;
  ListType list_;
  size_t max_size_;
  std::shared_mutex mutex_;
};

实现一个 lru cache，支持线程安全，并且支持以下接口：
1. `LruCache (size_t max_size)`: 构造函数，指定最大容量
2. `size_t size()`: 获取当前缓存大小
3. `void add(const K &k, const V &v)`: 增加一条记录，如果 cache 容量满了，会淘汰掉最旧的
4. `bool get(const K &k, V &result)`: 这个访问会将该记录挪到最前，当成最近的记录
5. `bool peek(const K &k, V &result)`: 和 get 的区别是，不移动记录，只需要读锁
6. `void iter_all(std::function<void(const K &, const V &)> f)`: 访问 cache 中所有的 key value 对

#include <bits/stdc++.h>
#<INSERT>

#include <atomic>
#include <cassert>
#include <iostream>
#include <memory>
#include <unordered_map>
#include <vector>

void testcase() {
  LruCache<int, int> cache(3);

  cache.add(1, 1);
  cache.add(2, 2);
  cache.add(3, 3);
  cache.add(1, 1);
  cache.add(4, 4);

  assert(3 == cache.size());
  std::vector<std::pair<int, int>> vecs;
  auto func = [&](const int &k, const int &v) {
    vecs.push_back(std::make_pair(k, v));
  };
  cache.iter_all(func);
  assert(vecs.size() == 3);
  assert(vecs[0] == std::make_pair<>(4, 4));
  assert(vecs[1] == std::make_pair<>(1, 1));
  assert(vecs[2] == std::make_pair<>(3, 3));
}

int main() {
  testcase();
  return 0;
}


#include <atomic>
#include <chrono>
#include <cstdint>
#include <thread>
#include <cassert>

class TokenBucket final {
 public:
  TokenBucket(double tokens_per_sec, uint64_t capacity,
              uint64_t initial_tokens = 0)
      : tokens_per_sec_(tokens_per_sec), capacity_(capacity) {
    ns_per_token_ = 1000000000 / tokens_per_sec;
    capacity_ns_ = ns_per_token_ * capacity;
    last_update_time_ns_.store(
        NowNs() - initial_tokens * ns_per_token_,
        std::memory_order_relaxed);
  }

  bool TryConsume(uint64_t tokens = 1) {
    return Consume(tokens, false /*wait*/) == 0;
  }

  static int64_t NowNs() {
    return std::chrono::duration_cast<std::chrono::nanoseconds>(
        std::chrono::steady_clock::now().time_since_epoch()
      ).count();
  }

  void Consume(uint64_t tokens = 1) { Consume(tokens, true /*wait*/); }

  int64_t ConsumeWithBorrow(uint64_t tokens = 1) {
    assert(tokens <= capacity_);
    auto old_ts_ns = last_update_time_ns_.load(std::memory_order_relaxed);
    auto tokens_ns = tokens * ns_per_token_;
    uint64_t now_ns = NowNs();
    for (;;) {
      auto new_ts_ns = old_ts_ns;
      if (old_ts_ns < now_ns && now_ns - old_ts_ns > capacity_ns_) {
        new_ts_ns = now_ns - capacity_ns_;
      }
      new_ts_ns += tokens_ns;
      if (last_update_time_ns_.compare_exchange_weak(old_ts_ns, new_ts_ns,
                                                     std::memory_order_relaxed)) {
        return new_ts_ns > now_ns
               ? new_ts_ns - now_ns
               : 0;
      }
      now_ns = NowNs();
    }
  }

  int64_t GetWaitTime(uint64_t tokens = 1) {
    return Consume(tokens, false /*wait*/);
  }

  void Return(uint64_t tokens = 1) {
    auto old_ts_ns = last_update_time_ns_.load(std::memory_order_relaxed);
    uint64_t returned_ns = tokens * ns_per_token_;
    uint64_t new_ts_ns{0};
    do {
      if (old_ts_ns > returned_ns) {
        new_ts_ns = old_ts_ns - returned_ns;
      }
    } while (!last_update_time_ns_.compare_exchange_weak(
        old_ts_ns, new_ts_ns, std::memory_order_relaxed));
  }

  double GetTokensPerSec() const { return tokens_per_sec_; }

  uint64_t GetCapacity() const { return capacity_; }

 private:
  int64_t Consume(uint64_t tokens, bool wait) {
    assert(tokens <= capacity_);
    auto tokens_ns = tokens * ns_per_token_;
    assert(tokens_ns <= capacity_ns_);
    int64_t now_ns = NowNs();
    auto old_ts_ns = last_update_time_ns_.load(std::memory_order_relaxed);
    for (;;) {
      int64_t avail_ns = 0;
      uint64_t extra_ns = 0;
      avail_ns = static_cast<int64_t>(now_ns) -
                 static_cast<int64_t>(old_ts_ns);
      if (avail_ns > static_cast<int64_t>(capacity_ns_)) {
        extra_ns = avail_ns - capacity_ns_;
        avail_ns = capacity_ns_;
      }
      if (avail_ns < static_cast<int64_t>(tokens_ns)) {
        if (!wait) {
          return tokens_ns - avail_ns;
        }
        std::this_thread::sleep_for(std::chrono::nanoseconds(tokens_ns - avail_ns));
        old_ts_ns = last_update_time_ns_.load(std::memory_order_relaxed);
      } else {
        if (last_update_time_ns_.compare_exchange_strong(
              old_ts_ns, old_ts_ns + extra_ns + tokens_ns,
              std::memory_order_relaxed)) {
          return static_cast<int64_t>(0);
        }
      }
      now_ns = NowNs();
    }
  }

  double tokens_per_sec_;
  uint64_t capacity_;

  std::atomic<uint64_t> last_update_time_ns_;
  uint64_t ns_per_token_;
  uint64_t capacity_ns_;
};

用 c++ 实现令牌桶 `TokenBucket`, 令牌桶是一种用于流量控制的算法。它可以限制数据传输的速率，防止数据传输过快或过慢。
1. 根据裸指针实现一个构造函数`TokenBucket(double tokens_per_sec, uint64_t capacity, uint64_t initial_tokens = 0)`, `double tokens_per_sec 每秒生成多少token`, `uint64_t capacity 表示最多有多少token`, `uint64_t initial_tokens 表示一开始有多少token`
2. 实现接口 `bool TryConsume(uint64_t tokens = 1)`表示尝试获得`tokens`, 返回`false`表示需要等待,返回`true`表示获得了
3. 实现接口 `int64_t ConsumeWithBorrow(uint64_t tokens = 1)`表示需要获得`tokens`, 需要等待多少纳秒
4. 实现接口 `int64_t GetWaitTime(uint64_t tokens = 1)`表示需要获得这么多`token`, 需要等待多少纳秒
5. 实现接口 `void Return(uint64_t tokens = 1)`表示归还多少`token`
6. 实现接口 `double GetTokensPerSec() const `表示每秒生成多少token
7. 实现接口 `uint64_t GetCapacity() const`表示总共多少token

#include <bits/stdc++.h>
#<INSERT>

#include <chrono>
#include <cassert>

void testcase() {
  {
    TokenBucket tb(100, 10, 0);
    assert(tb.GetTokensPerSec() == 100.);
    assert(tb.GetCapacity() == 10U);
    auto start = TokenBucket::NowNs();
    for (int i = 0; i < 10; ++i) {
      tb.Consume(1);
    }
    assert(!tb.TryConsume());
    auto ms = (TokenBucket::NowNs() - start) / 1000000.0;
    assert(ms >= 50);
    assert(ms <= 150);
    std::this_thread::sleep_for(std::chrono::milliseconds(20));
    assert(tb.TryConsume());
  }
  {
    TokenBucket tb(1000, 1000, 1000);
    assert(tb.GetTokensPerSec() == 1000.);
    assert(tb.GetCapacity() == 1000U);
    auto start = TokenBucket::NowNs();
    auto r = tb.ConsumeWithBorrow(1000);
    assert(r == 0);
    r = tb.ConsumeWithBorrow(1000);
    auto ms = (TokenBucket::NowNs() - start) / 1000000.0;
    auto need_wait_time = r / 1000000.0;
    assert(need_wait_time <= 1000);
    assert(need_wait_time >= 500 - ms);

    need_wait_time = tb.GetWaitTime(1) / 1000000.0;
    ms = (TokenBucket::NowNs() - start) / 1000000.0;
    assert(need_wait_time >= 500 - ms);
  }
}

int main() {
  testcase();
  return 0;
}


#include <deque>
#include <functional>
#include <memory>
#include <mutex>

// ObjectCreater 封装了构造函数和初始化过程。默认实现为调用默认构造函数。
template <class T> struct DefaultObjectCreater {
  template <class... Args> T *operator()() { return new T(); }
};

// ObjectPool 必须以shared_ptr方式使用，才能保证Pool和对象都正确析构
template <class T, class N = DefaultObjectCreater<T>>
class ObjectPool : public std::enable_shared_from_this<ObjectPool<T, N>> {
public:
  using std::enable_shared_from_this<ObjectPool<T, N>>::shared_from_this;

  // 默认情况下可以申请的object无穷多个，池子总保留的object可以无穷多个
  // =0 等价于不设上限
  ObjectPool(size_t max_idle_object_num = 0, size_t max_total_object_num = 0)
      : _max_idle_object_num(max_idle_object_num),
        _max_total_object_num(max_total_object_num), _object_creater() {}

  // 使用传入的构造器
  ObjectPool(const N &creater, size_t max_idle_object_num = 0,
             size_t max_total_object_num = 0)
      : _max_idle_object_num(max_idle_object_num),
        _max_total_object_num(max_total_object_num), _object_creater(creater) {}

  // 使用移动传入的构造器
  ObjectPool(N &&creater, size_t max_idle_object_num = 0,
             size_t max_total_object_num = 0)
      : _max_idle_object_num(max_idle_object_num),
        _max_total_object_num(max_total_object_num),
        _object_creater(std::move(creater)) {}

  virtual ~ObjectPool() {
    for (auto &pobject : _objects) {
      delete pobject;
      pobject = nullptr;
    }
  }

  std::shared_ptr<T> get() {
    T *pobject = nullptr;
    bool create = false;
    {
      std::lock_guard<std::mutex> lock(_mutex);
      if (!_objects.empty()) {
        pobject = _objects.front();
        _objects.pop_front();
        --_idle_object_num;
      } else {
        if (_max_total_object_num == 0 ||
            _total_object_num < _max_total_object_num) {
          ++_total_object_num;
          create = true;
        }
      }
    }
    if (create) {
      pobject = _object_creater();
    }
    return std::shared_ptr<T>(pobject, ObjectDeleter(shared_from_this()));
  }

  void warmup(size_t num) {
    std::lock_guard<std::mutex> lock(_mutex);
    for (size_t i = 0;
         i < num &&
         (_max_total_object_num == 0 ||
          _total_object_num < _max_total_object_num) &&
         (_max_idle_object_num == 0 || _objects.size() < _max_idle_object_num);
         i++) {
      ++_total_object_num;
      auto pobject = _object_creater();
      _objects.push_back(pobject);
      ++_idle_object_num;
    }
  }

  size_t total_object_num() const { return _total_object_num; }

  size_t idle_object_num() const { return _idle_object_num; }

protected:
  void put(T *pobject) {
    if (!pobject)
      return;
    bool destroy = false;
    {
      std::lock_guard<std::mutex> lock(_mutex);
      if (_max_idle_object_num > 0 && _objects.size() >= _max_idle_object_num) {
        --_total_object_num;
        destroy = true;
      } else {
        _objects.push_back(pobject);
        ++_idle_object_num;
      }
    }
    if (destroy) {
      delete pobject;
    }
  }

  class ObjectDeleter {
  public:
    ObjectDeleter(std::shared_ptr<ObjectPool<T, N>> pool)
        : _pool(std::move(pool)) {}

    void operator()(T *pobject) { _pool->put(pobject); }

  private:
    std::shared_ptr<ObjectPool<T, N>> _pool;
  };

protected:
  std::deque<T *> _objects;
  volatile size_t _total_object_num = 0;
  volatile size_t _idle_object_num = 0;

  const size_t _max_idle_object_num;
  const size_t _max_total_object_num;

  std::mutex _mutex;
  N _object_creater;
};

template <class T, class N = DefaultObjectCreater<T>>
using ObjectPoolPtr = std::shared_ptr<ObjectPool<T, N>>;

用 c++ 实现一个对象池 `ObjectPool`，来避免大量重复的对象申请/释放开销，提供以下功能：
1. 构造函数: `ObjectPool(size_t max_idle_object_num = 0, size_t max_total_object_num = 0)`
    a. 默认情况下可以申请的object无穷多个，池子总保留的object可以无穷多个;
    b. =0 等价于不设上限;
2. 支持传入自定义 object 构造函数；
2. `std::shared_ptr<T> get()`: 支持从 objectpool 中取出一个元素，如果 buffer 池中不存在则调用默认构造或传入构造函数构造对象
3. `void warmup(size_t num)`: 支持使用 num warmup objectpool，避免启动时出现延迟抖动

#include <bits/stdc++.h>
#<INSERT>
#include <atomic>
#include <cassert>
#include <iostream>
#include <memory>

std::atomic_int32_t new_count = 0, delete_count = 0;

class Test {
public:
  Test() {
    new_count++;
    value_ = new_count;
  }
  ~Test() { delete_count++; }
  int get_value() const { return value_; }

public:
  int value_ = 0;
};

struct TestObjectCreater {
  Test *operator()() {
    Test *res = new Test();
    res->value_ = 42;
    return res;
  }
};

void testcase() {
  {
    ObjectPoolPtr<Test, TestObjectCreater> pool =
        std::make_shared<ObjectPool<Test, TestObjectCreater>>();
    pool->warmup(2);
    auto r1 = pool->get();
    assert(pool->total_object_num() == 2);
    assert(pool->idle_object_num() == 1);
    auto r2 = pool->get();
    assert(pool->idle_object_num() == 0);
    auto r3 = pool->get();
    assert(pool->idle_object_num() == 0);
    assert(pool->total_object_num() == 3);

    // recycle object
    r3.reset();
    r2.reset();
    assert(pool->idle_object_num() == 2);
    assert(pool->total_object_num() == 3);

    // get object again
    r2 = pool->get();
    assert(pool->idle_object_num() == 1);
    assert(pool->total_object_num() == 3);

    // check alloc & delloc count
    assert(new_count == 3);
    assert(delete_count == 0);

    // release obj pool
    pool.reset();
  }

  assert(new_count == 3);
  std::cout << delete_count << std::endl;
  assert(delete_count == 3);
}

int main() {
  testcase();
  return 0;
}