openwrt修改终端默认波特率

wrtnode boot默认波特率为115200,git 上下载的openwrt源码编译后终端默认波特率是57600,开机后总会出现乱码,新手探索的修改默认波特率的方法:
1.使用stty
opkg update
opkg install coreutils-stty  安装stty
stty -F /dev/ttyS0 ispeed 115200 ospeed 115200   修改终端串口波特率
这样修改完重启后会恢复57600,可以将修改语句放到/etc/rc.local作为启动项
这样修改后在boot结束,启动项启动之前还是会乱码,至少现在用一个波特率就可以操作boot和kernel了,继续探索中。
请大神指教下如何在编译固件时把波特率改好
继续阅读 »
wrtnode boot默认波特率为115200,git 上下载的openwrt源码编译后终端默认波特率是57600,开机后总会出现乱码,新手探索的修改默认波特率的方法:
1.使用stty
opkg update
opkg install coreutils-stty  安装stty
stty -F /dev/ttyS0 ispeed 115200 ospeed 115200   修改终端串口波特率
这样修改完重启后会恢复57600,可以将修改语句放到/etc/rc.local作为启动项
这样修改后在boot结束,启动项启动之前还是会乱码,至少现在用一个波特率就可以操作boot和kernel了,继续探索中。
请大神指教下如何在编译固件时把波特率改好 收起阅读 »

MQTT开源项目应用

EMQ - 百万级开源MQTT消息服务器

EMQ (Erlang/Enterprise/Elastic MQTT Broker)是基于Erlang/OTP平台开发的开源物联网MQTT消息服务器。Erlang/OTP是出色的软实时(Soft-Realtime)、低延时(Low-Latency)、分布式(Distributed)的语言平台。MQTT是轻量的(Lightweight)、发布订阅模式(PubSub)的物联网消息协议。

注解

2.0版本开始emqttd消息服务器自正式简称为EMQ。

EMQ 项目设计目标是承载移动终端或物联网终端海量的MQTT连接,并实现在海量物联网设备间快速低延时(Low-Latency)消息路由:

1. 稳定承载大规模的MQTT客户端连接,单服务器节点支持50万到100万连接。

2. 分布式节点集群,快速低延时的消息路由,单集群支持1000万规模的路由。

3. 消息服务器内扩展,支持定制多种认证方式、高效存储消息到后端数据库。

4. 完整物联网协议支持,MQTT、MQTT-SN、CoAP、WebSocket或私有协议支持。

EMQ 2.0完整支持MQTT V3.1/V3.1.1版本协议规范,并扩展支持WebSocket、Stomp、CoAP、MQTT-SN或私有TCP协议。EMQ 2.0消息服务器支持单节点100万连接与多节点分布式集群:

TODO: 2.0-rc.1图片更新.
emqtt.png

EMQ 2.0为大规模客户端连接(C1000K+)的移动推送、移动消息、物联网、车联网、智能硬件等应用,提供一个完全开放源码、安装部署简便、企业级稳定可靠、可弹性扩展、易于定制开发的MQTT消息服务器。

物联网传感器、智能硬件、移动终端、浏览器、应用服务器与数据服务器通过异步发布订阅模式MQTT消息连接

注解

MQTT-SN、CoAP协议支持已在2.0-rc.1版本发布。
MQTT发布订阅模式简述

MQTT是发布订阅(Publish/Subscribe)模式的消息协议,与HTTP协议请求响应(Request/Response)模式不同。

MQTT发布者与订阅者之间通过”主题”(Topic)进行消息路由,主题(Topic)格式类似Unix文件路径,例如:
sensor/1/temperature

chat/room/subject

presence/user/feng

sensor/1/#

sensor/+/temperature

uber/drivers/joe/inbox

MQTT主题(Topic)支持’+’, ‘#’的通配符,’+’通配一个层级,’#’通配多个层级(必须在末尾)。

MQTT消息发布者(Publisher)只能向特定’名称主题’(不支持通配符)发布消息,订阅者(Subscriber)通过订阅’过滤主题’(支持通配符)来匹配消息。

注解

