class
memcacheHashMap {
private
$_node
=
array
();
private
$_nodeData
=
array
();
private
$_keyNode
= 0;
private
$_memcache
= null;
private
$_virtualNodeNum
= 200;
private
function
__construct() {
$config
=
array
(
'127.0.0.1:11211'
,
'127.0.0.1:11212'
,
'127.0.0.1:11213'
,
'127.0.0.1:11214'
,
'127.0.0.1:11215'
);
if
(!
$config
)
throw
new
Exception(
'Cache config NULL'
);
foreach
(
$config
as
$key
=>
$value
) {
for
(
$i
= 0;
$i
<
$this
->_virtualNodeNum;
$i
++) {
$this
->_node[sprintf(
"%u"
, crc32(
$value
.
'_'
.
$i
))] =
$value
.
'_'
.
$i
;
}
}
ksort(
$this
->_node);
}
private
function
__clone(){}
static
public
function
getInstance() {
static
$memcacheObj
= null;
if
(!
is_object
(
$memcacheObj
)) {
$memcacheObj
=
new
self();
}
return
$memcacheObj
;
}
private
function
_connectMemcache(
$key
) {
$this
->_nodeData =
array_keys
(
$this
->_node);
$this
->_keyNode = sprintf(
"%u"
, crc32(
$key
));
$nodeKey
=
$this
->_findServerNode();
if
(
$this
->_keyNode >
end
(
$this
->_nodeData)) {
$this
->_keyNode -=
end
(
$this
->_nodeData);
$nodeKey2
=
$this
->_findServerNode();
if
(
abs
(
$nodeKey2
-
$this
->_keyNode) <
abs
(
$nodeKey
-
$this
->_keyNode))
$nodeKey
=
$nodeKey2
;
}
var_dump(
$this
->_node[
$nodeKey
]);
list(
$config
,
$num
) =
explode
(
'_'
,
$this
->_node[
$nodeKey
]);
if
(!
$config
)
throw
new
Exception(
'Cache config Error'
);
if
(!isset(
$this
->_memcache[
$config
])) {
$this
->_memcache[
$config
] =
new
Memcache;
list(
$host
,
$port
) =
explode
(
':'
,
$config
);
$this
->_memcache[
$config
]->connect(
$host
,
$port
);
}
return
$this
->_memcache[
$config
];
}
private
function
_findServerNode(
$m
= 0,
$b
= 0) {
$total
=
count
(
$this
->_nodeData);
if
(
$total
!= 0 &&
$b
== 0)
$b
=
$total
- 1;
if
(
$m
<
$b
){
$avg
=
intval
((
$m
+
$b
) / 2);
if
(
$this
->_nodeData[
$avg
] ==
$this
->_keyNode)
return
$this
->_nodeData[
$avg
];
elseif
(
$this
->_keyNode <
$this
->_nodeData[
$avg
] && (
$avg
-1 >= 0))
return
$this
->_findServerNode(
$m
,
$avg
-1);
else
return
$this
->_findServerNode(
$avg
+1,
$b
);
}
if
(
abs
(
$this
->_nodeData[
$b
] -
$this
->_keyNode) <
abs
(
$this
->_nodeData[
$m
] -
$this
->_keyNode))
return
$this
->_nodeData[
$b
];
else
return
$this
->_nodeData[
$m
];
}
public
function
set(
$key
,
$value
,
$expire
= 0) {
return
$this
->_connectMemcache(
$key
)->set(
$key
, json_encode(
$value
), 0,
$expire
);
}
public
function
add(
$key
,
$value
,
$expire
= 0) {
return
$this
->_connectMemcache(
$key
)->add(
$key
, json_encode(
$value
), 0,
$expire
);
}
public
function
get(
$key
) {
return
json_decode(
$this
->_connectMemcache(
$key
)->get(
$key
), true);
}
public
function
delete
(
$key
) {
return
$this
->_connectMemcache(
$key
)->
delete
(
$key
);
}
}
$runData
[
'BEGIN_TIME'
] = microtime(true);
for
(
$i
=0;
$i
<10000;
$i
++) {
$key
= md5(mt_rand());
$b
= memcacheHashMap::getInstance()->set(
$key
, time(), 10);
}
var_dump(number_format(microtime(true) -
$runData
[
'BEGIN_TIME'
],6));
$runData
[
'BEGIN_TIME'
] = microtime(true);
$m
=
new
Memcache;
$m
->connect(
'127.0.0.1'
, 11211);
for
(
$i
=0;
$i
<10000;
$i
++) {
$key
= md5(mt_rand());
$b
=
$m
->set(
$key
, time(), 0, 10);
}
var_dump(number_format(microtime(true) -
$runData
[
'BEGIN_TIME'
],6));