[PATCH 02/11] vinyl: refactor quota use/unuse methods
Vladimir Davydov
vdavydov.dev at gmail.com
Thu Sep 20 12:34:07 MSK 2018
Some minor refactoring targeted at beautifying the code:
- Rename vy_quota_is_exceeded to vy_quota_may_use and pass the
requested amount of quota to it explicitly instead of incrementing
quota before calling this function and decremented after. Move the
definition closer to vy_quota_use, where this function is used.
- Implement quota consumption in vy_quota_use via vy_quota_force_use
so that there's the only function that increments quota.
- Factor out vy_quota_unuse out of vy_qouta_adjust. This function is
opposite to vy_quota_force_use.
---
src/box/vy_quota.c | 55 +++++++++++++++++++++++++-----------------------------
1 file changed, 25 insertions(+), 30 deletions(-)
diff --git a/src/box/vy_quota.c b/src/box/vy_quota.c
index d3588b6e..8ead5c4b 100644
--- a/src/box/vy_quota.c
+++ b/src/box/vy_quota.c
@@ -68,16 +68,6 @@ static const size_t VY_DEFAULT_DUMP_BANDWIDTH = 10 * 1024 * 1024;
*/
enum { VY_DUMP_BANDWIDTH_PCT = 10 };
-/**
- * Returns true if the quota limit is exceeded and so consumers
- * have to wait.
- */
-static inline bool
-vy_quota_is_exceeded(struct vy_quota *q)
-{
- return q->used > q->limit;
-}
-
static void
vy_quota_timer_cb(ev_loop *loop, ev_timer *timer, int events)
{
@@ -209,25 +199,29 @@ vy_quota_force_use(struct vy_quota *q, size_t size)
q->quota_exceeded_cb(q);
}
+/**
+ * Returns true if the requested amount of quota may be consumed,
+ * or false if consumers have to wait.
+ */
+static bool
+vy_quota_may_use(struct vy_quota *q, size_t size)
+{
+ return q->used + size <= q->limit;
+}
+
int
vy_quota_use(struct vy_quota *q, size_t size, double timeout)
{
- q->used += size;
- q->use_curr += size;
- if (vy_quota_is_exceeded(q)) {
+ if (!vy_quota_may_use(q, size)) {
/* Wait for quota. */
double start_time = ev_monotonic_now(loop());
double deadline = start_time + timeout;
do {
q->quota_exceeded_cb(q);
- q->used -= size;
- q->use_curr -= size;
if (fiber_cond_wait_deadline(&q->cond, deadline) != 0)
return -1; /* timed out */
- q->used += size;
- q->use_curr += size;
- } while (vy_quota_is_exceeded(q));
+ } while (!vy_quota_may_use(q, size));
double wait_time = ev_monotonic_now(loop()) - start_time;
if (wait_time > q->too_long_threshold) {
@@ -240,24 +234,25 @@ vy_quota_use(struct vy_quota *q, size_t size, double timeout)
*/
fiber_cond_signal(&q->cond);
}
- if (q->used >= q->watermark)
- q->quota_exceeded_cb(q);
+ vy_quota_force_use(q, size);
return 0;
}
+static void
+vy_quota_unuse(struct vy_quota *q, size_t size)
+{
+ assert(q->used >= size);
+ q->used -= size;
+ /* use_curr could have been reset on timeout. */
+ q->use_curr -= MIN(q->use_curr, size);
+ fiber_cond_signal(&q->cond);
+}
+
void
vy_quota_adjust(struct vy_quota *q, size_t reserved, size_t used)
{
- if (reserved > used) {
- size_t excess = reserved - used;
- assert(q->used >= excess);
- q->used -= excess;
- if (q->use_curr >= excess)
- q->use_curr -= excess;
- else /* was reset by timeout */
- q->use_curr = 0;
- fiber_cond_signal(&q->cond);
- }
+ if (reserved > used)
+ vy_quota_unuse(q, reserved - used);
if (reserved < used)
vy_quota_force_use(q, used - reserved);
}
--
2.11.0
More information about the Tarantool-patches
mailing list