OSDN Git Service

Fix the bug of X.NodeAnime.
[pettanr/clientJs.git] / 0.6.x / js / 01_core / 10_XPair.js
1 /**\r
2  * Object(Array|Function)をキーにする、キーバリューストアを作る。js 自体にオブジェクトをキーとするハッシュの機能は無い為、内部はArrayで代用している。そのため値へのアクセスは低速。\r
3  * 値を隠蔽したい場合に加え、速度が問題にならないケースや、速度対策を実施したうえで使用する。\r
4  * @namespace X.Pair\r
5  */\r
6 X[ 'Pair' ] = {\r
7         'create'  : X_Pair_create,\r
8         \r
9         'get'     : X_Pair_get,\r
10         \r
11         'release' : X_Pair_release\r
12 };\r
13 \r
14 var X_Pair_SIZE            = 1024,\r
15         X_Pair_KEY_STORE_LIST  = [[]],\r
16         X_Pair_PAIR_STORE_LIST = [[]],\r
17         X_Pair_noChashe        = false,\r
18         \r
19         X_Pair_functionString  = new Function( 's', 'p', 'k', (function(){\r
20                 var ret = 'var i=0,l=s.length,a;' +\r
21                                   'for(;i<l;++i){' +\r
22                                   'a=s[i];' +\r
23                                   'switch(k){',\r
24                         j = 0, hex;\r
25                 for( ; j < X_Pair_SIZE; ++j ){\r
26                         hex = j.toString( 16 );\r
27                         ret += 'case a[0x' + hex + ']:return p[i][0x' + hex + '];';\r
28                 };\r
29                 return ret + '}}';\r
30         })()),\r
31         \r
32         // TODO キャッシュするペアの数とヒット率、探索時間の記録\r
33         X_Pair_lastKey, X_Pair_lastPair;\r
34 \r
35 /**\r
36  * Object(Array|Function)をキーとして値を登録。すでにキーが登録されている場合は登録できない。\r
37  * @alias X.Pair.create\r
38  * @param {object|function|array} key\r
39  * @param {*} pair == false な値は不可\r
40  * @return {boolean} true の場合、登録成功\r
41  */\r
42 function X_Pair_create( key, pair ){\r
43         var keyStore  = X_Pair_KEY_STORE_LIST[ X_Pair_KEY_STORE_LIST.length - 1 ],\r
44                 pairStore = X_Pair_PAIR_STORE_LIST[ X_Pair_PAIR_STORE_LIST.length - 1 ];\r
45         \r
46         X_Pair_noChashe = true;\r
47         if( !pair || X_Pair_get( key ) || !( X_Type_isObject( key ) || X_Type_isArray( key ) || X_Type_isFunction( key ) ) ) return false;\r
48         \r
49         if( keyStore.length === X_Pair_SIZE ){\r
50                 keyStore  = X_Pair_KEY_STORE_LIST[ X_Pair_KEY_STORE_LIST.length   ] = [];\r
51                 pairStore = X_Pair_PAIR_STORE_LIST[ X_Pair_PAIR_STORE_LIST.length ] = [];\r
52         };\r
53         \r
54         keyStore[  keyStore.length  ] = key;\r
55         pairStore[ pairStore.length ] = pair;\r
56         return true;\r
57 };\r
58 \r
59 /**\r
60  * キーとペアになっている値の取得。\r
61  * @alias X.Pair.get\r
62  * @param {object|function|array} key\r
63  * @return {*}\r
64  */\r
65 function X_Pair_get( key ){\r
66         var chashe = !X_Pair_noChashe, pair;\r
67         \r
68         X_Pair_noChashe = false;\r
69         if( key === X_Pair_lastKey ) return X_Pair_lastPair; // quick\r
70         \r
71         if( ( pair = X_Pair_functionString( X_Pair_KEY_STORE_LIST, X_Pair_PAIR_STORE_LIST, key ) ) && chashe ){\r
72                 X_Pair_lastKey  = key;\r
73                 X_Pair_lastPair = pair;\r
74         };\r
75         return pair;\r
76 };\r
77 \r
78 /**\r
79  * キー/バリューのペアを解消する。バリューは指定しなくても可。\r
80  * @alias X.Pair.release\r
81  * @param {object|function|array} key\r
82  * @param {*} [pair=]\r
83  * @return {boolean} true の場合解除成功\r
84  */\r
85 function X_Pair_release( key, opt_pair ){\r
86         var i = 0,\r
87                 l = X_Pair_KEY_STORE_LIST.length,\r
88                 keyStore, pairStore, j;\r
89         \r
90         for( ; i < l; ++i ){\r
91                 keyStore  = X_Pair_KEY_STORE_LIST[ i ];\r
92                 pairStore = X_Pair_PAIR_STORE_LIST[ i ];\r
93                 j = keyStore.indexOf( key );\r
94                 if( j !== -1 && ( opt_pair === undefined || pairStore[ j ] === opt_pair ) ){\r
95                         keyStore.splice( j, 1 );\r
96                         pairStore.splice( j, 1 );\r
97                         if( X_Pair_lastKey === key ){\r
98                                 X_Pair_lastKey = X_Pair_lastPair = null;\r
99                         };\r
100                         return true;\r
101                 };\r
102         };\r
103         return false;\r
104 };\r
105 \r