初接触MQTT协议的用户,通常会向通配符的’过滤主题’发布广播消息,MQTT协议不支持这种模式,需从订阅侧设计广播主题(Topic)。 例如Android推送,向所有广州用户,推送某类本地消息,客户端获得GIS位置后,可订阅’news/city/guangzhou’主题。
EMQ设计

基于出色的软实时、低延时、高并发、分布式的Erlang/OTP语言平台开发设计

按主题树(Topic Trie)和路由表(Routing Table)发布订阅模式在集群节点间转发路由MQTT消息

architecture.png

五分钟下载启动EMQ

EMQ 2.0消息服务器每个版本,会发布Ubuntu、CentOS、FreeBSD、Mac OS X、Windows平台程序包与Docker镜像。下载地址: http://emqtt.com/downloads
 MQTT消息服务器的具体应用
1、移动即时消息
MQTT协议将在即时消息领域逐渐取代XMPP协议,移动消息例如Facebook Messenger采用MQTT协议,我们为部分客户基于EMQ项目定制了即时消息服务端
2、Android、HTML5消息推送
Android客户端通过MQTT协议实现低电量、低带宽消耗的消息推送,ZAKER新闻客户端基于EMQ项目实现单节点90万+连接新闻推送。
3、物联网M2M、物联网大数据
物联网终端通过MQTT协议实现发布订阅模式的M2M通信,物联网网关通过MQTT协议上报传感器数据到云平台进行大数据分析和存储。
4、车联网、电动车站桩管理
电动车联网电池监控,电动车、站、桩传感数据采集与分析。鲁能电力基于EMQ项目开发了电动车联网数据采集分析平台。
5、智能硬件、智能家居、智能电器
智能硬件与移动终端通过MQTT协议实现双向通信与智能控制。智能家居、智能电器通过MQTT协议实时双向连接云端服务器。
6、智慧城市、智慧医疗、远程教育
智慧城市传感器、智慧医疗终端均可通过MQTT协议实时上报检测数据,远程教育等多媒体客户端可采用MQTT作为控制通道协议。
7、电力、石油与能源行业
电力、石油、能源等行业户外终端设备,可通过MQTT协议卫星链路推送数据到服务端网络,例如实现石油管道监测系统。
8、SCADA与工业4.0
采用MQTT协议与物联网架构,改造和实现新型的SCADA系统。工业4.0的工厂网络通过MQTT协议打造消息总线并实现云端互联。
继续阅读 »
EMQ - 百万级开源MQTT消息服务器

EMQ (Erlang/Enterprise/Elastic MQTT Broker)是基于Erlang/OTP平台开发的开源物联网MQTT消息服务器。Erlang/OTP是出色的软实时(Soft-Realtime)、低延时(Low-Latency)、分布式(Distributed)的语言平台。MQTT是轻量的(Lightweight)、发布订阅模式(PubSub)的物联网消息协议。

注解

2.0版本开始emqttd消息服务器自正式简称为EMQ。

EMQ 项目设计目标是承载移动终端或物联网终端海量的MQTT连接,并实现在海量物联网设备间快速低延时(Low-Latency)消息路由:

1. 稳定承载大规模的MQTT客户端连接,单服务器节点支持50万到100万连接。

2. 分布式节点集群,快速低延时的消息路由,单集群支持1000万规模的路由。

3. 消息服务器内扩展,支持定制多种认证方式、高效存储消息到后端数据库。

4. 完整物联网协议支持,MQTT、MQTT-SN、CoAP、WebSocket或私有协议支持。

EMQ 2.0完整支持MQTT V3.1/V3.1.1版本协议规范,并扩展支持WebSocket、Stomp、CoAP、MQTT-SN或私有TCP协议。EMQ 2.0消息服务器支持单节点100万连接与多节点分布式集群:

TODO: 2.0-rc.1图片更新.
emqtt.png

EMQ 2.0为大规模客户端连接(C1000K+)的移动推送、移动消息、物联网、车联网、智能硬件等应用,提供一个完全开放源码、安装部署简便、企业级稳定可靠、可弹性扩展、易于定制开发的MQTT消息服务器。

物联网传感器、智能硬件、移动终端、浏览器、应用服务器与数据服务器通过异步发布订阅模式MQTT消息连接

