MCPcopy Create free account
hub / github.com/Snapchat/KeyDB / dbSwapDatabases

Function dbSwapDatabases

src/db.cpp:1721–1754  ·  view source on GitHub ↗

Swap two databases at runtime so that all clients will magically see * the new database even if already connected. Note that the client * structure c->db points to a given DB, so we need to be smarter and * swap the underlying referenced structures, otherwise we would need * to fix all the references to the Redis DB structure. * * Returns C_ERR if at least one of the DB ids are out of range,

Source from the content-addressed store, hash-verified

1719 * Returns C_ERR if at least one of the DB ids are out of range, otherwise
1720 * C_OK is returned. */
1721int dbSwapDatabases(int id1, int id2) {
1722 if (id1 < 0 || id1 >= cserver.dbnum ||
1723 id2 < 0 || id2 >= cserver.dbnum) return C_ERR;
1724 if (id1 == id2) return C_OK;
1725 std::swap(g_pserver->db[id1], g_pserver->db[id2]);
1726
1727 //swap db's id too, otherwise db does not match its id
1728 std::swap(g_pserver->db[id1]->id, g_pserver->db[id2]->id);
1729
1730 /* Note that we don't swap blocking_keys,
1731 * ready_keys and watched_keys, since we want clients to
1732 * remain in the same DB they were. so put them back */
1733 std::swap(g_pserver->db[id1]->blocking_keys, g_pserver->db[id2]->blocking_keys);
1734 std::swap(g_pserver->db[id2]->ready_keys, g_pserver->db[id2]->ready_keys);
1735 std::swap(g_pserver->db[id2]->watched_keys, g_pserver->db[id2]->watched_keys);
1736
1737 /* Now we need to handle clients blocked on lists: as an effect
1738 * of swapping the two DBs, a client that was waiting for list
1739 * X in a given DB, may now actually be unblocked if X happens
1740 * to exist in the new version of the DB, after the swap.
1741 *
1742 * However normally we only do this check for efficiency reasons
1743 * in dbAdd() when a list is created. So here we need to rescan
1744 * the list of clients blocked on lists and signal lists as ready
1745 * if needed.
1746 *
1747 * Also the swapdb should make transaction fail if there is any
1748 * client watching keys */
1749 scanDatabaseForReadyLists(g_pserver->db[id1]);
1750 touchAllWatchedKeysInDb(g_pserver->db[id1], g_pserver->db[id2]);
1751 scanDatabaseForReadyLists(g_pserver->db[id2]);
1752 touchAllWatchedKeysInDb(g_pserver->db[id2], g_pserver->db[id1]);
1753 return C_OK;
1754}
1755
1756/* SWAPDB db1 db2 */
1757void swapdbCommand(client *c) {

Callers 1

swapdbCommandFunction · 0.85

Calls 3

touchAllWatchedKeysInDbFunction · 0.85
swapFunction · 0.50

Tested by

no test coverage detected