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 */
9class Increment
10{
11public:
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
65private:
66 CounterInFile counter;
67};
68