hsf笔记-AttributeMap

1.AttributeMap

AttributeMap有2个实现

  1. DefaultAttributeMap 使用数组实现
  2. ConcurrentAttributeMap 使用ConcurrentHashMap实现
image.png

其中key为AttributeKey

public interface AttributeMap {
    Object put(AttributeKey key, Object value);

    Object get(AttributeKey key);

    Object putIfAbsent(AttributeKey key, Object value);

    Object remove(AttributeKey key);
}

2.AttributeKey

AttributeKey中比较关键是AttributeNamespace,其中id是由namespace的IdGen递增添加的

public class AttributeKey {
    private final AttributeNamespace namespace;
    private final String name;
    private final int id;

    protected AttributeKey(AttributeNamespace namespace, String name) {
        this.namespace = namespace;
        this.name = name;
        this.id = namespace.getIdGen().getAndIncrement();
    }

    public int getId() {
        return this.id;
    }

    public String getName() {
        return this.name;
    }

    public AttributeNamespace getNamespace() {
        return this.namespace;
    }
}

3. AttributeNamespace

AttributeNamespace由2个Map来维护索引,name和id,每当创建一个新的AttributeKey时,id就会递增1

public class AttributeNamespace {
    private static final ConcurrentHashMap<String, AttributeNamespace> name2Instance = new ConcurrentHashMap();
    private final String namespace;
    private final AtomicInteger idGen = new AtomicInteger();
    private final ConcurrentHashMap<String, AttributeKey> name2AttributeKey = new ConcurrentHashMap();
    private final ConcurrentHashMap<Integer, AttributeKey> id2AttributeKey = new ConcurrentHashMap();

    public static AttributeNamespace getOrCreateNamespace(String namespace) {
        AttributeNamespace instance = (AttributeNamespace)name2Instance.get(namespace);
        if (instance == null) {
            instance = new AttributeNamespace(namespace);
            AttributeNamespace old = (AttributeNamespace)name2Instance.putIfAbsent(namespace, instance);
            if (old != null) {
                instance = old;
            }
        }

        return instance;
    }

    public static AttributeNamespace createNamespace(String namespace) {
        AttributeNamespace key = new AttributeNamespace(namespace);
        AttributeNamespace old = (AttributeNamespace)name2Instance.putIfAbsent(namespace, key);
        if (old != null) {
            throw new IllegalArgumentException(String.format("namespace '%s' is already in use", namespace));
        } else {
            return key;
        }
    }

    private AttributeNamespace(String namespace) {
        this.namespace = namespace;
    }

    public String getNamespace() {
        return this.namespace;
    }

    public AtomicInteger getIdGen() {
        return this.idGen;
    }

    public AttributeKey getOrCreate(String name) {
        AttributeKey key = (AttributeKey)this.name2AttributeKey.get(name);
        if (key == null) {
            key = new AttributeKey(this, name);
            AttributeKey old = (AttributeKey)this.name2AttributeKey.putIfAbsent(name, key);
            if (old == null) {
                this.cacheForId(key);
            } else {
                key = old;
            }
        }

        return key;
    }

    public AttributeKey create(String name) {
        AttributeKey key = new AttributeKey(this, name);
        AttributeKey old = (AttributeKey)this.name2AttributeKey.putIfAbsent(name, key);
        if (old != null) {
            throw new IllegalArgumentException(String.format("name '%s' in namespace '%s' is already in use", name, this.namespace));
        } else {
            this.cacheForId(key);
            return key;
        }
    }

    private void cacheForId(AttributeKey key) {
        this.id2AttributeKey.put(key.getId(), key);
    }

    public AttributeKey get(int id) {
        return (AttributeKey)this.id2AttributeKey.get(id);
    }
}

3.1 AttributeNamespace操作示例

   @Test
   public void test1()
   {
       AttributeNamespace space=AttributeNamespace.createNamespace("test");
       space.create("test");
       space.getOrCreate("test");
       space.create("test1");
       space.create("test2");
   }

4.AttributeMap和AttributeNamespace

首先当使用AttributeNamespace创建AttributeKey时,其内部容器已经有一个备份,
所以不管在AttributeMap添加还是删除,相同的AttributeKey则不会再重新创建,这样的好处可以让相同AttributeNamespace的AttributeKey可以在不同的AttributeMap中共享,最终实现了相同的AttributeKey,不同的value

public class AttributeMapTest {
    @Test
    public void test2() {
        AttributeNamespace space = AttributeNamespace.createNamespace("test");

        AttributeMap map = new DefaultAttributeMap(space, 12);

        for (int i = 0; i < 20; i++) {
            map.put(space.getOrCreate("key" + i), "value" + i);
        }

        System.out.println(map.get(space.getOrCreate("key2")));

        for (int i = 0; i < 20; i++) {
            map.remove(space.getOrCreate("key" + i));
        }

        map.put(space.getOrCreate("key" + 80), "value" + 88);

        for (int i = 0; i < 20; i++) {
            map.put(space.getOrCreate("key" + i), "value" + i);
        }
        AttributeMap map2 = new ConcurrentAttributeMap(space, 5);
        for (int i = 0; i < 20; i++) {
            map2.put(space.getOrCreate("key" + i), "value2" + i);
        }
    }
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,941评论 19 139
  • 关于Mongodb的全面总结 MongoDB的内部构造《MongoDB The Definitive Guide》...
    中v中阅读 32,370评论 2 89
  • 1.ios高性能编程 (1).内层 最小的内层平均值和峰值(2).耗电量 高效的算法和数据结构(3).初始化时...
    欧辰_OSR阅读 30,349评论 8 265
  • 秋光半盏,夜梦难离,青山往事犹在,两堆黄土心悲。泪眸情深孙儿懂,不是无心、却也无心,而今恩情难还,肠断天涯...
    子山上人阅读 325评论 0 0
  • 各式蛋糕,预定来私我
    oktracy阅读 184评论 0 0

友情链接更多精彩内容