1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
|
#pragma once
#include "blob.h"
#include "ref.h"
#include <library/cpp/yt/error/error.h>
namespace NYT {
////////////////////////////////////////////////////////////////////////////////
struct IMemoryUsageTracker
: public TRefCounted
{
virtual TError TryAcquire(i64 size) = 0;
virtual TError TryChange(i64 size) = 0;
//! Returns true unless overcommit occurred.
virtual bool Acquire(i64 size) = 0;
virtual void Release(i64 size) = 0;
virtual void SetLimit(i64 size) = 0;
virtual i64 GetLimit() const = 0;
virtual i64 GetUsed() const = 0;
virtual i64 GetFree() const = 0;
virtual bool IsExceeded() const = 0;
//! Tracks memory used by references.
/*!
* Memory tracking is implemented by specific shared ref holders.
* #Track returns reference with a holder that wraps the old one and also
* enables accounting memory in memory tracker's internal state.
* Subsequent #Track calls for this reference drop memory reference tracker's
* holder unless #keepExistingTracking is true.
*/
virtual TSharedRef Track(
TSharedRef reference,
bool keepHolder = false) = 0;
virtual TErrorOr<TSharedRef> TryTrack(
TSharedRef reference,
bool keepHolder) = 0;
};
DEFINE_REFCOUNTED_TYPE(IMemoryUsageTracker)
////////////////////////////////////////////////////////////////////////////////
struct IReservingMemoryUsageTracker
: public IMemoryUsageTracker
{
virtual void ReleaseUnusedReservation() = 0;
virtual TError TryReserve(i64 size) = 0;
};
DEFINE_REFCOUNTED_TYPE(IReservingMemoryUsageTracker)
////////////////////////////////////////////////////////////////////////////////
IMemoryUsageTrackerPtr GetNullMemoryUsageTracker();
////////////////////////////////////////////////////////////////////////////////
class TMemoryUsageTrackerGuard
: private TNonCopyable
{
public:
TMemoryUsageTrackerGuard() = default;
TMemoryUsageTrackerGuard(const TMemoryUsageTrackerGuard& other) = delete;
TMemoryUsageTrackerGuard(TMemoryUsageTrackerGuard&& other);
~TMemoryUsageTrackerGuard();
TMemoryUsageTrackerGuard& operator=(const TMemoryUsageTrackerGuard& other) = delete;
TMemoryUsageTrackerGuard& operator=(TMemoryUsageTrackerGuard&& other);
static TMemoryUsageTrackerGuard Build(
IMemoryUsageTrackerPtr tracker,
i64 granularity = 1);
static TMemoryUsageTrackerGuard Acquire(
IMemoryUsageTrackerPtr tracker,
i64 size,
i64 granularity = 1);
static TErrorOr<TMemoryUsageTrackerGuard> TryAcquire(
IMemoryUsageTrackerPtr tracker,
i64 size,
i64 granularity = 1);
void Release();
//! Releases the guard but does not return memory to the tracker.
//! The caller should care about releasing memory itself.
void ReleaseNoReclaim();
explicit operator bool() const;
i64 GetSize() const;
void SetSize(i64 size);
TError TrySetSize(i64 size);
void IncreaseSize(i64 sizeDelta);
void DecreaseSize(i64 sizeDelta);
TMemoryUsageTrackerGuard TransferMemory(i64 size);
private:
IMemoryUsageTrackerPtr Tracker_;
i64 Size_ = 0;
i64 AcquiredSize_ = 0;
i64 Granularity_ = 0;
void MoveFrom(TMemoryUsageTrackerGuard&& other);
TError SetSizeImpl(i64 size, auto acquirer);
};
////////////////////////////////////////////////////////////////////////////////
class TMemoryTrackedBlob
{
public:
static TMemoryTrackedBlob Build(
IMemoryUsageTrackerPtr tracker,
TRefCountedTypeCookie tagCookie = GetRefCountedTypeCookie<TDefaultBlobTag>());
TMemoryTrackedBlob() = default;
TMemoryTrackedBlob(const TMemoryTrackedBlob& other) = delete;
TMemoryTrackedBlob(TMemoryTrackedBlob&& other) = default;
~TMemoryTrackedBlob() = default;
TMemoryTrackedBlob& operator=(const TMemoryTrackedBlob& other) = delete;
TMemoryTrackedBlob& operator=(TMemoryTrackedBlob&& other) = default;
void Resize(
i64 size,
bool initializeStorage = true);
TError TryResize(
i64 size,
bool initializeStorage = true);
void Reserve(i64 capacity);
TError TryReserve(i64 capacity);
char* Begin();
char* End();
size_t Capacity() const;
size_t Size() const;
void Append(TRef ref);
void Clear();
private:
TBlob Blob_;
TMemoryUsageTrackerGuard Guard_;
TMemoryTrackedBlob(
TBlob&& blob,
TMemoryUsageTrackerGuard&& guard);
};
////////////////////////////////////////////////////////////////////////////////
TErrorOr<TSharedRef> TryTrackMemory(
const IMemoryUsageTrackerPtr& tracker,
TSharedRef reference,
bool keepExistingTracking = false);
TSharedRef TrackMemory(
const IMemoryUsageTrackerPtr& tracker,
TSharedRef reference,
bool keepExistingTracking = false);
TSharedRefArray TrackMemory(
const IMemoryUsageTrackerPtr& tracker,
TSharedRefArray array,
bool keepExistingTracking = false);
////////////////////////////////////////////////////////////////////////////////
} // namespace NYT
|