Cache

これもldr劣化コピー,キューの数によるFIFOなキャッシュ。ちょっと変わってるのは、MochiKit使いなのでキーチェック&生成にAdapterRegistry使ってるくらい。

Cache = function(name, max, key_checker, key_generator) {
  this.name = name;
  this.max = max || 10;
  this.index = {};
  this.pool = [];
  this.key_registry = new AdapterRegistry();
  this.key_registry.register("Cache.key_registry",
                             key_checker || function(obj) {return 1},
                             key_generator || function(obj) {return obj.toString()});
};
Cache.prototype = {
  set: function(key, value) {
    key  = this.get_key(key);
    if ((this.max > 0) && (this.pool.length + 1 > this.max)) {
      delete this.index[this.pool.shift()];
    }
    log("Cache[" +  this.name + "].set:: key = " + key);
    this.index[key] = value;
    this.pool.push(key);
  },
  
  get: function(key) {
    key  = this.get_key(key);
    log("Cache[" + this.name + "].get:: key = " + key);
    return this.index[key];
  },
  
  get_key: function(key_obj) {
    var key;
    try {
      key = this.key_registry.match(key_obj);
    }
    catch(e) {
      if (e != MochiKit.Base.NotFound) {
        throw e;
      }
      key = null;
    }
    return key;
  }
};

以下のように使う。

// setup
var cache_pages = 4;
var yws_cache = new Cache("yws", cache_pages, function(o) {
  return o.hasOwnProperty("search_word") && o.hasOwnProperty("page_no")
}, function(o) {
  return "_" + [o.search_word, o.page_no].join("-")
});

// get cache or set new data
function search(search_word, page_no) {
  var cache = yws_cache.get({search_word: search_word,
                             page_no: current_page});
  if (cahce) {
    render_search_result(cache);
  }
  else {
    var result_set = yahoo_search(search_word, page_no);
    render_search_result(result_set);
    yws_cache.set({search_word: search_word, page_no: page_no}, result_set);
  }
}

javascript版hatebusaでは一度読み込んだ最近の4ページをキャッシュしている。ldrみたいに先読みしたかったんだけど検索にYahoo!Search API使ってるので検索回数制限を気にして読み込み済みページのキャッシュのみにしている。あまり意味ないかなぁと思ってたけどキャッシュの体感速度のデモとしてはいいと思う。
ちゃんとソース追ってないけどldrの挙動見てると先読みはキーボードによるfeed選択(a,s)された場合に有効になる。キーボード操作で読んでる人はシーケンシャルにfeed購読するから先読みすることが重要だけどマウスだとランダムアクセスされる可能性があるので先読みの魅力は無くなるしサーバにも優しくない。当たり前といえば当たり前だけど、とてもよく考えられている。