swoole_table应用类
<?php
/* Redis可真能坑爷,原先的设计用redis保存临时数据,可到了实际应用(实际上也就是几十个人同时用),总是出现莫名其妙的问题,最常见的就是读不出数据来,调试了好多天,那问题还是偶尔出现(也不是一直有,偶尔读不到),幸好这段时间接触swoole,发现有swoole_table这么个好东东,于是就先试试吧,下面的就是用于替换redis的。完了后再测,基本没出什么异常,也用了N个客户端同时自动发送(比原先十几个人手工发速度要快很多了),运行了十多分钟,基本没问题。 swoole_table还有些功能上的不足之处:
1,不能getAll,可能是我没找到方法吧,于是就另外建个表专门用于记录键,虽然这样应付不了多少数据,而且可能也很慢,但这是目前能想到的唯一的办法。
2,可保存的数据类型只有:string,int,float,如果能加上数组就好了,或者在保存时,若是数组,自动转换JSON,会好很多。
3,创建表时,有点麻烦,如果能象redis那样允许直接一个字串就好了,虽然可以创建只有一个列的表,可还是觉得有点不方便; 下面的类是完整应用类,里面的表结构需根据实际需要设置 调用: $mem=new Mem_swoole(); 然后就可以按对象直接使用啦。 */ class Mem_swoole
{
private $user;//数据表
private $client;//数据表
private $master;//数据表 private $index;//保存数据表的所有键
private $count;//计数器 private $temp;//测试表 public function __construct($conf = [])
{
$user = [];
$user[] = ['key' => 'ip', 'type' => 'string', 'len' => 15];
$user[] = ['key' => 'port', 'type' => 'int', 'len' => 4];
$user[] = ['key' => 'dns', 'type' => 'string', 'len' => 30];
$user[] = ['key' => 'pid', 'type' => 'int', 'len' => 4];
$user[] = ['key' => 'mode', 'type' => 'int', 'len' => 2];
$user[] = ['key' => 'screen', 'type' => 'string', 'len' => 10];
$user[] = ['key' => 'name', 'type' => 'string', 'len' => 30]; $client = [];
$client[] = ['key' => 'dns', 'type' => 'string', 'len' => 15];
$client[] = ['key' => 'client', 'type' => 'string', 'len' => 100]; $master = [];
$master[] = ['key' => 'id', 'type' => 'int', 'len' => 4];
$master[] = ['key' => 'dns', 'type' => 'string', 'len' => 15];
$master[] = ['key' => 'lv', 'type' => 'int', 'len' => 1]; $index = [];
$index[] = ['key' => 'keys', 'type' => 'string', 'len' => 65536]; $count = [];
$count[] = ['key' => 'send', 'type' => 'int', 'len' => 8]; $this->user = new swoole_table(1024);
$this->client = new swoole_table(1024);
$this->master = new swoole_table(1024);
$this->index = new swoole_table(8);
$this->count = new swoole_table(8); $this->column($this->user, $user);
$this->column($this->client, $client);
$this->column($this->master, $master);
$this->column($this->index, $index);
$this->column($this->count, $count); $this->user->create();
$this->client->create();
$this->master->create();
$this->index->create();
$this->count->create();
} /**
* swoole_table的测试
* @param string $table
*/
public function test($table = 'temp')
{
$count = [];
$count[] = ['key' => 'name', 'type' => 'string', 'len' => 50];
$count[] = ['key' => 'title', 'type' => 'string', 'len' => 50]; $this->{$table} = new swoole_table(1024);
$allType = ['int' => swoole_table::TYPE_INT, 'string' => swoole_table::TYPE_STRING, 'float' => swoole_table::TYPE_FLOAT];
foreach ($count as $row) {
$this->{$table}->column($row['key'], $allType[$row['type']], $row['len']);
}
$this->{$table}->create(); foreach ([1, 2, 3] as $val) {
$value = ['title' => "这是第{$val}个标题"];
$this->{$table}->set("K_{$val}", $value);
$this->record($table, "K_{$val}");
} foreach ([4, 5, 6] as $val) {
$value = ['name' => "这是第{$val}个名字"];
$this->{$table}->set("K_{$val}", $value);
$this->record($table, "K_{$val}");
} foreach ([7, 8, 9] as $val) {
$value = ['name' => "这是第{$val}个名字", 'title' => "这是第{$val}个标题"];
$this->{$table}->set("K_{$val}", $value);
$this->record($table, "K_{$val}");
} $value = [];
foreach ([1, 2, 3, 4, 5, 6, 7, 8, 9] as $val) {
$value["K_{$val}"] = $this->{$table}->get("K_{$val}");
} $key = $this->record($table);
$all = $this->getAll($table);
print_r($value);
print_r($key);
print_r($all);
} /**
* 数据表定义
* @param $name
* @param $type
* @param int $len
*/
private function column(swoole_table $table, $arr)
{
$allType = ['int' => swoole_table::TYPE_INT, 'string' => swoole_table::TYPE_STRING, 'float' => swoole_table::TYPE_FLOAT];
foreach ($arr as $row) {
if (!isset($allType[$row['type']])) $row['type'] = 'string';
$table->column($row['key'], $allType[$row['type']], $row['len']);
}
} /**
* 存入【指定表】【行键】【行值】
* @param $key
* @param array $array
* @return bool
*/
public function set($table, $key, array $array)
{
$this->{$table}->set($key, $this->checkArray($array));
$this->add($table, 1);
return $this->record($table, $key);
} /**
* 存入数据时,遍历数据,二维以上的内容转换JSON
* @param array $array
* @return array
*/
private function checkArray(array $array)
{
$value = [];
foreach ($array as $key => $arr) {
$value[$key] = is_array($arr) ? json_encode($arr, 256) : $arr;
}
return $value;
} /**
* 读取【指定表】的【行键】数据
* @param $key
* @return array
*/
public function get($table, $key)
{
return $this->{$table}->get($key);
} /**
* 读取【指定表】所有行键值和记录
* @param $table
* @return array
*/
public function getAll($table)
{
$recode = $this->record($table);
return $this->getKeyValue($table, $recode);
} /**
* 读取【指定表】【指定键值】的记录
* @param $table
* @param $recode
* @return array
*/
public function getKeyValue($table, $recode)
{
$value = [];
foreach ($recode as $i => $key) {
$value[$key] = $this->get($table, $key);
}
return $value;
} /**
* 读取【指定表】的所有行键
* @param $table
* @return array
*/
public function getKey($table)
{
return $this->record($table);
} /**
* 记录【某个表】所有记录的键值,或读取【某个表】
* @param $table
* @param null $key 不指定为读取
* @param bool|true $add 加,或减
* @return array
*/
private function record($table, $key = null, $add = true)
{
$this->index->lock();
$oldVal = $this->index->get($table);
if (!$oldVal) {
$tmpArr = [];
} else {
$tmpArr = explode(',', $oldVal['keys']);
}
if ($key === null) {//读取,直接返回
$this->index->unlock();
return $tmpArr;
}
if ($add === true) {//加
$tmpArr[] = $key;
$tmpArr = array_unique($tmpArr);//过滤重复
} else {//减
$tmpArr = array_flip($tmpArr);//交换键值
unset($tmpArr[$key]);
$tmpArr = array_flip($tmpArr);//交换回来
}
$this->index->set($table, ['keys' => implode(',', $tmpArr)]);
return $this->index->unlock();
} /**
* 删除key
* @param $key
* @return bool
*/
public function del($table, $key)
{
$this->{$table}->del($key);
$this->add($table, -1);
return $this->record($table, $key, false);
} /**
* 原子自增操作,可用于整形或浮点型列
* @param string $TabKey 表名.键名,但这儿的键名要是预先定好义的
* @param int $incrby 可以是正数、负数,或0,=0时为读取值
* @return bool
*/
public function add($TabKey = 'count.send', $incrby = 1)
{
if (is_int($TabKey)) list($incrby, $TabKey) = [$TabKey, 'count.send'];
list($table, $column, $tmp) = explode('.', $TabKey . '.send.'); if ($incrby >= 0) {
return $this->count->incr($table, $column, $incrby);
} else {
return $this->count->decr($table, $column, 0 - $incrby);
}
} /**
* 某表行数
* @param string $TabKey
* @return bool
*/
public function len($TabKey = 'count.send')
{
return $this->add($TabKey, 0);
} /**
* 锁定整个表
* @return bool
*/
public function lock($table)
{
return $this->{$table}->lock();
} /**
* 释放表锁
* @return bool
*/
public function unlock($table)
{
return $this->{$table}->unlock();
} }
swoole_table应用类的更多相关文章
- Java类的继承与多态特性-入门笔记
相信对于继承和多态的概念性我就不在怎么解释啦!不管你是.Net还是Java面向对象编程都是比不缺少一堂课~~Net如此Java亦也有同样的思想成分包含其中. 继承,多态,封装是Java面向对象的3大特 ...
- C++ 可配置的类工厂
项目中常用到工厂模式,工厂模式可以把创建对象的具体细节封装到Create函数中,减少重复代码,增强可读和可维护性.传统的工厂实现如下: class Widget { public: virtual i ...
- Android请求网络共通类——Hi_博客 Android App 开发笔记
今天 ,来分享一下 ,一个博客App的开发过程,以前也没开发过这种类型App 的经验,求大神们轻点喷. 首先我们要创建一个Andriod 项目 因为要从网络请求数据所以我们先来一个请求网络的共通类. ...
- ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第二章:利用模型类创建视图、控制器和数据库
在这一章中,我们将直接进入项目,并且为产品和分类添加一些基本的模型类.我们将在Entity Framework的代码优先模式下,利用这些模型类创建一个数据库.我们还将学习如何在代码中创建数据库上下文类 ...
- ASP.NET Core 折腾笔记二:自己写个完整的Cache缓存类来支持.NET Core
背景: 1:.NET Core 已经没System.Web,也木有了HttpRuntime.Cache,因此,该空间下Cache也木有了. 2:.NET Core 有新的Memory Cache提供, ...
- .NET Core中间件的注册和管道的构建(2)---- 用UseMiddleware扩展方法注册中间件类
.NET Core中间件的注册和管道的构建(2)---- 用UseMiddleware扩展方法注册中间件类 0x00 为什么要引入扩展方法 有的中间件功能比较简单,有的则比较复杂,并且依赖其它组件.除 ...
- Java基础Map接口+Collections工具类
1.Map中我们主要讲两个接口 HashMap 与 LinkedHashMap (1)其中LinkedHashMap是有序的 怎么存怎么取出来 我们讲一下Map的增删改查功能: /* * Ma ...
- PHP-解析验证码类--学习笔记
1.开始 在 网上看到使用PHP写的ValidateCode生成验证码码类,感觉不错,特拿来分析学习一下. 2.类图 3.验证码类部分代码 3.1 定义变量 //随机因子 private $char ...
- C# 多种方式发送邮件(附帮助类)
因项目业务需要,需要做一个发送邮件功能,查了下资料,整了整,汇总如下,亲测可用- QQ邮箱发送邮件 #region 发送邮箱 try { MailMessage mail = new MailMess ...
随机推荐
- graphviz 的节点形状
graphviz 的节点可以定义不同的外形,比如下面的定义, digraph tt1{ a[shape=box]; c[shape=lpromoter]; d[shape=do ...
- div实现返回符,倒三角,椭圆+小知识收集
收集: 1,返回符(伪类元素): .back:before {content: "";width: .3rem;height: .3rem;border-left: .04rem ...
- ios移动端禁止双指缩放功能
在实际开发中,我们禁止缩放的实现方式: 1.meta设置: <meta name="viewport" content="width=device-width,h ...
- sublime text插件推荐
time: 2016-05-23 13:00 --- 用了Sublime Text有一段时间了,之前被周围的几个前端小伙伴灌输的思想就是,牛b的前端程序员都是手写代码的,用代码提示啥的都low,然而上 ...
- ubuntu下使用python3的有些库时,解决"raise ImportError(str(msg) + ', please install the python3-tk package') ImportError: No module named '_tkinter', please install the python3-tk package"的错误
问题: 在Ubuntu下使用matplotlib这个库时,运行时出现如下错误: raise ImportError(str(msg) + ', please install the python3-t ...
- FineReport中如何实现自动滚屏效果
对于一些特殊的模板,可能为了展示的更加丰富.全面会在一个页面放置很多图表.表格等内容.由于内容过多,超出了浏览器窗口的大小导致内容展示不全的情况.这样我们就需要用到JS滚屏效果来解决,这里主要介绍在F ...
- 签署您的应用--手动签署 APK
签署您的应用 本文内容 证书和密钥库 签署您的调试构建 调试证书的有效期 管理您的密钥 使用 Google Play 应用签名 自行管理您的密钥和密钥库 签署 APK 生成密钥和密钥库 手动签署 AP ...
- Pycharm Html CSS JS 快捷方式创建元素
div#div1>ol>li.id*4 tab键 <div id="div1"> <ol> <li id="id"&g ...
- 在线制作GIF图片项目愿景与范围
在线制作GIF图片项目愿景与范围 a. 业务需求 a.1 背景 在当今社会中,随着聊天软件和web网站的普及,原创动画制作越来越吸引人们的眼球,一个好的动态图片,可能就会为你的网站或本人赢得更多人的认 ...
- CSS 小结笔记之选择器
Css选择器主要分为以下几类 类选择器 ID选择器 通配符选择器 标签选择器 伪类选择器 复合选择器 1.类选择器:通过.classname 来选择 例如 .color2 { color: rebec ...