注解

MQTT-SN、CoAP协议支持已在2.0-rc.1版本发布。
MQTT发布订阅模式简述

MQTT是发布订阅(Publish/Subscribe)模式的消息协议,与HTTP协议请求响应(Request/Response)模式不同。

MQTT发布者与订阅者之间通过”主题”(Topic)进行消息路由,主题(Topic)格式类似Unix文件路径,例如:
sensor/1/temperature

chat/room/subject

presence/user/feng

sensor/1/#

sensor/+/temperature

uber/drivers/joe/inbox

MQTT主题(Topic)支持’+’, ‘#’的通配符,’+’通配一个层级,’#’通配多个层级(必须在末尾)。

MQTT消息发布者(Publisher)只能向特定’名称主题’(不支持通配符)发布消息,订阅者(Subscriber)通过订阅’过滤主题’(支持通配符)来匹配消息。

注解

初接触MQTT协议的用户,通常会向通配符的’过滤主题’发布广播消息,MQTT协议不支持这种模式,需从订阅侧设计广播主题(Topic)。 例如Android推送,向所有广州用户,推送某类本地消息,客户端获得GIS位置后,可订阅’news/city/guangzhou’主题。
EMQ设计

基于出色的软实时、低延时、高并发、分布式的Erlang/OTP语言平台开发设计

按主题树(Topic Trie)和路由表(Routing Table)发布订阅模式在集群节点间转发路由MQTT消息

architecture.png

五分钟下载启动EMQ

EMQ 2.0消息服务器每个版本,会发布Ubuntu、CentOS、FreeBSD、Mac OS X、Windows平台程序包与Docker镜像。下载地址: http://emqtt.com/downloads
 MQTT消息服务器的具体应用
1、移动即时消息
MQTT协议将在即时消息领域逐渐取代XMPP协议,移动消息例如Facebook Messenger采用MQTT协议,我们为部分客户基于EMQ项目定制了即时消息服务端
2、Android、HTML5消息推送
Android客户端通过MQTT协议实现低电量、低带宽消耗的消息推送,ZAKER新闻客户端基于EMQ项目实现单节点90万+连接新闻推送。
3、物联网M2M、物联网大数据
物联网终端通过MQTT协议实现发布订阅模式的M2M通信,物联网网关通过MQTT协议上报传感器数据到云平台进行大数据分析和存储。
4、车联网、电动车站桩管理
电动车联网电池监控,电动车、站、桩传感数据采集与分析。鲁能电力基于EMQ项目开发了电动车联网数据采集分析平台。
5、智能硬件、智能家居、智能电器
智能硬件与移动终端通过MQTT协议实现双向通信与智能控制。智能家居、智能电器通过MQTT协议实时双向连接云端服务器。
6、智慧城市、智慧医疗、远程教育
智慧城市传感器、智慧医疗终端均可通过MQTT协议实时上报检测数据,远程教育等多媒体客户端可采用MQTT作为控制通道协议。
7、电力、石油与能源行业
电力、石油、能源等行业户外终端设备,可通过MQTT协议卫星链路推送数据到服务端网络,例如实现石油管道监测系统。
8、SCADA与工业4.0
采用MQTT协议与物联网架构,改造和实现新型的SCADA系统。工业4.0的工厂网络通过MQTT协议打造消息总线并实现云端互联。 收起阅读 »

有没有人一起来做这个?用纯C写一个MQTT服务器

RT.
https://github.com/Markgorden/cmqttd
 
 
另外,我打算基于这个https://github.com/Markgorden/ ... ework库编写
 
因为
https://github.com/Markgorden/ ... ing.c
我认为这是目前效率最高的二进制协议Buffer处理方式。
come on, star 快来。 
 
继续阅读 »
RT.
https://github.com/Markgorden/cmqttd
 
 
另外,我打算基于这个https://github.com/Markgorden/ ... ework库编写
 
因为
https://github.com/Markgorden/ ... ing.c
我认为这是目前效率最高的二进制协议Buffer处理方式。
come on, star 快来。 
  收起阅读 »

招聘路由器软件工程师

