From: Yan, Zheng Date: Mon, 9 Feb 2015 03:44:16 +0000 (+0800) Subject: mds: use compact_map/compact_set to optimize memory usage of CInode X-Git-Tag: v9.0.0~201^2~6 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=00047fbefd87209b2957ba66f7a73fd38c87ac11;p=ceph.git mds: use compact_map/compact_set to optimize memory usage of CInode define some rarely used containers as compact_map/compact_set. Each replacement can save 40 bytes for 64 bits program. Signed-off-by: Yan, Zheng --- diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index ad14701f7b23..839ad6a4871e 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -229,8 +229,9 @@ ostream& operator<<(ostream& out, const CInode& in) } if (!in.get_mds_caps_wanted().empty()) { out << " mcw={"; - for (map::const_iterator p = in.get_mds_caps_wanted().begin(); - p != in.get_mds_caps_wanted().end(); ++p) { + for (compact_map::const_iterator p = in.get_mds_caps_wanted().begin(); + p != in.get_mds_caps_wanted().end(); + ++p) { if (p != in.get_mds_caps_wanted().begin()) out << ','; out << p->first << '=' << ccap_string(p->second); @@ -278,7 +279,7 @@ void CInode::add_need_snapflush(CInode *snapin, snapid_t snapid, client_t client void CInode::remove_need_snapflush(CInode *snapin, snapid_t snapid, client_t client) { dout(10) << "remove_need_snapflush client." << client << " snapid " << snapid << " on " << snapin << dendl; - map >::iterator p = client_need_snapflush.find(snapid); + compact_map >::iterator p = client_need_snapflush.find(snapid); if (p == client_need_snapflush.end()) { dout(10) << " snapid not found" << dendl; return; @@ -302,7 +303,7 @@ void CInode::remove_need_snapflush(CInode *snapin, snapid_t snapid, client_t cli void CInode::split_need_snapflush(CInode *cowin, CInode *in) { dout(10) << "split_need_snapflush [" << cowin->first << "," << cowin->last << "] for " << *cowin << dendl; - for (map >::iterator p = client_need_snapflush.lower_bound(cowin->first); + for (compact_map >::iterator p = client_need_snapflush.lower_bound(cowin->first); p != client_need_snapflush.end() && p->first <= cowin->last; ++p) { assert(!p->second.empty()); @@ -497,7 +498,7 @@ bool CInode::get_dirfrags_under(frag_t fg, list& ls) fragtree_t tmpdft; tmpdft.force_to_leaf(g_ceph_context, fg); - for (map::iterator p = dirfrags.begin(); p != dirfrags.end(); ++p) { + for (compact_map::iterator p = dirfrags.begin(); p != dirfrags.end(); ++p) { tmpdft.force_to_leaf(g_ceph_context, p->first); if (fg.contains(p->first) && !dirfragtree.is_leaf(p->first)) ls.push_back(p->second); @@ -517,7 +518,7 @@ bool CInode::get_dirfrags_under(frag_t fg, list& ls) void CInode::verify_dirfrags() { bool bad = false; - for (map::iterator p = dirfrags.begin(); p != dirfrags.end(); ++p) { + for (compact_map::iterator p = dirfrags.begin(); p != dirfrags.end(); ++p) { if (!dirfragtree.is_leaf(p->first)) { dout(0) << "have open dirfrag " << p->first << " but not leaf in " << dirfragtree << ": " << *p->second << dendl; @@ -530,7 +531,7 @@ void CInode::verify_dirfrags() void CInode::force_dirfrags() { bool bad = false; - for (map::iterator p = dirfrags.begin(); p != dirfrags.end(); ++p) { + for (compact_map::iterator p = dirfrags.begin(); p != dirfrags.end(); ++p) { if (!dirfragtree.is_leaf(p->first)) { dout(0) << "have open dirfrag " << p->first << " but not leaf in " << dirfragtree << ": " << *p->second << dendl; @@ -571,7 +572,7 @@ CDir *CInode::get_approx_dirfrag(frag_t fg) void CInode::get_dirfrags(list& ls) { // all dirfrags - for (map::iterator p = dirfrags.begin(); + for (compact_map::iterator p = dirfrags.begin(); p != dirfrags.end(); ++p) ls.push_back(p->second); @@ -579,7 +580,7 @@ void CInode::get_dirfrags(list& ls) void CInode::get_nested_dirfrags(list& ls) { // dirfrags in same subtree - for (map::iterator p = dirfrags.begin(); + for (compact_map::iterator p = dirfrags.begin(); p != dirfrags.end(); ++p) if (!p->second->is_subtree_root()) @@ -588,7 +589,7 @@ void CInode::get_nested_dirfrags(list& ls) void CInode::get_subtree_dirfrags(list& ls) { // dirfrags that are roots of new subtrees - for (map::iterator p = dirfrags.begin(); + for (compact_map::iterator p = dirfrags.begin(); p != dirfrags.end(); ++p) if (p->second->is_subtree_root()) @@ -660,7 +661,7 @@ void CInode::close_dirfrags() bool CInode::has_subtree_root_dirfrag(int auth) { - for (map::iterator p = dirfrags.begin(); + for (compact_map::iterator p = dirfrags.begin(); p != dirfrags.end(); ++p) if (p->second->is_subtree_root() && @@ -671,7 +672,7 @@ bool CInode::has_subtree_root_dirfrag(int auth) bool CInode::has_subtree_or_exporting_dirfrag() { - for (map::iterator p = dirfrags.begin(); + for (compact_map::iterator p = dirfrags.begin(); p != dirfrags.end(); ++p) if (p->second->is_subtree_root() || @@ -684,7 +685,7 @@ void CInode::get_stickydirs() { if (stickydir_ref == 0) { get(PIN_STICKYDIRS); - for (map::iterator p = dirfrags.begin(); + for (compact_map::iterator p = dirfrags.begin(); p != dirfrags.end(); ++p) { p->second->state_set(CDir::STATE_STICKY); @@ -700,7 +701,7 @@ void CInode::put_stickydirs() stickydir_ref--; if (stickydir_ref == 0) { put(PIN_STICKYDIRS); - for (map::iterator p = dirfrags.begin(); + for (compact_map::iterator p = dirfrags.begin(); p != dirfrags.end(); ++p) { p->second->state_clear(CDir::STATE_STICKY); @@ -1380,7 +1381,7 @@ void CInode::encode_lock_state(int type, bufferlist& bl) ::encode(inode.dirstat, bl); // only meaningful if i am auth. bufferlist tmp; __u32 n = 0; - for (map::iterator p = dirfrags.begin(); + for (compact_map::iterator p = dirfrags.begin(); p != dirfrags.end(); ++p) { frag_t fg = p->first; @@ -1415,7 +1416,7 @@ void CInode::encode_lock_state(int type, bufferlist& bl) ::encode(inode.rstat, bl); // only meaningful if i am auth. bufferlist tmp; __u32 n = 0; - for (map::iterator p = dirfrags.begin(); + for (compact_map::iterator p = dirfrags.begin(); p != dirfrags.end(); ++p) { frag_t fg = p->first; @@ -1536,7 +1537,7 @@ void CInode::decode_lock_state(int type, bufferlist& bl) // dft was scattered, or we may still be be waiting on the // notify from the auth) dirfragtree.swap(temp); - for (map::iterator p = dirfrags.begin(); + for (compact_map::iterator p = dirfrags.begin(); p != dirfrags.end(); ++p) { if (!dirfragtree.is_leaf(p->first)) { @@ -1772,7 +1773,7 @@ void CInode::start_scatter(ScatterLock *lock) assert(is_auth()); inode_t *pi = get_projected_inode(); - for (map::iterator p = dirfrags.begin(); + for (compact_map::iterator p = dirfrags.begin(); p != dirfrags.end(); ++p) { frag_t fg = p->first; @@ -1916,7 +1917,7 @@ void CInode::finish_scatter_gather_update(int type) bool touched_mtime = false; dout(20) << " orig dirstat " << pi->dirstat << dendl; pi->dirstat.version++; - for (map::iterator p = dirfrags.begin(); + for (compact_map::iterator p = dirfrags.begin(); p != dirfrags.end(); ++p) { frag_t fg = p->first; @@ -2008,7 +2009,7 @@ void CInode::finish_scatter_gather_update(int type) inode_t *pi = get_projected_inode(); dout(20) << " orig rstat " << pi->rstat << dendl; pi->rstat.version++; - for (map::iterator p = dirfrags.begin(); + for (compact_map::iterator p = dirfrags.begin(); p != dirfrags.end(); ++p) { frag_t fg = p->first; @@ -2095,7 +2096,7 @@ void CInode::finish_scatter_gather_update_accounted(int type, MutationRef& mut, dout(10) << "finish_scatter_gather_update_accounted " << type << " on " << *this << dendl; assert(is_auth()); - for (map::iterator p = dirfrags.begin(); + for (compact_map::iterator p = dirfrags.begin(); p != dirfrags.end(); ++p) { CDir *dir = p->second; @@ -2153,7 +2154,7 @@ void CInode::take_dir_waiting(frag_t fg, list& ls) if (waiting_on_dir.empty()) return; - map >::iterator p = waiting_on_dir.find(fg); + compact_map >::iterator p = waiting_on_dir.find(fg); if (p != waiting_on_dir.end()) { dout(10) << "take_dir_waiting frag " << fg << " on " << *this << dendl; ls.splice(ls.end(), p->second); @@ -2189,7 +2190,7 @@ void CInode::take_waiting(uint64_t mask, list& ls) if ((mask & WAIT_DIR) && !waiting_on_dir.empty()) { // take all dentry waiters while (!waiting_on_dir.empty()) { - map >::iterator p = waiting_on_dir.begin(); + compact_map >::iterator p = waiting_on_dir.begin(); dout(10) << "take_waiting dirfrag " << p->first << " on " << *this << dendl; ls.splice(ls.end(), p->second); waiting_on_dir.erase(p); @@ -2345,7 +2346,7 @@ void CInode::adjust_nested_auth_pins(int a, void *by) if (g_conf->mds_debug_auth_pins) { // audit int s = 0; - for (map::iterator p = dirfrags.begin(); + for (compact_map::iterator p = dirfrags.begin(); p != dirfrags.end(); ++p) { CDir *dir = p->second; @@ -2896,7 +2897,7 @@ int CInode::get_caps_wanted(int *ploner, int *pother, int shift, int mask) const //cout << " get_caps_wanted client " << it->first << " " << cap_string(it->second.wanted()) << endl; } if (is_auth()) - for (map::const_iterator it = mds_caps_wanted.begin(); + for (compact_map::const_iterator it = mds_caps_wanted.begin(); it != mds_caps_wanted.end(); ++it) { w |= it->second; @@ -3411,7 +3412,7 @@ void CInode::encode_export(bufferlist& bl) // include scatterlock info for any bounding CDirs bufferlist bounding; if (inode.is_dir()) - for (map::iterator p = dirfrags.begin(); + for (compact_map::iterator p = dirfrags.begin(); p != dirfrags.end(); ++p) { CDir *dir = p->second; @@ -3745,9 +3746,9 @@ void CInode::validate_disk_state(CInode::validated_data *results, // check each dirfrag... nest_info_t& sub_info = results->raw_rstats.ondisk_value; - for (map::iterator p = in->dirfrags.begin(); - p != in->dirfrags.end(); - ++p) { + for (compact_map::iterator p = in->dirfrags.begin(); + p != in->dirfrags.end(); + ++p) { if (!p->second->is_complete()) { results->raw_rstats.error_str << "dirfrag is INCOMPLETE despite fetching; probably too large compared to MDS cache size?\n"; return true; diff --git a/src/mds/CInode.h b/src/mds/CInode.h index aff95e9bffb9..35c4f9236703 100644 --- a/src/mds/CInode.h +++ b/src/mds/CInode.h @@ -21,6 +21,7 @@ #include "include/elist.h" #include "include/types.h" #include "include/lru.h" +#include "include/compact_set.h" #include "mdstypes.h" #include "flock.h" @@ -233,7 +234,7 @@ public: SnapRealm *snaprealm; SnapRealm *containing_realm; snapid_t first, last; - std::set dirty_old_rstats; + compact_set dirty_old_rstats; bool is_multiversion() const { return snaprealm || // other snaprealms will link to me @@ -392,7 +393,7 @@ public: // -- cache infrastructure -- private: - std::map dirfrags; // cached dir fragments under this Inode + compact_map dirfrags; // cached dir fragments under this Inode int stickydir_ref; public: @@ -427,7 +428,7 @@ public: protected: // parent dentries in cache CDentry *parent; // primary link - std::set remote_parents; // if hard linked + compact_set remote_parents; // if hard linked std::list projected_parent; // for in-progress rename, (un)link, etc. @@ -437,12 +438,12 @@ public: protected: // file capabilities std::map client_caps; // client -> caps - std::map mds_caps_wanted; // [auth] mds -> caps wanted + compact_map mds_caps_wanted; // [auth] mds -> caps wanted int replica_caps_wanted; // [replica] what i've requested from auth - std::map > client_snap_caps; // [auth] [snap] dirty metadata we still need from the head + compact_map > client_snap_caps; // [auth] [snap] dirty metadata we still need from the head public: - std::map > client_need_snapflush; + compact_map > client_need_snapflush; void add_need_snapflush(CInode *snapin, snapid_t snapid, client_t client); void remove_need_snapflush(CInode *snapin, snapid_t snapid, client_t client); @@ -639,7 +640,7 @@ public: // -- waiting -- protected: - std::map > waiting_on_dir; + compact_map > waiting_on_dir; public: void add_dir_waiter(frag_t fg, MDSInternalContextBase *c); void take_dir_waiting(frag_t fg, std::list& ls); @@ -791,8 +792,8 @@ public: bool is_any_caps() { return !client_caps.empty(); } bool is_any_nonstale_caps() { return count_nonstale_caps(); } - const std::map& get_mds_caps_wanted() const { return mds_caps_wanted; } - std::map& get_mds_caps_wanted() { return mds_caps_wanted; } + const compact_map& get_mds_caps_wanted() const { return mds_caps_wanted; } + compact_map& get_mds_caps_wanted() { return mds_caps_wanted; } const std::map& get_client_caps() const { return client_caps; } Capability *get_client_cap(client_t client) { diff --git a/src/mds/Locker.cc b/src/mds/Locker.cc index 4ea960fa4910..063322142f1d 100644 --- a/src/mds/Locker.cc +++ b/src/mds/Locker.cc @@ -1736,7 +1736,7 @@ void Locker::file_update_finish(CInode *in, MutationRef& mut, bool share, client dout(10) << " client_snap_caps " << in->client_snap_caps << dendl; // check for snap writeback completion bool gather = false; - map >::iterator p = in->client_snap_caps.begin(); + compact_map >::iterator p = in->client_snap_caps.begin(); while (p != in->client_snap_caps.end()) { SimpleLock *lock = in->get_lock(p->first); assert(lock); @@ -2397,7 +2397,7 @@ void Locker::adjust_cap_wanted(Capability *cap, int wanted, int issue_seq) void Locker::_do_null_snapflush(CInode *head_in, client_t client, snapid_t follows) { dout(10) << "_do_null_snapflish client." << client << " follows " << follows << " on " << *head_in << dendl; - map >::iterator p = head_in->client_need_snapflush.begin(); + compact_map >::iterator p = head_in->client_need_snapflush.begin(); while (p != head_in->client_need_snapflush.end()) { snapid_t snapid = p->first; set& clients = p->second; @@ -2413,7 +2413,7 @@ void Locker::_do_null_snapflush(CInode *head_in, client_t client, snapid_t follo // hrm, look forward until we find the inode. // (we can only look it up by the last snapid it is valid for) dout(10) << " didn't have " << head_in->ino() << " snapid " << snapid << dendl; - for (map >::iterator q = p; // p is already at next entry + for (compact_map >::iterator q = p; // p is already at next entry q != head_in->client_need_snapflush.end(); ++q) { dout(10) << " trying snapid " << q->first << dendl; diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 2d43317cc1f0..2cac326924b2 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -1719,7 +1719,7 @@ void MDCache::project_rstat_inode_to_frag(CInode *cur, CDir *parent, snapid_t fi if (cur->last >= floor) _project_rstat_inode_to_frag(*curi, MAX(first, floor), cur->last, parent, linkunlink); - for (set::iterator p = cur->dirty_old_rstats.begin(); + for (compact_set::iterator p = cur->dirty_old_rstats.begin(); p != cur->dirty_old_rstats.end(); ++p) { old_inode_t& old = cur->old_inodes[*p];