HashMap和Hashtable及HashSet的区别

<iframe align="center" marginwidth="0" marginheight="0" src="http://www.zealware.com/csdnblog336280.html" frameborder="0" width="336" scrolling="no" height="280"></iframe>



MemCached的PHP客户端操作类一

<?php <br />//
//+---------------------------------------------------------------------------+
//|memcachedclient,PHP|
//+---------------------------------------------------------------------------+
//|Copyright(c)2003RyanT.Dean<rtdean>| <br>//|Allrightsreserved.| <br>//|| <br>//|Redistributionanduseinsourceandbinaryforms,withorwithout| <br>//|modification,arepermittedprovidedthatthefollowingconditions| <br>//|aremet:| <br>//|| <br>//|1.Redistributionsofsourcecodemustretaintheabovecopyright| <br>//|notice,thislistofconditionsandthefollowingdisclaimer.| <br>//|2.Redistributionsinbinaryformmustreproducetheabovecopyright| <br>//|notice,thislistofconditionsandthefollowingdisclaimerinthe| <br>//|documentationand/orothermaterialsprovidedwiththedistribution.| <br>//|| <br>//|THISSOFTWAREISPROVIDEDBYTHEAUTHOR``ASIS''ANDANYEXPRESSOR| <br>//|IMPLIEDWARRANTIES,INCLUDING,BUTNOTLIMITEDTO,THEIMPLIEDWARRANTIES| <br>//|OFMERCHANTABILITYANDFITNESSFORAPARTICULARPURPOSEAREDISCLAIMED.| <br>//|INNOEVENTSHALLTHEAUTHORBELIABLEFORANYDIRECT,INDIRECT,| <br>//|INCIDENTAL,SPECIAL,EXEMPLARY,ORCONSEQUENTIALDAMAGES(INCLUDING,BUT| <br>//|NOTLIMITEDTO,PROCUREMENTOFSUBSTITUTEGOODSORSERVICES;LOSSOFUSE,| <br>//|DATA,ORPROFITS;ORBUSINESSINTERRUPTION)HOWEVERCAUSEDANDONANY| <br>//|THEORYOFLIABILITY,WHETHERINCONTRACT,STRICTLIABILITY,ORTORT| <br>//|(INCLUDINGNEGLIGENCEOROTHERWISE)ARISINGINANYWAYOUTOFTHEUSEOF| <br>//|THISSOFTWARE,EVENIFADVISEDOFTHEPOSSIBILITYOFSUCHDAMAGE.| <br>//+---------------------------------------------------------------------------+ <br>//|Author:RyanT.Dean<rtdean>| <br>//|HeavilyinfluencedbythePerlmemcachedclientbyBradFitzpatrick.| <br>//|PermissiongrantedbyBradFitzpatrickforrelicenseofportedPerl| <br>//|clientlogicunder2-clauseBSDlicense.| <br>//+---------------------------------------------------------------------------+ <br>// <br>//$TCAnet$ <br>// <br><br>/** <br>*ThisisthePHPclientformemcached-adistributedmemorycachedaemon. <br>*Moreinformationisavailableathttp://www.danga.com/memcached/ <br>* <br>*Usageexample: <br>* <br>*require_once'memcached.php'; <br>* <br>*$mc=newmemcached(array( <br>*'servers'=&gt;array('127.0.0.1:10000', <br>*array('192.0.0.1:10010',2), <br>*'127.0.0.1:10020'), <br>*'debug'=&gt;false, <br>*'compress_threshold'=&gt;10240, <br>*'persistant'=&gt;true)); <br>* <br>*$mc-&gt;add('key',array('some','array')); <br>*$mc-&gt;replace('key','somerandomstring'); <br>*$val=$mc-&gt;get('key'); <br>* <br>*@authorRyanT.Dean<rtdean><br>*@packagememcached-client <br>*@version0.1.2 <br>*/ <br><br>//{{{requirements <br>//}}} <br><br>//{{{constants <br>//{{{flags <br><br>/** <br>*Flag:indicatesdataisserialized <br>*/ <br></rtdean></rtdean></rtdean>
define("MEMCACHE_SERIALIZED",10);