工作地点:上海漕河泾开发区
工作内容:高通方案AP软件开发
目标人群:3-5年嵌入式软件开发经验,如有路由器软件开发经验最好。
联系人: 
工作地点:上海漕河泾开发区
工作内容:高通方案AP软件开发
目标人群:3-5年嵌入式软件开发经验,如有路由器软件开发经验最好。
联系人: 

ADLIST说明

Redis大婶的Adlist
相对Linux 内核链表,有点好处是,它多了几个API,可以用。
一个是 链表长度。
一个是 可以指定对比的回调函数。方便查找元素。

我加了一个方法,清空整个链表,但是不清空头指针,即与listRelease不同。
/* Free the elements that whole list, the list head is still in memory.
* This function can't fail. */
void listReleaseAllElements(list *list)
{
    unsigned long len;
    listNode *current, *next;
    current = list->head;
    len = list->len;
    while(len--) {
        next = current->next;
         if (list->free) list->free(current->value);
         free(current);
        current = next;
    }
   list->len = 0;
    //free(list);  // listRealse把这个也清空掉了,在需要把整个链表清空, 再加入数据时,就不适用了。
}

在头文件中添加
#ifdef __cplusplus
extern "C"{
#endif

….


#ifdef __cplusplus
}
#endif
以便在c++中使用。
 
 
 
 
继续阅读 »
Redis大婶的Adlist
相对Linux 内核链表,有点好处是,它多了几个API,可以用。
一个是 链表长度。
一个是 可以指定对比的回调函数。方便查找元素。

我加了一个方法,清空整个链表,但是不清空头指针,即与listRelease不同。
/* Free the elements that whole list, the list head is still in memory.
* This function can't fail. */
void listReleaseAllElements(list *list)
{
    unsigned long len;
    listNode *current, *next;
    current = list->head;
    len = list->len;
    while(len--) {
        next = current->next;
         if (list->free) list->free(current->value);
         free(current);
        current = next;
    }
   list->len = 0;
    //free(list);  // listRealse把这个也清空掉了,在需要把整个链表清空, 再加入数据时,就不适用了。
}

在头文件中添加
#ifdef __cplusplus
extern "C"{
#endif

….


#ifdef __cplusplus
}
#endif
以便在c++中使用。
 
 
 
  收起阅读 »

sds例子程序

Redis大婶用的一个动态字符串类。
主要解决三个问题
1、strlen时,O(1);
2、字符串修改操作时,无需频繁地malloc与free。
3、二进制安全。
 
实现这货,用了很多技巧。
直接上代码。

SDS说明.png

 
继续阅读 »
Redis大婶用的一个动态字符串类。
主要解决三个问题
1、strlen时,O(1);
2、字符串修改操作时,无需频繁地malloc与free。
3、二进制安全。
 
实现这货,用了很多技巧。
直接上代码。

SDS说明.png

  收起阅读 »

为什么现在流行单进程单线程模型?

问:我发现,现在 居然这样的潮流 盛行了吗?

现在流行的软件模型,有向单钱程,单进程靠的意思。


如?redis,node.js.

不知道为何?

问题详细描述:
事件驱动模型中多路IO 收到 可读可写事件后,需要 回调一个 处理函数,这个处理函数得花时间。
这时候,高并发,也只能等待了。事件来了,你得处理啊。
同一进程处理,意味着处理函数阻塞掉了多路复用IO的回调处理。
我说的线程,并不是说要开多个线程去做工作线程。而是reactor模型,把收到的IO事件,发送到处理线程去处理。

答:
其实开多个线程,也是一样的。只是把队列,搬到用户态来了。
其实放在 内核态是一样的。内核态会维护一个IO列表,取一个处理一个,和取出来后,放到用户态的队列去一个个被处理,其实是一样的,单进程模型,还省下了数据复制与线程切换过程。

因为,单个请求速度没变,量大了就好处来了
线程创建开销很大
线程占2m内存
÷2m,就是线程模型的最大限制
线程间的切换也也非常消耗cpu。

另外:单线程是不是就处理不了事件优先级的问题了
Redis中,是这样的,处理不了了。但是它把 事件分为两类,一类时间事件,一类文件事件。
时间事件,有明显的延迟。
它貌似设计上无所谓。
延迟就延迟吧。


