summaryrefslogtreecommitdiff
path: root/items.c
diff options
context:
space:
mode:
authordormando <dormando@rydia.net>2019-04-30 01:38:05 -0700
committerdormando <dormando@rydia.net>2019-09-30 18:17:46 -0700
commit1e1462867dfe057e037b62fa9ca50e1062874d44 (patch)
treedbbdc73b5d3008a9eb364fb7754bbec915065e0c /items.c
parentef4d20d265449329d5af80d397eb9c739f172411 (diff)
downloadmemcached-1e1462867dfe057e037b62fa9ca50e1062874d44.tar.gz
meta text protocol commands
- we get asked a lot to provide a "metaget" command, for various uses (debugging, etc) - we also get asked for random one-off commands for various use cases. - I really hate both of these situations and have been wanting to experiment with a slight tuning of how get commands work for a long time. Assuming that if I offer a metaget command which gives people the information they're curious about in an inefficient format, plus data they don't need, we'll just end up with a slow command with compatibility issues. No matter how you wrap warnings around a command, people will put it into production under high load. Then I'm stuck with it forever. Behold, the meta commands! See doc/protocol.txt and the wiki for a full explanation and examples. The intent of the meta commands is to support any features the binary protocol had over the text protocol. Though this is missing some commands still, it is close and surpasses the binary protocol in many ways.
Diffstat (limited to 'items.c')
-rw-r--r--items.c55
1 files changed, 31 insertions, 24 deletions
diff --git a/items.c b/items.c
index 2923dd6..696b558 100644
--- a/items.c
+++ b/items.c
@@ -1034,30 +1034,7 @@ item *do_item_get(const char *key, const size_t nkey, const uint32_t hv, conn *c
was_found = 3;
} else {
if (do_update) {
- /* We update the hit markers only during fetches.
- * An item needs to be hit twice overall to be considered
- * ACTIVE, but only needs a single hit to maintain activity
- * afterward.
- * FETCHED tells if an item has ever been active.
- */
- if (settings.lru_segmented) {
- if ((it->it_flags & ITEM_ACTIVE) == 0) {
- if ((it->it_flags & ITEM_FETCHED) == 0) {
- it->it_flags |= ITEM_FETCHED;
- } else {
- it->it_flags |= ITEM_ACTIVE;
- if (ITEM_lruid(it) != COLD_LRU) {
- do_item_update(it); // bump LA time
- } else if (!lru_bump_async(c->thread->lru_bump_buf, it, hv)) {
- // add flag before async bump to avoid race.
- it->it_flags &= ~ITEM_ACTIVE;
- }
- }
- }
- } else {
- it->it_flags |= ITEM_FETCHED;
- do_item_update(it);
- }
+ do_item_bump(c, it, hv);
}
DEBUG_REFCNT(it, '+');
}
@@ -1072,6 +1049,36 @@ item *do_item_get(const char *key, const size_t nkey, const uint32_t hv, conn *c
return it;
}
+// Requires lock held for item.
+// Split out of do_item_get() to allow mget functions to look through header
+// data before losing state modified via the bump function.
+void do_item_bump(conn *c, item *it, const uint32_t hv) {
+ /* We update the hit markers only during fetches.
+ * An item needs to be hit twice overall to be considered
+ * ACTIVE, but only needs a single hit to maintain activity
+ * afterward.
+ * FETCHED tells if an item has ever been active.
+ */
+ if (settings.lru_segmented) {
+ if ((it->it_flags & ITEM_ACTIVE) == 0) {
+ if ((it->it_flags & ITEM_FETCHED) == 0) {
+ it->it_flags |= ITEM_FETCHED;
+ } else {
+ it->it_flags |= ITEM_ACTIVE;
+ if (ITEM_lruid(it) != COLD_LRU) {
+ do_item_update(it); // bump LA time
+ } else if (!lru_bump_async(c->thread->lru_bump_buf, it, hv)) {
+ // add flag before async bump to avoid race.
+ it->it_flags &= ~ITEM_ACTIVE;
+ }
+ }
+ }
+ } else {
+ it->it_flags |= ITEM_FETCHED;
+ do_item_update(it);
+ }
+}
+
item *do_item_touch(const char *key, size_t nkey, uint32_t exptime,
const uint32_t hv, conn *c) {
item *it = do_item_get(key, nkey, hv, c, DO_UPDATE);