美文网首页
hsf笔记-AttributeMap

hsf笔记-AttributeMap

作者: 兴浩 | 来源:发表于2018-08-13 17:47 被阅读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);
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:hsf笔记-AttributeMap

          本文链接:https://www.haomeiwen.com/subject/rmiubftx.html