2010年2月2日火曜日

LRU at BPStudy with JSSpec.

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
まあまあ手になじむ。あとは非同期なモノをどうかけるのかをチェックするべし。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ko">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<title>LRU JSSpec results</title>
<link rel="stylesheet" type="text/css" href="../src/JSSpec.css" />
<script type="text/javascript" src="../src/diff_match_patch.js"></script>
<script type="text/javascript" src="../src/JSSpec.js"></script>
<script type="text/javascript">// <![CDATA[

function debug(){
  if (window['console']){
    console.log.apply(null, arguments);
  }
};

function LRU(maxSize){
  return {
    '_store' : [],
    '_maxSize': maxSize,
    'maxSize': function(){
      var self = this;
      return self._maxSize;
    },
    'put': function(key, value){
      var self = this;
      var p;
      var n;
      var v;
      p = self._peek(key);
      n = p[0];
      v = p[1];
      if (n >=0){
        self._store = self._store.slice(0, n).concat(self._store.slice(n+1));
        debug('self._store', self._store);
        self._store.push([key, value]);
        return;
      }else{
        self._touch(key, value);
      };
    },
    '_peek': function(key){
      var self = this;
      var n;
      var k;
      var v;
      for (n in self._store){
        k = self._store[n][0];
        v = self._store[n][1];
        if (k==key){
          return [n, v];
        };
      };
      return [-1, null];
    },
    'get': function(key){
      var self = this;
      var n;
      var k;
      var v;
      p = self._peek(key);
      n = p[0];
      v = p[1];
      if (v != null){
        self._touch(key);
      };
      return v;
    },
    _touch: function(key, new_value){
      var self = this;
      var p;
      var n;
      var v;
      p = self._peek(key);
      n = p[0];
      v = p[1];
      if (n >=0){
        // found so pop and append key-value pair with new value.
        self._store = self._store.slice(0, n).concat(self._store.slice(n+1));
        self._store.push([key, v]);
        return;
      };

      // not found in _store, 
      if (typeof(new_value) != 'undefined'){
        self._store.push([key, new_value]);
        if (self._store.length > maxSize){
          self._store = self._store.slice(1);
        };
        return;
      }
    }
  };
};


describe('LRU', {
        'before': function() {
                target = LRU(2);
        },
        'should 現在の最大サイズを返す。': function() {
                value_of(target.maxSize()).should_be(2);
        },
        'should keyに対応する値がなければnullを返す。': function() {
                value_of(target._peek('foo')[1]).should_be(null);
        },
        'should keyに対応する値を内部状態を変えることなく返す。': function() {
                target.put('foo', 42);
                value_of(target._peek('foo')[1]).should_be(42);
        },
        'should keyの値が同じなら上書きされる。': function() {
                target.put('foo', 0);
                target.put('foo', 42);
                value_of(target._peek('foo')[1]).should_be(42);
        },
        'should sizeよりたくさん入れると始めに入れたやつが消える。': function() {
                target.put('foo', 42);
                target.put('bar', 43);
                target.put('buzz', 44);
                value_of(target._peek('foo')[1]).should_be(null);
                value_of(target._peek('bar')[1]).should_be(43);
                value_of(target._peek('buzz')[1]).should_be(44);
        },
        'should getすると居残る。': function() {
                target.put('foo', 42);
                target.put('bar', 43);
                value_of(target.get('foo')).should_be(42);
                target.put('buzz', 44);
                value_of(target._peek('foo')[1]).should_be(42);
                value_of(target._peek('bar')[1]).should_be(null);
                value_of(target._peek('buzz')[1]).should_be(44);
        },

})

// ]]></script>
</head>
<body><div style="display:none;"><p>A</p><p>B</p></div></body>
</html>

0 件のコメント: