1.AttributeMap
AttributeMap有2个实现
- DefaultAttributeMap 使用数组实现
- ConcurrentAttributeMap 使用ConcurrentHashMap实现
其中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);
}
}
}
网友评论