1 | #pragma once |
2 | |
3 | #include <Common/CounterInFile.h> |
4 | |
5 | |
6 | /** Allows to get an auto-increment number, storing it in a file. |
7 | * Intended for rare calls (not designed for performance). |
8 | */ |
9 | class Increment |
10 | { |
11 | public: |
12 | /// path - the name of the file, including the path |
13 | Increment(const std::string & path_) : counter(path_) {} |
14 | |
15 | /** Get the next number. |
16 | * If the `create_if_need` parameter is not set to true, then |
17 | * the file must already have a number written (if not - create the file manually with zero). |
18 | * |
19 | * To protect against race conditions between different processes, file locks are used. |
20 | * (But when the first file is created, the race condition is possible, so it's better to create the file in advance.) |
21 | * |
22 | * `locked_callback` is called when the counter file is locked. A new value is passed to it. |
23 | * `locked_callback` can be used to do something atomically with the increment of the counter (for example, rename files). |
24 | */ |
25 | template <typename Callback> |
26 | UInt64 get(Callback && locked_callback, bool create_if_need = false) |
27 | { |
28 | return static_cast<UInt64>(counter.add(1, std::forward<Callback>(locked_callback), create_if_need)); |
29 | } |
30 | |
31 | UInt64 get(bool create_if_need = false) |
32 | { |
33 | return getBunch(1, create_if_need); |
34 | } |
35 | |
36 | /// Peek the next value. |
37 | UInt64 peek(bool create_if_need = false) |
38 | { |
39 | return getBunch(0, create_if_need); |
40 | } |
41 | |
42 | /** Get the next number and increase the counter by `count`. |
43 | * If the `create_if_need` parameter is not set to true, then |
44 | * the file should already have a number written (if not - create the file manually with zero). |
45 | * |
46 | * To protect against race conditions between different processes, file locks are used. |
47 | * (But when the first file is created, the race condition is possible, so it's better to create the file in advance.) |
48 | */ |
49 | UInt64 getBunch(UInt64 count, bool create_if_need = false) |
50 | { |
51 | return static_cast<UInt64>(counter.add(static_cast<Int64>(count), create_if_need) - count + 1); |
52 | } |
53 | |
54 | /// Change the path to the file. |
55 | void setPath(std::string path_) |
56 | { |
57 | counter.setPath(path_); |
58 | } |
59 | |
60 | void fixIfBroken(UInt64 value) |
61 | { |
62 | counter.fixIfBroken(value); |
63 | } |
64 | |
65 | private: |
66 | CounterInFile counter; |
67 | }; |
68 | |