栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 大数据 > 大数据系统

zookeeper源码解析(三)

zookeeper源码解析(三)

2021SC@SDUSC

前言

NodeHashMap是DataTree类所维护的最核心的成员变量的变量类型。NodeHashMap是接口,且在zookeeper中提供了它唯一一个实现类NodeHashMapImpl。本文主要介绍该接口和该实现类。

NodeHashMap
    //把数据节点加入map,并更新digest
    DataNode put(String path, DataNode node);

    //把数据节点加入map,不更新digest
    DataNode putWithoutDigest(String path, DataNode node);

    //根据路径返回对应的数据节点
    DataNode get(String path);

    //根据路径移除数据节点,并返回该数据节点
    DataNode remove(String path);

    //返回map对应的键值对集合
    Set> entrySet();

    //对map清空
    void clear();

    //返回map的节点数
    int size();

    //两个参数是路径和对应的数据节点,该函数在节点被修改前被调用
    //用于清空节点的digest
    void preChange(String path, DataNode node);

    //两个参数是路径和对应的数据节点,该函数在节点被修改后被调用
    //用于更新digest
    void postChange(String path, DataNode node);

    //返回digest值
    long getDigest();

PS:这里的digest不同于上一篇文章所讲的节点的digest,这里是指整棵树的digest(可以简单理解为节点的digest加起来)

NodeHashMapImpl

成员变量:

    //并发哈希表,路径到数据节点的映射
    private final ConcurrentHashMap nodes;
    //布尔值,决定是否要用digest
    private final boolean digestEnabled;
    //用于计算digest
    private final DigestCalculator digestCalculator;
    //维护整棵树的hash
    private final AdHash hash;

构造函数:

    public NodeHashMapImpl(DigestCalculator digestCalculator) {
        this.digestCalculator = digestCalculator;
        nodes = new ConcurrentHashMap<>();
        hash = new AdHash();
        digestEnabled = ZooKeeperServer.isDigestEnabled();
    }

该类实现NodeHashMap接口,除了实现接口的函数,另外增加了两个函数:
 

    //增加指定路径指定数据节点的digest(前提是节点不是/zookeeper/路径下的)
    private void addDigest(String path, DataNode node) {
        if (path.startsWith(ZooDefs.ZOOKEEPER_NODE_SUBTREE)) {
            return;
        }
        if (digestEnabled) {
            hash.addDigest(digestCalculator.calculateDigest(path, node));
        }
    }
    //减去指定路径指定数据节点的digest(前提是节点不是/zookeeper/路径下的)
    private void removeDigest(String path, DataNode node) {
        if (path.startsWith(ZooDefs.ZOOKEEPER_NODE_SUBTREE)) {
            return;
        }
        if (digestEnabled) {
            hash.removeDigest(digestCalculator.calculateDigest(path, node));
        }
    }

该类实现了NodeHashMap接口的一系列方法:

    //为了维护digest,如果路径原本有对应节点,要减去对应的节点digest,更新hash
    public DataNode put(String path, DataNode node) {
        DataNode oldNode = nodes.put(path, node);
        addDigest(path, node);
        if (oldNode != null) {
            removeDigest(path, oldNode);
        }
        return oldNode;
    }
    //同样地,这里也要考虑对应路径是否真的有节点,有的话就减去它的digest,更新hash
    public DataNode remove(String path) {
        DataNode oldNode = nodes.remove(path);
        if (oldNode != null) {
            removeDigest(path, oldNode);
        }
        return oldNode;
    }
    //清空了节点,也要清空整棵树的hash
     public void clear() {
        nodes.clear();
        hash.clear();
    }
    //节点修改前,要做的是去掉旧节点的digest
    public void preChange(String path, DataNode node) {
        removeDigest(path, node);
    }

    //节点修改后,要将node中记录digest是否算好了的属性digestCached置为false
    //还记得我们上一篇文章所介绍的DigestCaculator中计算digest的函数吗?
    //在那个函数中我们要根据digestCached的值来判断是否需要计算一遍digest
    public void postChange(String path, DataNode node) {
        node.digestCached = false;
        addDigest(path, node);
    }
    //获取整棵树的hash值
    public long getDigest() {
        return hash.getHash();
    }

下面几个函数只是纯粹在并发哈希表的函数方法外再封装一层,作用就类似get/set方法那样

    public DataNode putWithoutDigest(String path, DataNode node) {
        return nodes.put(path, node);
    }

    public DataNode get(String path) {
        return nodes.get(path);
    }

    public Set> entrySet() {
        return nodes.entrySet();
    }
     public int size() {
        return nodes.size();
    }
AdHash

AdHash是NodeHashMapImpl类中成员变量hash的变量类型

该类维护一个成员变量(用volatile修饰,支持一定程度并发)

    private volatile long hash;

提供addDiget,removeDigest,getHash,clear等函数

实现上也都极为简单,就是给hash加上digest,减去digest,返回hash,把hash置为0

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/336316.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号