redis:set数据类型与操作

    set是集合。我们可以向一个集合中“插入”,“删除”元素,也可以计算两个集合的“交集”,“并集”,及“作差”。如:

假设有集合A,B。

其中,A={1,2,3,4,5},B={4,5,6,7,8}。

那么,

交集:inter(A,B)= {4,5}

并集:union(A, B)= {1,2,3,4,5,6,7,8}

差集:diff(A,B)= {1,2,3},即属于集合A,但不属于集合B的元素


    set的是通过hash table实现的,所以添加、删除和查找的复杂度都是O(1)。hash table会随着添加或者删除自动的调整大小。需要注意的是调整hash table大小时候需要同步(获取写锁)会阻塞其他读写操作,可能不久后就会改用跳表(skip list)来实现,跳表已经在sorted set中使用了。(引自:http://hb.qq.com/a/20111001/000022.htm)


    关于set数据类型的操作详见:http://redis.readthedocs.org/en/2.4/set.html

    下面结合redis c++接口,了解一下这些基本操作。

#include "redisclient.h"

#include "tests/functions.h"

#include <iostream>

#include <boost/date_time.hpp>

#define OUT(x) std::cout<<#x<<" = "<<x<<std::endl;

boost::shared_ptr<redis::client> init_non_cluster_client();

void output_set(redis::client::string_set & sset);

void test_set(redis::client & c);

int main(int argv, char* argc[]) 
{
	boost::shared_ptr<redis::client> shared_c;

	shared_c = init_non_cluster_client();

	redis::client& c = *shared_c;

	test_set(c);

	return 0;
}

void test_set(redis::client & c)
{
	test("test redis set type.");

	test("sadd");
	{
		std::vector<std::string> vals;
		for(size_t i=0; i<10; ++i) {
			char ch = (char)('A'+i);
			std::string tmp ="";
			tmp += ch;
			vals.push_back(tmp);
		}
		std::vector<std::string>::iterator it;
		c.sadd("set_a", vals.begin(), vals.end());
	}

	test("smembers");
	{
		redis::client::string_set out;
		OUT(c.smembers("set_a", out));
		output_set( out );
	}

	test("srem");
	{
		c.srem("set_a", "A");
		redis::client::string_set out;
		OUT(c.smembers("set_a", out));
		output_set( out );
	}

	test("sismember");
	{
		OUT( c.sismember("set_a", "A") );
		OUT( c.sismember("set_a", "B") );
	}

	test("scard");
	{
		OUT( c.scard("set_a") );
	}

	test("smove");
	{
		c.smove("set_a", "set_b", "B");
		redis::client::string_set out;
		OUT(c.smembers("set_a", out));
		output_set(out);

		out.clear();
		OUT(c.smembers("set_b", out));
		output_set( out );
	}

	test("spop");
	{
		OUT( c.scard("set_a") );
		OUT( c.spop("set_a") );
		OUT( c.scard("set_a") );
	}

	test("srandmember");
	{
		OUT( c.srandmember("set_a") );
	}

	test("sinter");
	{
		c.sadd("set_b", "C");
		c.sadd("set_b", "F");
		redis::client::string_vector keys;
		keys.push_back("set_a");
		keys.push_back("set_b");
		redis::client::string_set out;
		c.smembers("set_a", out);
		std::cout<<"set a:  *******************"<<std::endl;
		output_set(out);
		out.clear();
		c.smembers("set_b", out);
		std::cout<<"set b:  *******************"<<std::endl;
		output_set(out);
		c.sinter(keys, out);
		output_set(out);
	}

	test("sinterstore");
	{
		redis::client::string_vector keys;
		redis::client::string_set out;
		keys.push_back("set_a");
		keys.push_back("set_b");
		c.sinterstore("set_c", keys);
		c.smembers("set_c", out);
		output_set(out);
	}

	test("sunion & sunionstore");
	{
		redis::client::string_vector keys;
		redis::client::string_set out;
		keys.push_back("set_a");
		keys.push_back("set_b");
		c.sunion(keys, out);
		output_set(out);
		out.clear();
		c.sunionstore("set_d", keys);
		c.smembers("set_d", out);
		std::cout<<"set d: ****************"<<std::endl;
		output_set(out);
	}

	test("sdiff * sdiffstore");
	{
		redis::client::string_vector keys;
		redis::client::string_set out;
		keys.push_back("set_a");
		keys.push_back("set_b");
		c.sdiff(keys, out);
		output_set(out);
		out.clear();
		c.sdiffstore("set_e", keys);
		c.smembers("set_e", out);
		std::cout<<"set e: ****************"<<std::endl;
		output_set(out);	
	}
}

void output_set(redis::client::string_set & sset)
{
	size_t size = sset.size();
	OUT(size);
	redis::client::string_set::iterator it;
	for(it=sset.begin(); it!=sset.end(); ++it) {
		OUT(*it);
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值