/**
*Flag:indicatesdataiscompressed
*/
define("MEMCACHE_COMPRESSED",11);

//}}}

/**
*Minimumsavingstostoredatacompressed
*/
define("COMPRESSION_SAVINGS",0.20);

//}}}

//{{{classmemcached
/**
*memcachedclientclassimplementedusing(p)fsockopen()
*
*@authorRyanT.Dean<rtdean><br>*@packagememcached-client <br>*/ <br></rtdean>
classmemcached
{
//{{{properties
//{{{public

/**
*Commandstatistics
*
*@vararray
*@accesspublic
*/
var$stats;

//}}}
//{{{private

/**
*CachedSocketsthatareconnected
*
*@vararray
*@accessprivate
*/
var$_cache_sock;

/**
*Currentdebugstatus;0-noneto9-profiling
*
*@varboolean
*@accessprivate
*/
var$_debug;

/**
*Deadhosts,assocarray,'host'=>'unixtimewhenoktocheckagain'
*
*@vararray
*@accessprivate
*/
var$_host_dead;

/**
*Iscompressionavailable?
*
*@varboolean
*@accessprivate
*/
var$_have_zlib;

/**
*Dowewanttousecompression?
*
*@varboolean
*@accessprivate
*/
var$_compress_enable;

/**
*Athowmanybytesshouldwecompress?
*
*@varinterger
*@accessprivate
*/
var$_compress_threshold;

/**
*Areweusingpersistantlinks?
*
*@varboolean
*@accessprivate
*/
var$_persistant;

/**
*Ifonlyusingoneserver;containsip:porttoconnectto
*
*@varstring
*@accessprivate
*/
var$_single_sock;

/**
*Arraycontainingip:portorarray(ip:port,weight)
*
*@vararray
*@accessprivate
*/
var$_servers;

/**
*Ourbitbuckets
*
*@vararray
*@accessprivate
*/
var$_buckets;

/**
*Total#ofbitbucketswehave
*
*@varinterger
*@accessprivate
*/
var$_bucketcount;

/**
*#oftotalserverswehave
*
*@varinterger
*@accessprivate
*/
var$_active;

//}}}
//}}}
//{{{methods
//{{{publicfunctions
//{{{memcached()

/**
*Memcacheinitializer
*
*@paramarray$argsAssociativearrayofsettings
*
*@returnmixed
*@accesspublic
*/
functionmemcached($args)
{
$this->set_servers($args['servers']);
$this->_debug=$args['debug'];
$this->stats=array();
$this->_compress_threshold=$args['compress_threshold'];
$this->_persistant=isset($args['persistant'])?$args['persistant']:false;
$this->_compress_enable=true;
$this->_have_zlib=function_exists("gzcompress");

$this->_cache_sock=array();
$this->_host_dead=array();
}

//}}}
//{{{add()

/**
*Addsakey/valuetothememcacheserverifoneisn'talreadysetwith
*thatkey
*
*@paramstring$keyKeytosetwithdata
*@parammixed$valValuetostore
*@paraminterger$exp(optional)Timetoexpiredataat
*
*@returnboolean
*@accesspublic
*/
functionadd($key,$val,$exp=0)
{
return
$this->_set('add',$key,$val,$exp);
}

//}}}
//{{{decr()

/**
*Decrimentavaluestoredonthememcacheserver
*
*@paramstring$keyKeytodecriment
*@paraminterger$amt(optional)Amounttodecriment
*
*@returnmixedFALSEonfailure,valueonsuccess
*@accesspublic
*/
functiondecr($key,$amt=1)
{
return
$this->_incrdecr('decr',$key,$amt);
}

//}}}
//{{{delete()

/**
*Deletesakeyfromtheserver,optionallyafter$time
*
*@paramstring$keyKeytodelete
*@paraminterger$time(optional)Howlongtowaitbeforedeleting
*
*@returnbooleanTRUEonsuccess,FALSEonfailure
*@accesspublic
*/
functiondelete($key,$time=0)
{
if(!
$this->_active)
return
false;

$sock=$this->get_sock($key);
if(!
is_resource($sock))
return
false;

$key=is_array($key)?$key[1]:$key;

$this->stats['delete']++;
$cmd="delete$key$time/r/n";
if(!
fwrite($sock,$cmd,strlen($cmd)))
{
$this->_dead_sock($sock);
return
false;
}
$res=trim(fgets($sock));

if(
$this->_debug)
printf("MemCache:delete%s(%s)/n",$key,$res);

if(
$res=="DELETED")
return
true;
return
false;
}

//}}}
//{{{disconnect_all()

/**
*Disconnectsallconnectedsockets
*
*@accesspublic
*/
functiondisconnect_all()
{
foreach(
$this->_cache_sockas$sock)
fclose($sock);

$this->_cache_sock=array();
}

//}}}
//{{{enable_compress()

/**
*Enable/Disablecompression
*
*@paramboolean$enableTRUEtoenable,FALSEtodisable
*
*@accesspublic
*/
functionenable_compress($enable)
{
$this->_compress_enable=$enable;
}

//}}}
//{{{forget_dead_hosts()

/**
*Forgetaboutallofthedeadhosts
*
*@accesspublic
*/
functionforget_dead_hosts()
{
$this->_host_dead=array();
}

//}}}
//{{{get()

/**
*Retrievesthevalueassociatedwiththekeyfromthememcacheserver
*
*@paramstring$keyKeytoretrieve
*
*@returnmixed
*@accesspublic
*/
functionget($key)
{
if(!
$this->_active)
return
false;

$sock=$this->get_sock($key);

if(!
is_resource($sock))
return
false;

$this->stats['get']++;

$cmd="get$key/r/n";
if(!
fwrite($sock,$cmd,strlen($cmd)))
{
$this->_dead_sock($sock);
return
false;
}

$val=array();
$this->_load_items($sock,$val);

if(
$this->_debug)
foreach(
$valas$k=>$v)
printf("MemCache:sock%sgot%s=>%s/r/n",$sock,$k,$v);

return
$val[$key];
}

//}}}
//{{{get_multi()

/**
*Getmultiplekeysfromtheserver(s)
*
*@paramarray$keysKeystoretrieve
*
*@returnarray
*@accesspublic
*/
functionget_multi($keys)
{
if(!
$this->_active)
return
false;

$this->stats['get_multi']++;

foreach(
$keysas$key)
{
$sock=$this->get_sock($key);
if(!
is_resource($sock))continue;
$key=is_array($key)?$key[1]:$key;
if(!isset(
$sock_keys[$sock]))
{
$sock_keys[$sock]=array();
$socks[]=$sock;
}
$sock_keys[$sock][]=$key;
}

//Sendouttherequests
foreach($socksas$sock)
{
$cmd="get";
foreach(
$sock_keys[$sock]as$key)
{
$cmd.="".$key;
}
$cmd.="/r/n";

if(
fwrite($sock,$cmd,strlen($cmd)))
{
$gather[]=$sock;
}else
{
$this->_dead_sock($sock);
}
}

//Parseresponses
$val=array();
foreach(
$gatheras$sock)
{
$this->_load_items($sock,$val);
}

if(
$this->_debug)
foreach(
$valas$k=>$v)
printf("MemCache:got%s=>%s/r/n",$k,$v);

return
$val;
}

//}}}
//{{{incr()

/**
*Increments$key(optionally)by$amt
*
*@paramstring$keyKeytoincrement
*@paraminterger$amt(optional)amounttoincrement
*
*@returnintergerNewkeyvalue?
*@accesspublic
*/
functionincr($key,$amt=1)
{
return
$this->_incrdecr('incr',$key,$amt);
}

//}}}
//{{{replace()

/**
*Overwritesanexistingvalueforkey;onlyworksifkeyisalreadyset
*
*@paramstring$keyKeytosetvalueas
*@parammixed$valueValuetostore
*@paraminterger$exp(optional)Experiationtime
*
*@returnboolean
*@accesspublic
*/
functionreplace($key,$value,$exp=0)
{
return
$this->_set('replace',$key,$value,$exp);
}

//}}}
//{{{run_command()

/**
*Passesthrough$cmdtothememcacheserverconnectedby$sock;returns
*outputasanarray(nullarrayifnooutput)
*
*NOTE:duetoapossiblebuginhowPHPreadswhileusingfgets(),each
*linemaynotbeterminatedbya/r/n.Morespecifically,mytesting
*hasshownthat,onFreeBSDatleast,eachlineisterminatedonly
*witha/n.ThisiswiththePHPflagauto_detect_line_endingsset
*tofalase(thedefault).
*
*@paramresource$sockSockettosendcommandon
*@paramstring$cmdCommandtorun
*
*@returnarrayOutputarray
*@accesspublic
*/
functionrun_command($sock,$cmd)
{
if(!
is_resource($sock))
returnarray();

if(!
fwrite($sock,$cmd,strlen($cmd)))
returnarray();

while(
true)
{
$res=fgets($sock);
$ret[]=$res;
if(
preg_match('/^END/',$res))
break;
if(
strlen($res)==0)
break;
}
return
$ret;
}

//}}}
//{{{set()

/**
*Unconditionallysetsakeytoagivenvalueinthememcache.Returnstrue
*ifsetsuccessfully.
*
*@paramstring$keyKeytosetvalueas
*@parammixed$valueValuetoset
*@paraminterger$exp(optional)Experiationtime
*
*@returnbooleanTRUEonsuccess
*@accesspublic
*/
functionset($key,$value,$exp=0)
{
return
$this->_set('set',$key,$value,$exp);
}

//}}}
//{{{set_compress_threshold()

/**
*Setsthecompressionthreshold
*
*@paraminterger$threshThresholdtocompressiflargerthan
*
*@accesspublic
*/
functionset_compress_threshold($thresh)
{
$this->_compress_threshold=$thresh;
}

//}}}
//{{{set_debug()

/**
*Setsthedebugflag
*
*@paramboolean$dbgTRUEfordebugging,FALSEotherwise
*
*@accesspublic
*
*@seememcahced::memcached
*/
functionset_debug($dbg)
{
$this->_debug=$dbg;
}

//}}}
//{{{set_servers()

/**
*Setstheserverlisttodistributekeygetsandputsbetween
*
*@paramarray$listArrayofserverstoconnectto
*
*@accesspublic
*
*@seememcached::memcached()
*/
functionset_servers($list)
{
$this->_servers=$list;
$this->_active=count($list);
$this->_buckets=null;
$this->_bucketcount=0;

$this->_single_sock=null;
if(
$this->_active==1)
$this->_single_sock=$this->_servers[0];
}

//}}}
//}}}
//{{{privatemethods
//{{{_close_sock()

/**
*Closethespecifiedsocket
*
*@paramstring$sockSockettoclose
*
*@accessprivate
*/
function_close_sock($sock)
{
$host=array_search($sock,$this->_cache_sock);
fclose($this->_cache_sock[$host]);
unset(
$this->_cache_sock[$host]);
}

//}}}
//{{{_connect_sock()

/**
*Connects$sockto$host,timingoutafter$timeout
*
*@paraminterger$sockSockettoconnect
*@paramstring$hostHost:IPtoconnectto
*@paramfloat$timeout(optional)Timeoutvalue,defaultsto0.25s
*
*@returnboolean
*@accessprivate
*/
function_connect_sock(&$sock,$host,$timeout=0.25)
{
list(
$ip,$port)=explode(":",$host);
if(
$this->_persistant==1)
{
$sock=@pfsockopen($ip,$port,$errno,$errstr,$timeout);
}else
{
$sock=@fsockopen($ip,$port,$errno,$errstr,$timeout);
}

if(!
$sock)
return
false;
return
true;
}

//}}}
//{{{_dead_sock()

/**
*Marksahostasdeaduntil30-40secondsinthefuture
*
*@paramstring$sockSockettomarkasdead
*
*@accessprivate
*/
function_dead_sock($sock)
{
$host=array_search($sock,$this->_cache_sock);
list(
$ip,$port)=explode(":",$host);
$this->_host_dead[$ip]=time()+30+intval(rand(0,10));
$this->_host_dead[$host]=$this->_host_dead[$ip];
unset(
$this->_cache_sock[$host]);
}

//}}}
//{{{get_sock()

/**
*get_sock
*
*@paramstring$keyKeytoretrievevaluefor;
*
*@returnmixedresourceonsuccess,falseonfailure
*@accessprivate
*/
functionget_sock($key)
{
if(!
$this->_active)
return
false;

if(
$this->_single_sock!==null)
return
$this->sock_to_host($this->_single_sock);

$hv=is_array($key)?intval($key[0]):$this->_hashfunc($key);

if(
$this->_buckets===null)
{
foreach(
$this->_serversas$v)
{
if(
is_array($v))
{
for(
$i=0;$i$v[1];$i++)
$bu[]=$v[0];
}else
{
$bu[]=$v;
}
}
$this->_buckets=$bu;
$this->_bucketcount=count($bu);
}

$realkey=is_array($key)?$key[1]:$key;
for(
$tries=0;$tries20;$tries++)
{
$host=$this->_buckets[$hv%$this->_bucketcount];
$sock=$this->sock_to_host($host);
if(
is_resource($sock))
return
$sock;
$hv+=$this->_hashfunc($tries.$realkey);
}

return
false;
}

//}}}
//{{{_hashfunc()

/**
*Createsahashintergerbasedonthe$key
*
*@paramstring$keyKeytohash
*
*@returnintergerHashvalue
*@accessprivate
*/
function_hashfunc($key)
{
$hash=0;
for(
$i=0;$istrlen($key);$i++)
{
$hash=$hash*33+ord($key[$i]);
}

return
$hash;
}

//}}}
//{{{_incrdecr()

/**
*Performincrement/decrimenton$key
*
*@paramstring$cmdCommandtoperform
*@paramstring$keyKeytoperformiton
*@paraminterger$amtAmounttoadjust
*
*@returnintergerNewvalueof$key
*@accessprivate
*/
function_incrdecr($cmd,$key,$amt=1)
{
if(!
$this->_active)
return
null;

$sock=$this->get_sock($key);
if(!
is_resource($sock))
return
null;

$key=is_array($key)?$key[1]:$key;
$this->stats[$cmd]++;
if(!
fwrite($sock,"$cmd$key$amt/r/n"))
return
$this->_dead_sock($sock);

stream_set_timeout($sock,1,0);
$line=fgets($sock);
if(!
preg_match('/^(/d+)/',$line,$match))
return
null;
return
$match[1];
}

//}}}
//{{{_load_items()

/**
*Loaditemsinto$retfrom$sock
*
*@paramresource$sockSockettoreadfrom
*@paramarray$retReturnedvalues
*
*@accessprivate
*/
function_load_items($sock,&$ret)
{
while(
1)
{
$decl=fgets($sock);
if(
$decl=="END/r/n")
{
return
true;
}elseif(
preg_match('/^VALUE(/S+)(/d+)(/d+)/r/n$/',$decl,$match))
{
list(
$rkey,$flags,$len)=array($match[1],$match[2],$match[3]);
$bneed=$len+2;
$offset=0;

while(
$bneed>0)
{
$data=fread($sock,$bneed);
$n=strlen($data);
if(
$n==0)
break;
$offset+=$n;
$bneed-=$n;
$ret[$rkey].=$data;
}

if(
$offset!=$len+2)
{
//Somethingisborked!
if($this->_debug)
printf("Somethingisborked!key%sexpecting%dgot%dlength/n",$rkey,$len+2,$offset);

unset(
$ret[$rkey]);
$this->_close_sock($sock);
return
false;
}

$ret[$rkey]=rtrim($ret[$rkey]);

if(
$this->_have_zlib&&$flags&MEMCACHE_COMPRESSED)
$ret[$rkey]=gzuncompress($ret[$rkey]);

if(
$flags&MEMCACHE_SERIALIZED)
$ret[$rkey]=unserialize($ret[$rkey]);

}else
{
if(
$this->_debug)
print(
"Errorparsingmemcachedresponse/n");
return
0;
}
}
}

//}}}
//{{{_set()

/**
*Performstherequestedstorageoperationtothememcacheserver
*
*@paramstring$cmdCommandtoperform
*@paramstring$keyKeytoacton
*@parammixed$valWhatweneedtostore
*@paraminterger$expWhenitshouldexpire
*
*@returnboolean
*@accessprivate
*/
function_set($cmd,$key,$val,$exp)
{
if(!
$this->_active)
return
false;

$sock=$this->get_sock($key);
if(!
is_resource($sock))
return
false;

$this->stats[$cmd]++;

$flags=0;

if(!
is_scalar($val))
{
$val=serialize($val);
$flags|=MEMCACHE_SERIALIZED;
if(
$this->_debug)
printf("client:serializingdataasitisnotscalar/n");
}

$len=strlen($val);

if(
$this->_have_zlib&&$this->_compress_enable&&
$this->_compress_threshold&&$len>=$this->_compress_threshold)
{
$c_val=gzcompress($val,9);
$c_len=strlen($c_val);

if(
$c_len$len*(1-COMPRESS_SAVINGS))
{
if(
$this->_debug)
printf("client:compressingdata;was%dbytesisnow%dbytes/n",$len,$c_len);
$val=$c_val;
$len=$c_len;
$flags|=MEMCACHE_COMPRESSED;
}
}
if(!
fwrite($sock,"$cmd$key$flags$exp$len/r/n$val/r/n"))
return
$this->_dead_sock($sock);

$line=trim(fgets($sock));

if(
$this->_debug)
{
if(
$flags&MEMCACHE_COMPRESSED)
$val='compresseddata';
printf("MemCache:%s%s=>%s(%s)/n",$cmd,$key,$val,$line);
}
if(
$line=="STORED")
return
true;
return
false;
}

//}}}
//{{{sock_to_host()

/**
*Returnsthesocketforthehost
*
*@paramstring$hostHost:IPtogetsocketfor
*
*@returnmixedIOStreamorfalse
*@accessprivate
*/
functionsock_to_host($host)
{
if(isset(
$this->_cache_sock[$host]))
return
$this->_cache_sock[$host];

$now=time();
list(
$ip,$port)=explode(":",$host);
if(isset(
$this->_host_dead[$host])&&$this->_host_dead[$host]>$now||
isset(
$this->_host_dead[$ip])&&$this->_host_dead[$ip]>$now)
return
null;

if(!
$this->_connect_sock($sock,$host))
return
$this->_dead_sock($host);

//Donotbufferwrites
stream_set_write_buffer($sock,0);

$this->_cache_sock[$host]=$sock;

return
$this->_cache_sock[$host];
}

//}}}
//}}}
//}}}
}

//}}}
?>




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值