]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
added clean bh merging, removed unnecessary dirty list
authorsageweil <sageweil@29311d96-e01e-0410-9327-a35deaab8ce9>
Tue, 28 Aug 2007 21:18:17 +0000 (21:18 +0000)
committersageweil <sageweil@29311d96-e01e-0410-9327-a35deaab8ce9>
Tue, 28 Aug 2007 21:18:17 +0000 (21:18 +0000)
git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@1716 29311d96-e01e-0410-9327-a35deaab8ce9

trunk/ceph/ebofs/BufferCache.cc
trunk/ceph/ebofs/BufferCache.h

index 18912aa867e6fb6ee6285443696ad398e6c1e172..b02f4e0058ac2634581274bc3174bed55adee16f 100644 (file)
@@ -133,7 +133,10 @@ void ObjectCache::tx_finish(ioh_t ioh, block_t start, block_t length,
     assert(p->first == bh->start());
 
     // past?
-    if (p->first >= start+length) break;
+    if (p->first >= start+length) {
+      bh->oc->try_merge_bh_right(p);
+      break;
+    }
 
     if (bh->tx_ioh == ioh)
       bh->tx_ioh = 0;
@@ -149,6 +152,7 @@ void ObjectCache::tx_finish(ioh_t ioh, block_t start, block_t length,
       assert(bh->end() <= start+length);
       bh->set_last_flushed(version);
       bc->mark_clean(bh);
+      bh->oc->try_merge_bh_left(p);
     } else {
       dout(10) << "tx_finish  leaving tx, " << bh->version << " > " << version 
                << " on " << *bh << dendl;
@@ -714,6 +718,83 @@ void ObjectCache::clone_to(Onode *other)
 
 
 
+BufferHead *ObjectCache::merge_bh_left(BufferHead *left, BufferHead *right)
+{
+  dout(-10) << "merge_bh_left " << *left << " " << *right << dendl;
+  assert(left->end() == right->start());
+  assert(left->is_clean());
+  assert(right->is_clean());
+  assert(right->get_num_ref() == 0);
+
+  // hrm, is this right?
+  if (right->version > left->version) left->version = right->version;
+  if (right->last_flushed > left->last_flushed) left->last_flushed = right->last_flushed;
+
+  left->set_length(left->length() + right->length());
+  left->data.claim_append(right->data);
+
+  // remove right
+  remove_bh(right);
+  bc->lru_rest.lru_remove(right);
+  delete right;  
+  dout(-10) << "merge_bh_left result " << *left << dendl;
+  return left;
+}
+
+/* wait until this has a user
+void ObjectCache::try_merge_bh(BufferHead *bh)
+{
+  dout(-10) << "try_merge_bh " << *bh << dendl;
+
+  map<block_t, BufferHead*>::iterator p = data.lower_bound(bh->start());
+  assert(p->second == bh);
+  
+  try_merge_bh_left(p);
+  try_merge_bh_right(p);
+}
+*/
+
+
+void ObjectCache::try_merge_bh_left(map<block_t, BufferHead*>::iterator& p)
+{
+  BufferHead *bh = p->second;
+  dout(10) << "try_merge_bh_left " << *bh << dendl;
+
+  // left?
+  if (p != data.begin()) {
+    p--;
+    if (p->second->end() == bh->start() &&
+       p->second->is_clean() && 
+       bh->is_clean() &&
+       bh->get_num_ref() == 0)
+      bh = merge_bh_left(p->second, bh);      // yay!
+    else 
+      p++;      // nope.
+  }
+}
+
+void ObjectCache::try_merge_bh_right(map<block_t, BufferHead*>::iterator& p)
+{
+  BufferHead *bh = p->second;
+  dout(10) << "try_merge_bh_right " << *bh << dendl;
+
+  // right?
+  map<block_t, BufferHead*>::iterator o = p;
+  p++;
+  if (p != data.end() &&
+      bh->end() == p->second->start() && 
+      p->second->is_clean() && 
+      bh->is_clean() &&
+      p->second->get_num_ref() == 0) {
+    BufferHead *right = p->second;
+    p--;
+    merge_bh_left(bh, right);
+  } else
+    p = o;
+}
+
+
+
 /************** BufferCache ***************/
 
 #undef dout
@@ -787,6 +868,8 @@ BufferHead *BufferCache::split(BufferHead *orig, block_t after)
 }
 
 
+
+
 void BufferCache::bh_read(Onode *on, BufferHead *bh, block_t from)
 {
   dout(10) << "bh_read " << *on << " on " << *bh << dendl;
index 24aeccc4a200c56cf6918ff11c379de0e6e333b8..346a5cc7856183ce404732546e0b046c9a5a1012 100644 (file)
@@ -25,6 +25,7 @@
 #include "BlockDevice.h"
 
 #include "include/interval_set.h"
+#include "include/xlist.h"
 
 class ObjectCache;
 class BufferCache;
@@ -62,6 +63,7 @@ class BufferHead : public LRUObject {
   set<BufferHead*>  shadows;     // shadow bh's that clone()ed me.
   BufferHead*       shadow_of;
 
+
  private:
   int        ref;
   int        state;
@@ -75,6 +77,7 @@ class BufferHead : public LRUObject {
   Extent     object_loc;     // block position _in_object_
 
   utime_t    dirty_stamp;
+  //xlist<BufferHead*>::item xlist_dirty;
 
   bool       want_to_expire;  // wants to be at bottom of lru
 
@@ -84,6 +87,7 @@ class BufferHead : public LRUObject {
     rx_ioh(0), tx_ioh(0), tx_block(0), partial_tx_to(0), partial_tx_epoch(0),
     shadow_of(0),
     ref(0), state(STATE_MISSING), epoch_modified(0), version(0), last_flushed(0),
+    //xlist_dirty(this),
     want_to_expire(false)
     {}
   ~BufferHead() {
@@ -103,6 +107,7 @@ class BufferHead : public LRUObject {
     --ref;
     return ref;
   }
+  int get_num_ref() { return ref; }
 
   block_t start() { return object_loc.start; }
   void set_start(block_t s) { object_loc.start = s; }
@@ -283,7 +288,7 @@ class BufferHead : public LRUObject {
         continue;
       }
       // overlap tail of i?
-      if (off > i->first && off < i->first + i->second.length()) {
+      if (off > i->first && off+len >= i->first + i->second.length()) {
         // shorten i.
         bufferlist o;
         o.claim( i->second );
@@ -293,7 +298,7 @@ class BufferHead : public LRUObject {
         continue;
       }
       // overlap head of i?
-      if (off < i->first && off+len < i->first + i->second.length()) {
+      if (off <= i->first && off+len < i->first + i->second.length()) {
         // move i (make new tail).
         off_t tailoff = off+len;
         unsigned trim = tailoff - i->first;
@@ -322,7 +327,6 @@ class BufferHead : public LRUObject {
     partial[off] = p;
   }
 
-
 };
 
 inline ostream& operator<<(ostream& out, BufferHead& bh)
@@ -413,6 +417,11 @@ class ObjectCache {
   }
   bool is_empty() { return data.empty(); }
 
+  void try_merge_bh(BufferHead *bh);
+  void try_merge_bh_left(map<block_t, BufferHead*>::iterator& p);
+  void try_merge_bh_right(map<block_t, BufferHead*>::iterator& p);
+  BufferHead* merge_bh_left(BufferHead *left, BufferHead *right);
+
   int find_tx(block_t start, block_t len,
               list<BufferHead*>& tx);
 
@@ -459,7 +468,7 @@ class BufferCache {
   Mutex             &ebofs_lock;          // hack: this is a ref to global ebofs_lock
   BlockDevice       &dev;
 
-  set<BufferHead*> dirty_bh;
+  //xlist<BufferHead*> dirty_bh;
 
   LRU   lru_dirty, lru_rest;
 
@@ -521,7 +530,7 @@ class BufferCache {
     bh->get_oc()->add_bh(bh);
     if (bh->is_dirty()) {
       lru_dirty.lru_insert_mid(bh);
-      dirty_bh.insert(bh);
+      //dirty_bh.push_back(&bh->xlist_dirty);
     } else
       lru_rest.lru_insert_mid(bh);
     stat_add(bh);
@@ -544,7 +553,7 @@ class BufferCache {
     stat_sub(bh);
     if (bh->is_dirty()) {
       lru_dirty.lru_remove(bh);
-      dirty_bh.erase(bh);
+      //dirty_bh.push_back(&bh->xlist_dirty);
     } else
       lru_rest.lru_remove(bh);
   }
@@ -612,7 +621,7 @@ class BufferCache {
     if (s == BufferHead::STATE_DIRTY && bh->get_state() != BufferHead::STATE_DIRTY) {
       lru_rest.lru_remove(bh);
       lru_dirty.lru_insert_top(bh);
-      dirty_bh.insert(bh);
+      //dirty_bh.push_back(&bh->xlist_dirty);
     }
     if (s != BufferHead::STATE_DIRTY && bh->get_state() == BufferHead::STATE_DIRTY) {
       lru_dirty.lru_remove(bh);
@@ -620,7 +629,7 @@ class BufferCache {
        lru_rest.lru_insert_bot(bh);
       else
        lru_rest.lru_insert_mid(bh);
-      dirty_bh.erase(bh);
+      //dirty_bh.remove(&bh->xlist_dirty);
     }
 
     // set state