不同的语言是不同的。例如erlang这些,它的线程不同于java的线程,它的开销很小。

并且,不能神化单进程与单线程模型的作用。
单进程单线程要利用多核,就得开多个实例。
 
像Redis,就要注意以下三点:
1、避免大Value,元素过多的Value出现。
2、单机多实例,充分利用cpu多核。
3、单实例数据不要过大1~10G 
继续阅读 »
问:我发现,现在 居然这样的潮流 盛行了吗?

现在流行的软件模型,有向单钱程,单进程靠的意思。


如?redis,node.js.

不知道为何?

问题详细描述:
事件驱动模型中多路IO 收到 可读可写事件后,需要 回调一个 处理函数,这个处理函数得花时间。
这时候,高并发,也只能等待了。事件来了,你得处理啊。
同一进程处理,意味着处理函数阻塞掉了多路复用IO的回调处理。
我说的线程,并不是说要开多个线程去做工作线程。而是reactor模型,把收到的IO事件,发送到处理线程去处理。

答:
其实开多个线程,也是一样的。只是把队列,搬到用户态来了。
其实放在 内核态是一样的。内核态会维护一个IO列表,取一个处理一个,和取出来后,放到用户态的队列去一个个被处理,其实是一样的,单进程模型,还省下了数据复制与线程切换过程。

因为,单个请求速度没变,量大了就好处来了
线程创建开销很大
线程占2m内存
÷2m,就是线程模型的最大限制
线程间的切换也也非常消耗cpu。

另外:单线程是不是就处理不了事件优先级的问题了
Redis中,是这样的,处理不了了。但是它把 事件分为两类,一类时间事件,一类文件事件。
时间事件,有明显的延迟。
它貌似设计上无所谓。
延迟就延迟吧。


不同的语言是不同的。例如erlang这些,它的线程不同于java的线程,它的开销很小。

并且,不能神化单进程与单线程模型的作用。
单进程单线程要利用多核,就得开多个实例。
 
像Redis,就要注意以下三点:
1、避免大Value,元素过多的Value出现。
2、单机多实例,充分利用cpu多核。
3、单实例数据不要过大1~10G  收起阅读 »

几个Hash Table对比

几个Hash Table对比
1、https://github.com/redis/hiredis
/* -------------------------- hash functions -------------------------------- */
/* Generic hash function (a popular one from Bernstein).
* I tested a few and this was the best. */
static unsigned int dictGenHashFunction(const unsigned char *buf, int len) {
unsigned int hash = 5381;
while (len--)
hash = ((hash << 5) + hash) + (*buf++); /* hash * 33 + c */
return hash;
}








 
2、https://github.com/Markgorden/ ... ash.h

3、https://github.com/Markgorden/c_hashmap/blob/master/hashmap.c 
/*
* Hashing function for a string
*/
unsigned int hashmap_hash_int(hashmap_map * m, char* keystring){
unsigned long key = crc32((unsigned char*)(keystring), strlen(keystring));
/* Robert Jenkins' 32 bit Mix Function */
key += (key << 12);
key ^= (key >> 22);
key += (key << 4);
key ^= (key >> 9);
key += (key << 10);
key ^= (key >> 2);
key += (key << 7);
key ^= (key >> 12);
/* Knuth's Multiplicative Method */
key = (key >> 3) * 2654435761;
return key % m->table_size;
}


4、std::hash<std::string>
在std::hash_set 和std::unordered_map中使用。
template<class _Kty>
struct _Bitwise_hash
{ // hash functor for plain old data
typedef _Kty argument_type;
typedef size_t result_type;
size_t operator()(const _Kty& _Keyval) const
{ // hash _Keyval to size_t value by pseudorandomizing transform
return (_Hash_seq((const unsigned char *)&_Keyval, sizeof (_Kty)));
}
};
-------------
// FUNCTION _Hash_seq
inline size_t _Hash_seq(const unsigned char *_First, size_t _Count)
{ // FNV-1a hash function for bytes in [_First, _First + _Count)
#if defined(_WIN64)
static_assert(sizeof(size_t) == 8, "This code is for 64-bit size_t.");
const size_t _FNV_offset_basis = 14695981039346656037ULL;
const size_t _FNV_prime = 1099511628211ULL;
#else /* defined(_WIN64) */
static_assert(sizeof(size_t) == 4, "This code is for 32-bit size_t.");
const size_t _FNV_offset_basis = 2166136261U;
const size_t _FNV_prime = 16777619U;
#endif /* defined(_WIN64) *
/
size_t _Val = _FNV_offset_basis;
for (size_t _Next = 0; _Next < _Count; ++_Next)
{ // fold in another byte
_Val ^= (size_t)_First[_Next];
_Val *= _FNV_prime;
}
return (_Val);
}








 性能测试结果:
hash_test1.jpg

测下了uthash和unorder_map的效率比较
不在一个数量级

 
 
hash_test2.png

 2千万个,uthash扑街


hash_test3.png

 unorder_map正常



 
 
 
 测试姿势如下:
  g++ -O2 test_hash.cpp -o test_hash -lrt -std=c++0x  

 不知测试的姿势是否不对
 
-================================================================---
 
今天补了一下Redis大婶用的那货Dict.h/Dict.c
每个数据项如下。
 
typedef struct dictEntry {
    void *key;
    union {
        void *val;
        uint64_t u64;
        int64_t s64;
        double d;
    } v;
    struct dictEntry *next;
} dictEntry;
 
通用性强,赞
插入500W条记录时,性能乐观。
如图
dict500w.png


1千万条简直太慢了
 
./aaa 
Hello, World!
To insert twenty million
table size:10000000
value is 0
To insert twenty million time-consuming
consumption times :828685 microsecond.
-------------------------------
Began to traverse the read
There are number of elements: 10000000 
 
远低于unordered_map,主要怀疑我的测试姿势不对。

 
直接上测试代码。
 
 gcc -o aaa LinuxProject2_ADLISTtest.c dict.c -lrt

 
 
 
 
 
 
 
 
 
 
 
 
 
继续阅读 »
几个Hash Table对比
1、https://github.com/redis/hiredis
/* -------------------------- hash functions -------------------------------- */
/* Generic hash function (a popular one from Bernstein).
* I tested a few and this was the best. */
static unsigned int dictGenHashFunction(const unsigned char *buf, int len) {
unsigned int hash = 5381;
while (len--)
hash = ((hash << 5) + hash) + (*buf++); /* hash * 33 + c */
return hash;
}








 
2、https://github.com/Markgorden/ ... ash.h

3、https://github.com/Markgorden/c_hashmap/blob/master/hashmap.c 
/*
* Hashing function for a string
*/
unsigned int hashmap_hash_int(hashmap_map * m, char* keystring){
unsigned long key = crc32((unsigned char*)(keystring), strlen(keystring));
/* Robert Jenkins' 32 bit Mix Function */
key += (key << 12);
key ^= (key >> 22);
key += (key << 4);
key ^= (key >> 9);
key += (key << 10);
key ^= (key >> 2);
key += (key << 7);
key ^= (key >> 12);
/* Knuth's Multiplicative Method */
key = (key >> 3) * 2654435761;
return key % m->table_size;
}


4、std::hash<std::string>
在std::hash_set 和std::unordered_map中使用。
template<class _Kty>
struct _Bitwise_hash
{ // hash functor for plain old data
typedef _Kty argument_type;
typedef size_t result_type;
size_t operator()(const _Kty& _Keyval) const
{ // hash _Keyval to size_t value by pseudorandomizing transform
return (_Hash_seq((const unsigned char *)&_Keyval, sizeof (_Kty)));
}
};
-------------
// FUNCTION _Hash_seq
inline size_t _Hash_seq(const unsigned char *_First, size_t _Count)
{ // FNV-1a hash function for bytes in [_First, _First + _Count)
#if defined(_WIN64)
static_assert(sizeof(size_t) == 8, "This code is for 64-bit size_t.");
const size_t _FNV_offset_basis = 14695981039346656037ULL;
const size_t _FNV_prime = 1099511628211ULL;
#else /* defined(_WIN64) */
static_assert(sizeof(size_t) == 4, "This code is for 32-bit size_t.");
const size_t _FNV_offset_basis = 2166136261U;
const size_t _FNV_prime = 16777619U;
#endif /* defined(_WIN64) *
/
size_t _Val = _FNV_offset_basis;
for (size_t _Next = 0; _Next < _Count; ++_Next)
{ // fold in another byte
_Val ^= (size_t)_First[_Next];
_Val *= _FNV_prime;
}
return (_Val);
}








 性能测试结果:
