BosCollege-SimpleDB-线性哈希索引

Author: Sixing Yan

在SimpleDB-3.00中,相对于原有的静态哈希索引技术,我们将实现一种动态哈希索引技术,线性哈希索引技术。相关算法的可以参考这篇文章

该哈希索引的核心思想是,当一个哈希桶被填满时,将该哈希桶分裂成 新&旧哈希桶,其中将有一般左右的数据从旧哈希桶移动到新哈希桶。查询时,通过对比哈希键(key)的值与分裂点游标,判断当前桶是否已经被分裂,如果被分裂,则用“升级的”哈希函数重新计算键值,找到目标数据所在的哈希桶。

在具体实现中,相比于静态索引仅需一个(种)索引文件,线性哈希索引需要两个(种)索引文件。两个索引文件分别是:存储线性哈希函数参数的索引文件,存储具体数据映射地址的哈希桶。


linear structure.jpg

根据这篇文章示意的函数算法, 我们可以在SimpleDB-3.00中实现线性哈希索引技术,该类的工作流程如下。

linear hash.jpg

首先,初始实例化一个LinearHashIndex类,除了(保留地)为当前索引名(idxname),涉及的表的Schema信息(sch)以及当前的事务(tx),还需要初始化线性哈希方程initLinearHash。
初始化线性哈希方程时,

  • 检查方程文件是否存在(tx.size("lnrhshcat") == 0),如果不存在则新建。
    使用tableMgr来新建一个table结构的文件,每一条记录即是一个索引的哈希函数的参数
  • 接着检查该索引的哈希方程是否存在(flag != true),如果不存在则新建(createFunction())。
    通过遍历方程文件来查找是否有符合条件的函数,如果没有 则向方程文件插入一条记录。同时新建默认个数的哈希桶文件,该桶文件使用table结构。
public class LinearHashIndex {
    public static int DFLT_COUNT = 25;
    public static int DFLT_SIZE = 100;
    public static int DFLT_ROUND = 1;
    public static int DFLT_SPLIT = 0;

    private String idxname;
    private Schema sch;
    private Transaction tx;
    private Constant searchkey = null;
    private TableScan ts = null;

    private int round; // 第几回合
    private int split; // 分裂点坐标
    private int size; // function的最大bucket数量
    private int count; // 目前有多少个bucket
    private RID funcRid;
    private TableInfo funcTi;

    /**
     * Opens a hash index for the specified index.
     * @param idxname the name of the index
     * @param sch the schema of the index records
     * @param tx the calling transaction
     */
    public LinearHashIndex(String idxname, Schema sch, Transaction tx) {
        this.idxname = idxname;
        this.sch = sch;
        this.tx = tx;
        initLinearHash();}

    public void initLinearHash() {
        String functbl = this.idxname + "func";
        Schema funcsch = new Schema();
        funcsch.addStringField("funcname", MAX_NAME);
        funcsch.addIntField("round");
        funcsch.addIntField("size");
        funcsch.addIntField("count");
        funcsch.addIntField("split");

        if (tx.size("lnrhshcat") == 0) // if the function file no exists
            // create linear-hash file
            SimpleDB.mdmgr().tblmgr.createTable("lnrhshcat", funcsch, this.tx);// tablemgr
        // open linear-hash file
        this.funcTi = new TableInfo(functbl, funcsch);
        // get the related record
        RecordFile fcatfile = new RecordFile(this.funcTi, tx);
        Boolean flag = false;
        while (fcatfile.next())
            if (fcatfile.getString("funcname").equals(tblname)) {
                flag = true;
                this.size = fcatfile.getInt("size");
                this.count = fcatfile.getInt("count");
                this.split = fcatfile.getInt("split");
                this.round = fcatfile.getInt("round");
                break;
            }
        if (flag != true) // if there no exist the related record
            createFunction(funcTi);}

    public void createFunction(TableInfo funcTi) {
        // a record of parameter into tblcat
        RecordFile fcatfile = new RecordFile(funcTi, tx);
        fcatfile.insert();
        fcatfile.setInt("funcname", funcTi.fileName());
        fcatfile.setInt("round", DFLT_ROUND);
        fcatfile.setInt("size", DFLT_SIZE);
        fcatfile.setInt("count", DFLT_COUNT);
        fcatfile.setInt("split", DFLT_SPLIT);
        fcatfile.close();
        // record the information of current function
        this.funcRid = fcatfile.currentRid();
        this.count = DFLT_COUNT;
        this.size = DFLT_SIZE;
        this.round = DFLT_ROUND;
        this.split = DFLT_SPLIT;
        //initial default buckets
        for (int bkt = 0; bkt < this.count; i++)
            SimpleDB.mdmgr().tblmgr.createTable(this.idxname + bkt, this.sch, this.tx) // tablemgr}
    ...
}
public class LinearHashIndex {
    public static int DFLT_COUNT = 25;
    public static int DFLT_SIZE = 100;
    public static int DFLT_ROUND = 1;
    public static int DFLT_SPLIT = 0;

    private String idxname;
    private Schema sch;
    private Transaction tx;
    private Constant searchkey = null;
    private TableScan ts = null;

    private int round; // 第几回合
    private int split; // 分裂点坐标
    private int size; // function的最大bucket数量
    private int count; // 目前有多少个bucket
    private RID funcRid;
    private TableInfo funcTi;

    ...
    public void beforeFirst(Constant searchkey) {
        close(); // end up the scan on the last file
        this.searchkey = searchkey;
        int bucket = linearHash();
        String tblname = idxname + bucket;
        TableInfo ti = new TableInfo(tblname, sch); // this will open a bucket
        this.ts = new TableScan(ti, tx);
    }
    
    private int linearHash() {
        int key = this.searchkey.hashCode();
        int bktnum = hash(key, this.round);
        if (bktnum < this.split)
            bktnum = hash(key, this.round + 1);
        return bktnum;}

    private int hash(int key, int round) {return key % (this.count * round);}
      ...
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,012评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,628评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,653评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,485评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,574评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,590评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,596评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,340评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,794评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,102评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,276评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,940评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,583评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,201评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,441评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,173评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,136评论 2 352

推荐阅读更多精彩内容