参考:
将PHP Manual融入(g)Vim : http://www.laruence.com/2010/08/18/1718.html
关于PHP的memcache模块的delete方法
【 可直接参看: http://phpor.net/blog/post/888 】
上篇文章解决了PHP的Memcache 模块的get方法不区分连接失败和NOT FOUND, 今天说一下delete方法不区分NOT FOUND和连接失败的处理办法。
这次的修改不同上次,虽然delete也有第二个参数,但是第二个参数不是引用(当然可以修改成引用,只是稍微麻烦一点);根据delete的特点,不妨将返回值修改为整型(long型); 代码如下:
==== memcache.c =======
- PHP_FUNCTION(memcache_delete)
- {
- …
- if (!mmc_get_pool(mmc_object, &pool TSRMLS_CC) || !pool->num_servers) {
- RETURN_LONG(-1); // 此处修改
- }
- if (mmc_prepare_key_ex(key, key_len, key_tmp, &key_tmp_len TSRMLS_CC) != MMC_OK) {
- RETURN_LONG(-1); // 此处修改
- }
- while (result < 0 && (mmc = mmc_pool_find(pool, key_tmp, key_tmp_len TSRMLS_CC)) != NULL) {
- if ((result = mmc_delete(mmc, key_tmp, key_tmp_len, time TSRMLS_CC)) < 0) {
- mmc_server_failure(mmc TSRMLS_CC);
- }
- }
- if (result > 0) {
- RETURN_LONG(1); // delete OK
- } elseif(result == 0) {
- RETURN_LONG(0); // not found
- }
- RETURN_LONG(-1); // connect fail
- }
测试代码如下:
- <?php
- $m = new Memcache();
- $m->addServer(“127.0.0.1”, 11211); // this is available
- $result = $m->delete(“noexists”);
- var_dump($result);
- $m->set(“exists”,“I am here”,0,600);
- $result = $m->delete(“exists”);
- var_dump($result);
- $m = new Memcache();
- $m->addServer(“127.0.0.1”, 11214); // this is available
- $result = $m->delete(“noexists”);
- var_dump($result);
输出:
int(0)
int(1)
int(-1)
这样修改以后,确实挺好用的,但是,和原来的用法已经不兼容了,除非你原来根本就不判断返回值。
关于PHP的memcache模块的一点修改
缘起
PHP连接Memcached一般有两个模块可以使用: libmemcached和memcache;
libmemcached是不支持PHP的长连接的,但是这个模块对各种错误的处理支持的比较好,如果不要求长连接的话,一般使用该模块。
memcache模块自从我开始使用(3年前)用的是2.2.4版本,到现在stable才到2.2.6; 开发极慢,而且最为让人诟病的一个bug就是: get($key)的返回值对于连接失败和NOT FOUND都是返回false的,以至于我无法知道究竟是哪种错误;如果我不关心二者的区别也就算了,对于必须(或者非常有必要)区别二者的话,只好选择使用libmemcached了。
现在遇到的问题是: 我既要区分连接失败和NOT FOUND,我有需要使用长连接,只好去看memcache的源码了。
解决办法
【可直接参看: http://phpor.net/blog/post/888 】
对于memcache的get方法有第二个参数,这个很少使用(而且用的时候也很是不爽的),就是flag参数,该参数为引用传递,旨在回传memcache中的存储标识,而且比较常用的标识就只有几个(如:压缩);看了一下源码,不妨通过该参数来回传失败的类型,如果是NOT FOUND,则可以将该参数设置一个特殊的标识,具体修改代码如下:
==== memcache.c ===
- int mmc_exec_retrieval_cmd(mmc_pool_t *pool, const char *key, int key_len,
- zval **return_value, zval *return_flags TSRMLS_DC) /* {{{ */
- {
- …
- mmc_t *mmc;
- char *command, *value;
- /* not found */
- if (result == 0) {
- flags |= 1<<30;
- ZVAL_FALSE(*return_value);
- }
- …
- }
下面是一个测试脚本:
- <?php
- $m = new Memcache();
- $m->addServer(“127.0.0.1”, 11211); // this is available
- //$m->addServer(“127.0.0.1”, 11219); //this is unavailable
- define(“E_MC_NO_FOUND”, 1<<30);
- $flag=0; // 这个一定要有值,否则是不会回传$flag的,大概这是一个bug吧
- $result = $m->get(“noexists”,$flag);
- if($result === false) {
- if ($flag & E_MC_NO_FOUND) {
- echo “not found\n”;
- } else {
- echo “connect error\n”;
- }
- }
- echo “flag:”.decbin($flag);
遗留问题:
为什么$flag 不设置一个值就不能回传内部的值,究竟源码错在了何处?
VIM 编程时括号的自动扩展
不解释了,把下面代码贴到.vimrc文件中就行了,然后,重新打开vim,写一个函数试试,我感觉还不错的…
- :inoremap <S-ENTER> <c-r>=SkipPair()<CR>
- :inoremap <S-SPACE> <ESC>la
- :inoremap <C-ENTER> <ESC>A;<CR>
- :inoremap ( ()<ESC>i
- :inoremap ) <c-r>=ClosePair(‘)’)<CR>
- :inoremap { <c-r>=ClsoeBrace()<CR>
- :inoremap } <c-r>=ClosePair(‘}’)<CR>
- :inoremap [ []<ESC>i
- :inoremap ] <c-r>=ClosePair(‘]’)<CR>
- :inoremap ;; <ESC>A;<CR>
- function ClosePair(char)
- if getline(‘.’)[col(‘.’) – 1] == a:char
- return "\<Right>"
- else
- return a:char
- endif
- endf
- function Semicolon()
- "echo getline(‘.’)[col(‘.’)]
- if getline(‘.’)[col(‘.’)] == ‘)’
- return "<ESC>A;"
- elseif getline(‘.’)[col(‘.’)] == ‘}’
- return "\<ESC>A;"
- elseif getline(‘.’)[col(‘.’)] == ‘]’
- return "\<ESC>A;"
- else
- return ";"
- endif
- endf
- function SkipPair()
- if getline(‘.’)[col(‘.’) – 1] == ‘)’
- return "\<ESC>o"
- else
- normal j
- let curline = line(‘.’)
- let nxtline = curline
- while curline == nxtline
- if getline(‘.’)[col(‘.’) – 1] == ‘}’
- normal j
- let nxtline = nxtline + 1
- let curline = line(‘.’)
- continue
- else
- return "\<ESC>i"
- endif
- endwhile
- return "\<ESC>o"
- endif
- endf
- function ClsoeBrace()
- if getline(‘.’)[col(‘.’) – 2] == ‘=’
- return "{}\<ESC>i"
- elseif getline(‘.’)[col(‘.’) – 3] == ‘=’
- return "{}\<ESC>i"
- elseif getline(‘.’)[col(‘.’) – 1] == ‘{‘
- return "{}\<ESC>i"
- elseif getline(‘.’)[col(‘.’) – 2] == ‘{‘
- return "{}\<ESC>i"
- elseif getline(‘.’)[col(‘.’) – 2] == ‘,’
- return "{}\<ESC>i"
- elseif getline(‘.’)[col(‘.’) – 3] == ‘,’
- return "{}\<ESC>i"
- else
- return "{\<ENTER>}\<ESC>O"
- endif
- endf
C++学习之 virtual 关键字
观看一个例子:
- #include <iostream>
- using namespace std;
- class A{
- public:
- virtual void say() {
- cout<<"A say: "<<endl;
- }
- };
- class B :public A{
- public:
- void say() {
- cout<<"B say: "<<endl;
- }
- };
- void testVirtual(A& a) {
- a.say();
- }
- int main(void) {
- B b;
- //b.say("hello B");
- testVirtual(b);
- return 0;
- }
1. 注意 第6行的virtual关键字和第18行的引用传参
2. 现在的结果是 "B say:";
3. 如果去掉virtual关键字,或者传参的时候不使用引用传参,则,输出的结果都将是: "A say:"
4. 这种语法现象叫 upcast
5. c++ 中class声明类,要以分号结束
6. 参考资料: 《C++编程思想》之 第15章 多态性和虚函数
启动gvim时自动最大化窗口的方法
根据帮助文档,gvim在windows下的最大化是通过模拟打开窗口菜单并点击最大化菜单项实现的,而在Linux下的方法较为灵活。
下面的方法是在vim中通过调用wmctrl实现最大化的方法:
1 |
<font><font size="3" face="微软雅黑" color="#ffcc00"><span style="color: rgb(128, 64, 64);">if</span> <span style="color: rgb(37, 187, 77);">has</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(197, 162, 45);">'win32'</span><span style="color: rgb(0, 0, 0);">)</span><br /> <span style="color: rgb(128, 64, 64);">au</span> <span style="color: rgb(37, 187, 77);">GUIEnter</span> <span style="color: rgb(0, 0, 0);">*</span> simalt <span style="color: rgb(0, 0, 0);">~</span>x<br /><span style="color: rgb(128, 64, 64);">else</span><br /> <span style="color: rgb(128, 64, 64);">au</span> <span style="color: rgb(37, 187, 77);">GUIEnter</span> <span style="color: rgb(0, 0, 0);">*</span> <span style="color: rgb(128, 64, 64);">call</span> MaximizeWindow<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><br /><span style="color: rgb(128, 64, 64);">endif</span><br /> <br /><span style="color: rgb(128, 64, 64);">function</span><span style="color: rgb(0, 0, 0);">!</span> MaximizeWindow<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><br /> silent <span style="color: rgb(0, 0, 0);">!</span>wmctrl <span style="color: rgb(0, 0, 0);">-</span>r <span style="color: rgb(0, 0, 0);">:</span>ACTIVE<span style="color: rgb(0, 0, 0);">:</span> <span style="color: rgb(0, 0, 0);">-</span>b <span style="color: rgb(37, 187, 77);">add</span>,maximized_vert,maximized_horz<br />endfunction<br /><br /></font></font>当然也可以通过配置窗口管理器规则实现自动最大化,但上面的方法更灵活<br /> |
vim 文档
给vim添加插件后,如果要启用文档,不单要把插件的doc文件添加到doc目录,还要执行 :helptags doc_dir 命令,这样才能使文档生效。
好久没看c++了
好久没看c++了,以为自己还能看明白,今天看了kyototycoon中的一个类,遇到了好几个知识点:
- // plug-in server driver
- class PlugInDriver : public kc::Thread {
- public:
- // constructor
- explicit PlugInDriver(kt::PluggableServer* serv) : serv_(serv), error_(false) {}
- // get the error flag
- bool error() {
- return error_;
- }
- private:
- // perform service
- void run(void) {
- kc::Thread::sleep(0.4);
- if (serv_->start()) {
- if (!serv_->finish()) error_ = true;
- } else {
- error_ = true;
- }
- }
- kt::PluggableServer* serv_;
- bool error_;
- };
且只看:
explicit PlugInDriver(kt::PluggableServer* serv) : serv_(serv), error_(false) {}
1. explicit 参看: http://wenku.baidu.com/view/3a02f28fcc22bcd126ff0ced.html
explicit 用来修饰构造函数的, 表明构造函数是显示的,而且,由explicit修饰的构造函数为默认构造函数;
因为使用了explicit,则可以:
PlugInDriver p(serv); // 而不能:
PlugInDriver p = serv; // 如果没有explicit ,则这样是可以的, 如:
string s = "abcd"; // 等价于
string s("abcd")
2. serv_(serv), error_(false)
这个是给两个私有成员赋值,至于为什么不卸载构造函数的函数体内,参看《c++编程思想》p329
3. 基类kt::Thread 使用了public来修饰
如果没有public来修饰的话,则子类的所有的public成员和方法在子类上都将体现为private的,这显然不是我们想看到的; 那样则可以只用组合而不用继承了
linux file命令是如何识别文件的类型的
man file、 strace file /bin/ls , 发现:
file命令参考magic文件/usr/share/file/magic.mgc, 如果/usr/share/file/magic.mgc不存在,会参考 /usr/share/file/magic ; 二者的关系为: magic.mgc 是magic 编译后的文件;编译方法为:
file -C /usr/share/file/magic.mgc -m /usr/share/file/magic
tokyocabinet 与 kyotocabinet
tokyocabinet(简称tc) 与 kyotocabinet(简称kc) 有如下主要区别:
1. tc是用c写的,kc使用c++写的
2. kc抛弃了fixedlength database, table database
3. tc只能在类unix系统中编译,kc也支持windows
Tokyo Tyrant(简称tt) 与 Kyoto Tycoon(简称kt)的区别:
1. tt是用c写的,kt使用c++写的
2. tt不支持自动过期,kt支持自动过期
3. kt有几乎tt的所有的优点
4. kt抛弃了fixedlength database, table database
参考文档: http://fallabs.com/kyotocabinet/kyotoproducts.pdf