假设一个网站,最初开始压力不大,只有几千条或者几万条数据存储,约几百个查询访问
那么一般就是一台设备应对 数据输入和查询 (后继更新代码)
整个思路就是写了一个 智能指针版的链表(注意指针间相互引用造成无法自动释放,出现内存泄漏)
然后将测试数据hash 分别放进制定数量的链表中 hash函数使用的是redis2.4版
目前来看8千数据hash分别存储5个链表 7个链表 还算比较均匀
测试数据如下:
5个链表存储效果
bucket[0] has 1687 nodes
bucket[1] has 1681 nodes
bucket[2] has 1658 nodes
bucket[3] has 1662 nodes
bucket[4] has 1713 nodes
7个链表存储效果
bucket[0] has 1153 nodes
bucket[1] has 1222 nodes
bucket[2] has 1195 nodes
bucket[3] has 1185 nodes
bucket[4] has 1142 nodes
bucket[5] has 1242 nodes
bucket[6] has 1262 nodes
//==================================
目前完成状态
将数据加载内存hash数组中, 可以进行查询
代码:
// Test.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include "MyLink.h"
#define BucketNums 37
MyLink bucket[BucketNums];
std::string testStrings[]{
"海贼王",
"幽游白书(全19册)",
"微处理器设计",
"提高C++性能的编程技术",
"一只非常寂寞的鸡",
"实现领域驱动设计",
"RabbitMQ in Action",
"悬崖上的金鱼姬",
"瑞克和莫蒂 第一季",
"猫和老鼠:魔法戒指",
"快乐东西",
"C3-魔幻三次方",
""
};
bool InitServer() {
bool ret = false;
std::ifstream infstream("OutData.dat");
if ( !infstream || infstream.bad() ) {
std::cerr << "infstream open file error " << std::endl;
return ret;
}
std::string key, value, tmp;
while (std::getline(infstream, key) &&
std::getline(infstream, value) &&
std::getline(infstream, tmp)) {
unsigned int hashNum = dictGenHashFunction(key.c_str(), key.size());
bucket[hashNum % BucketNums].AppendNode(key, value);
}
ret = true;
return ret;
}
bool QueryName(std::string queryStr,std::string& value) {
bool ret = false;
unsigned int hashNum = dictGenHashFunction(queryStr.c_str(), queryStr.size());
std::shared_ptr<LinkNode> p = bucket[hashNum % BucketNums].QueryNode(queryStr);
if (p != nullptr) {
value = p->value_;
}
ret = true;
return ret;
}
int main()
{
if (!InitServer())
return -1;
for (int i = 0; testStrings[i] != ""; i++) {
std::string queryStr = testStrings[i];
std::string value;
if (QueryName(queryStr, value)) {
std::cout << queryStr << "_intfo :" << value << std::endl;
}
}
return 0;
}
#pragma once
#include <memory>
#include <string>
#include <iostream>
// redis hash function
unsigned int dictGenHashFunction(const char *buf, int len) {
unsigned int hash = 5381;
while (len--)
hash = ((hash << 5) + hash) + (*buf++);
return hash;
}
struct LinkNode {
std::string key_;
std::string value_;
std::shared_ptr<LinkNode> next_;
std::shared_ptr<LinkNode> prev_;
};
class MyLink {
private:
public:
MyLink() :head_(nullptr), tail_(nullptr), nodeCount_(0){}
MyLink(std::string key,std::string value){
head_ = tail_ = InitNode(key,value);
nodeCount_ = 1;
}
~MyLink() {
if (head_ == nullptr) {
return;
}
while (head_ != nullptr) {
std::shared_ptr<LinkNode> p = head_;
if (p->next_ == nullptr) {
head_ = tail_ = nullptr;
nodeCount_--;
break;
}
head_ = p->next_;
p->next_ = nullptr;
head_->prev_ = nullptr;
nodeCount_--;
}
}
size_t GetNodeCount() {return nodeCount_;}
void PrintNode() {
std::shared_ptr<LinkNode> p = head_;
for (; p != nullptr; p = p->next_) {
std::cout << p->key_ << " " << p->value_ << std::endl;
}
std::cout << std::endl;
}
std::shared_ptr<LinkNode> QueryNode(const std::string key) {
std::shared_ptr<LinkNode> p = nullptr;
if (nullptr == tail_ || nullptr == head_) {
return p;
}
for (std::shared_ptr<LinkNode> p = head_; p != nullptr; p = p->next_) {
if (p->key_ == key )
return p;
}
return nullptr;
}
std::shared_ptr<LinkNode> FindNode(const std::string key,const std::string value) {
std::shared_ptr<LinkNode> p = nullptr;
if (nullptr == tail_ || nullptr == head_) {
return p;
}
for (std::shared_ptr<LinkNode> p = head_; p != nullptr; p = p->next_) {
if (p->key_ == key && p->value_ == value )
return p;
}
return nullptr;
}
std::shared_ptr<LinkNode> FindNode(std::shared_ptr<LinkNode> node) {
std::shared_ptr<LinkNode> p = nullptr;
if (node == nullptr)
return p;
if (nullptr == tail_ || nullptr == head_) {
return p;
}
for (std::shared_ptr<LinkNode> p = head_; p != nullptr; p = p->next_) {
if (p->key_ == node->key_ && p->value_ == node->value_)
return p;
}
return nullptr;
}
bool DeleteNode(const std::string key, const std::string value) {
std::shared_ptr<LinkNode>p = FindNode(key, value);
if ( p == nullptr ) {
return false;
}
if (p->prev_ == nullptr && p->next_ == nullptr) {
head_ = tail_ = nullptr;
}else if (p->prev_ == nullptr) {
head_ = p->next_;
p->next_ = nullptr;
head_->prev_ = nullptr;
}
else if (p->next_ == nullptr) {
tail_ = p->prev_;
tail_->next_ = nullptr;
p->prev_ = nullptr;
}else {
p->prev_->next_ = p->next_;
p->next_->prev_ = p->prev_;
p->prev_ = p->next_ = nullptr;
}
nodeCount_--;
return true;
}
bool DeleteNode(std::shared_ptr<LinkNode>& node) {
std::shared_ptr<LinkNode>p = FindNode(node);
if (p == nullptr) {
return false;
}
if (p->prev_ == nullptr && p->next_ == nullptr) {
head_ = tail_ = nullptr;
}
else if (p->prev_ == nullptr) {
head_ = p->next_;
p->next_ = nullptr;
head_->prev_ = nullptr;
}
else if (p->next_ == nullptr) {
tail_ = p->prev_;
tail_->next_ = nullptr;
p->prev_ = nullptr;
}
else {
p->prev_->next_ = p->next_;
p->next_->prev_ = p->prev_;
p->prev_ = p->next_ = nullptr;
}
nodeCount_--;
return true;
}
bool AppendNode(std::string key, std::string value) {
return AppendNode(InitNode(key,value));
}
bool AppendNode(std::shared_ptr<LinkNode> node) {
bool ret = false;
if (nullptr == head_ && nullptr == tail_) {
head_ = tail_ = node;
nodeCount_++;
ret = true;
return ret;
}
else if (nullptr == tail_ || nullptr == head_) {
return ret;
}
tail_->next_ = node;
node->prev_ = tail_;
tail_ = node;
node->next_ = nullptr;
nodeCount_++;
ret = true;
return ret;
}
static std::shared_ptr<LinkNode> InitNode(const std::string& key, const std::string& value) {
std::shared_ptr<LinkNode> p(new LinkNode);
p->key_ = key;
p->value_ = value;
p->next_ = nullptr;
p->prev_ = nullptr;
return p;
}
private:
MyLink(const MyLink&);
const MyLink& operator=(const MyLink&);
size_t nodeCount_;
std::shared_ptr<LinkNode> head_;
std::shared_ptr<LinkNode> tail_;
};
代码见 https://pan.baidu.com/s/1bpwzcE7
技术博客 http://blog.csdn.net/stecdeng
技术交流群 群号码:324164944 欢迎c c++ windows驱动爱好者 服务器程序员沟通交流