hash_test1.jpg

测下了uthash和unorder_map的效率比较
不在一个数量级

 
 
hash_test2.png

 2千万个,uthash扑街


hash_test3.png

 unorder_map正常



 
 
 
 测试姿势如下:
  g++ -O2 test_hash.cpp -o test_hash -lrt -std=c++0x  

 不知测试的姿势是否不对
 
-================================================================---
 
今天补了一下Redis大婶用的那货Dict.h/Dict.c
每个数据项如下。
 
typedef struct dictEntry {
    void *key;
    union {
        void *val;
        uint64_t u64;
        int64_t s64;
        double d;
    } v;
    struct dictEntry *next;
} dictEntry;
 
通用性强,赞
插入500W条记录时,性能乐观。
如图
dict500w.png


1千万条简直太慢了
 
./aaa 
Hello, World!
To insert twenty million
table size:10000000
value is 0
To insert twenty million time-consuming
consumption times :828685 microsecond.
-------------------------------
Began to traverse the read
There are number of elements: 10000000 
 
远低于unordered_map,主要怀疑我的测试姿势不对。

 
直接上测试代码。
 
 gcc -o aaa LinuxProject2_ADLISTtest.c dict.c -lrt

 
 
 
 
 
 
 
 
 
 
 
 
  收起阅读 »

Lua是源于对数据结构的精确理解


lua 设计者是真正理解了数据结构精髓的一个人。

 在C语言中,int a; 这句话意味着:
1、先向内存要4个字节。
2、给它起个名字,叫a,
3、将来里边存的数据,应该是 "int"型的。
这时候,语言(编译器)
给这四个字节,定义了一套运算算法规则。
+ - * / sizeof ^ & * > < >> 等一套规则。
所以,数据类型的含义就在这里——就是定义一个数据类型,同时也意味着定义了它相连的一套运算规则。

后来被高级语言扩展到 类——类里有属性和方法,方法就是运算规则。属性就是数据本身。

Lua,就学习了这两者——基本数据类型与用户数据类型——类。
并且发挥到了极致。

它只用一个table解决了所有的数据类型。
通过 元方法,实现运算。

__index
__meta
__xxxxx


-------------------------------------------------------------------------------

任何一种语言,都需要有schema 定义,即一定要有词法与语法分析,一颗树。









继续阅读 »

lua 设计者是真正理解了数据结构精髓的一个人。

 在C语言中,int a; 这句话意味着:
1、先向内存要4个字节。
2、给它起个名字,叫a,
3、将来里边存的数据,应该是 "int"型的。
这时候,语言(编译器)
给这四个字节,定义了一套运算算法规则。
+ - * / sizeof ^ & * > < >> 等一套规则。
所以,数据类型的含义就在这里——就是定义一个数据类型,同时也意味着定义了它相连的一套运算规则。

后来被高级语言扩展到 类——类里有属性和方法,方法就是运算规则。属性就是数据本身。

Lua,就学习了这两者——基本数据类型与用户数据类型——类。
并且发挥到了极致。

它只用一个table解决了所有的数据类型。
通过 元方法,实现运算。

__index
__meta
__xxxxx


-------------------------------------------------------------------------------

任何一种语言,都需要有schema 定义,即一定要有词法与语法分析,一颗树。









收起阅读 »

WRTNode 可以实现端口镜像功能吗?

类似于交换机和高级路由器那种功能,用于实时监控网络。
尝试使用过port-mirroring 失败, luci下也没有相关配置。
希望用过的提供思路哈!
类似于交换机和高级路由器那种功能,用于实时监控网络。
尝试使用过port-mirroring 失败, luci下也没有相关配置。
希望用过的提供思路哈!