欢迎来到gulucn的博客


  • 首页

  • 分类

  • 归档

  • 标签

[转]LevelDb日知录(Leveldb 实现原理)

发表于 2014年03月4日   |   分类于 nosql   |  

转自:http://www.cnblogs.com/haippy/archive/2011/12/04/2276064.html

郑重声明:本篇博客是自己学习 Leveldb 实现原理时参考了郎格科技系列博客整理的,原文地址: http://www.samecity.com/blog/Index.asp?SortID=12,只是为了加深印象,本文的配图是自己重新绘制的,大部分内容与原文相似,大家可以浏览原始页面:-),感兴趣的话可以一起讨论 Leveldb 的实现原理!

LevelDb日知录之一

  说起LevelDb也许您不清楚,但是如果作为IT工程师,不知道下面两位大神级别的工程师,那您的领导估计会Hold不住了:Jeff
Dean和Sanjay Ghemawat。这两位是Google公司重量级的工程师,为数甚少的Google
Fellow之二。

  Jeff Dean其人:http://research.google.com/people/jeff/index.html,Google大规模分布式平台Bigtable和MapReduce主要设计和实现者。

  Sanjay Ghemawat其人:http://research.google.com/people/sanjay/index.html,Google大规模分布式平台GFS,Bigtable和MapReduce主要设计和实现工程师。

  LevelDb就是这两位大神级别的工程师发起的开源项目,简而言之,LevelDb是能够处理十亿级别规模Key-Value型数据持久性存储的C++ 程序库。正像上面介绍的,这二位是Bigtable的设计和实现者,如果了解Bigtable的话,应该知道在这个影响深远的分布式存储系统中有两个核心的部分:Master
Server和Tablet Server。其中Master Server做一些管理数据的存储以及分布式调度工作,实际的分布式数据存储以及读写操作是由Tablet
Server完成的,而LevelDb则可以理解为一个简化版的Tablet Server。

  LevelDb有如下一些特点:

    首先,LevelDb是一个持久化存储的KV系统,和Redis这种内存型的KV系统不同,LevelDb不会像Redis一样狂吃内存,而是将大部分数据存储到磁盘上。

    其次,LevleDb在存储数据时,是根据记录的key值有序存储的,就是说相邻的key值在存储文件中是依次顺序存储的,而应用可以自定义key大小比较函数,LevleDb会按照用户定义的比较函数依序存储这些记录。

    再次,像大多数KV系统一样,LevelDb的操作接口很简单,基本操作包括写记录,读记录以及删除记录。也支持针对多条操作的原子批量操作。

    另外,LevelDb支持数据快照(snapshot)功能,使得读取操作不受写操作影响,可以在读操作过程中始终看到一致的数据。

  除此外,LevelDb还支持数据压缩等操作,这对于减小存储空间以及增快IO效率都有直接的帮助。

  LevelDb性能非常突出,官方网站报道其随机写性能达到40万条记录每秒,而随机读性能达到6万条记录每秒。总体来说,LevelDb的写操作要大大快于读操作,而顺序读写操作则大大快于随机读写操作。至于为何是这样,看了我们后续推出的LevelDb日知录,估计您会了解其内在原因。

阅读全文 »

[转]iostream、printf/wprintf和中文输出

发表于 2008年10月21日   |  

iostream、printf/wprintf和中文输出

  使用C++标准库的iostream,可以方便地将控制台、文件、字符串以及其它可扩充的外部表示作为流来处理,但要处理中文,却会碰到很多问题。本人原来没怎么用过这个iostream,这几天尝试用这个写点东西,一会儿不能输出中文,一会儿不支持中文文件名的,搞得头大。网上搜了搜,没有发现适用于所有情况的解决方案。不过后来自己经过多次测试,基本解决了这些问题,现在写成文字作为一个总结,也供碰到同样问题的朋友参考。关于C语言中的printf和wprintf的中文输出,本文也进行了探讨。

  需要说明的是,我的开发环境是VS 2005(标准库当然也是微软实现的),不保证其它环境下是相同的效果。

