hsf笔记-AttributeMap

2018-08-13  本文已影响37人  兴浩

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);
        }
    }
}
上一篇 下一篇

猜你喜欢

热点阅读