1、cout和wcout

  在缺省的C locale下,cout可以直接输出中文,但对于wcout却不行(至少VS 2005下不行)。对于wcout,需要将其locale设为本地语言才能输出中文:

  wcout.imbue(locale(locale(),””,LC_CTYPE));  // ①

  也有人用如下语句的,但这会改变wcout的所有locale设置,比如数字“1234”会输出为“1,234”。

  wcout.imbue(locale(“”));

阅读全文 »

[原]stl 输出unicode到文件中

发表于 2008年10月21日   |  

在VS2008中,如果项目设置了unicode字符集,把中文输出到文件中经常会遇到错误。

在MFC项目中,可以使用以下语句来实现unicode到多字节字符的转换:

USES_CONVERSION;
CString strLog = _T("我爱大家");
const char*   cpLog   =   (const char*)W2A(strLog);
CFile myFile;
myFile.Open(_T("test.txt"),CFile::modeCreate|CFile::modeWrite);
myFile.Write(cpLog,strlen(cpLog));
myFile.Close();

其实stl也提供了unicode字符的处理,这里的unicode只是两个字节的字符(即unsigned short)。unicode对应的字符串处理比ansi麻烦,相关的类基本前面都带有’w’。如std::wstring,std::wofstream。

阅读全文 »

[转]C++箴言:理解typename的两个含义

发表于 2008年08月6日   |  

问题:在下面的 template declarations(模板声明)中 class 和 typename 有什么不同?

template<class T> class Widget; // uses "class" 
template<typename T> class Widget; // uses "typename" 

答案:没什么不同。在声明一个 template type parameter(模板类型参数)的时候,class 和 typename 意味着完全相同的东西。一些程序员更喜欢在所有的时间都用 class,因为它更容易输入。其他人(包括我本人)更喜欢 typename,因为它暗示着这个参数不必要是一个 class type(类类型)。少数开发者在任何类型都被允许的时候使用 typename,而把 class 保留给仅接受 user-defined types(用户定义类型)的场合。但是从 C++ 的观点看,class 和 typename 在声明一个 template parameter(模板参数)时意味着完全相同的东西。

然而,C++ 并不总是把 class 和 typename 视为等同的东西。有时你必须使用 typename。为了理解这一点,我们不得不讨论你会在一个template(模板)中涉及到的两种名字。

假设我们有一个函数的模板,它能取得一个 STL-compatible container(STL 兼容容器)中持有的能赋值给 ints 的对象。进一步假设这个函数只是简单地打印它的第二个元素的值。它是一个用糊涂的方法实现的糊涂的函数,而且就像我下面写的,它甚至不能编译,但是请将这些事先放在一边——有一种方法能发现我的愚蠢:

template<typename C> // print 2nd element in 
void print2nd(const C& container) // container; 
{ 
  // this is not valid C++! 
  if (container.size() >= 2) {
   C::const_iterator iter(container.begin()); // get iterator to 1st element 
   ++iter; // move iter to 2nd element 
   int value = *iter; // copy that element to an int 
   std::cout << value; // print the int 
  }
}
阅读全文 »

[原]C++ 类成员引用变量的使用

发表于 2008年08月5日   |   分类于 C++   |  

出来工作后,才发现原来C++的类成员变量可以是引用变量。下面通过一个例子来说明(虽然没多大意义)

#include <iostream>
using namespace std;
class A
{
public:
    A(int i=3):m_i(i){}
    void print()
    {
        cout<<"m_i="<<m_i<<endl;
    }
private:
    int m_i;
};
class B
{
public:
    B(){}
    B(A& a):m_a(a){}
    void display()
    {
        m_a.print();
    }
private:
    A& m_a;
};
int main(int argc,char** argv)
{
    A a(5);
    B b(a);
    b.display();
    return 0;
}

其中,要注意的地方就是引用类型的成员变量的初始化问题,它不能直接在构造函数里初始化,必须用到初始化列表,且形参也必须是引用类型。
凡是有引用类型的成员变量的类,不能有缺省构造函数。原因是引用类型的成员变量必须在类构造时进行初始化。
如果两个类要对第三个类的数据进行共享处理,可以考虑把第三个类作为这两个类的引用类型的成员变量。

1…1011

55 日志
19 分类
27 标签
RSS
Links
  • 结构之法&算法之道
  • 数盟-数据科学家联盟
  • 36大数据
© 2018
由 Hexo 强力驱动
主题 - NexT.Mist