From 951e0ce133c6d2fe67c92ea1b9026a848e27e8e7 Mon Sep 17 00:00:00 2001 From: godotg Date: Fri, 24 Mar 2023 22:54:44 +0800 Subject: [PATCH] feat[storage]: support primitive int-object and long-object storage --- .../zfoo/storage/manager/StorageManager.java | 3 +- .../com/zfoo/storage/model/vo/Storage.java | 96 +++++++++++-------- .../com/zfoo/storage/model/vo/StorageInt.java | 92 ++++++++++++++++++ .../zfoo/storage/model/vo/StorageLong.java | 94 ++++++++++++++++++ 4 files changed, 244 insertions(+), 41 deletions(-) create mode 100644 storage/src/main/java/com/zfoo/storage/model/vo/StorageInt.java create mode 100644 storage/src/main/java/com/zfoo/storage/model/vo/StorageLong.java diff --git a/storage/src/main/java/com/zfoo/storage/manager/StorageManager.java b/storage/src/main/java/com/zfoo/storage/manager/StorageManager.java index 2e9e2a35..aee14780 100644 --- a/storage/src/main/java/com/zfoo/storage/manager/StorageManager.java +++ b/storage/src/main/java/com/zfoo/storage/manager/StorageManager.java @@ -131,8 +131,7 @@ public class StorageManager implements IStorageManager { var clazz = definition.getClazz(); var resource = definition.getResource(); var fileExtName = FileUtils.fileExtName(resource.getFilename()); - Storage storage = new Storage<>(); - storage.init(resource.getInputStream(), definition.getClazz(), fileExtName); + Storage storage = Storage.parse(resource.getInputStream(), clazz, fileExtName); storageMap.putIfAbsent(clazz, storage); } } catch (Exception e) { diff --git a/storage/src/main/java/com/zfoo/storage/model/vo/Storage.java b/storage/src/main/java/com/zfoo/storage/model/vo/Storage.java index 2ba937a8..1b27246e 100644 --- a/storage/src/main/java/com/zfoo/storage/model/vo/Storage.java +++ b/storage/src/main/java/com/zfoo/storage/model/vo/Storage.java @@ -30,34 +30,37 @@ import java.util.*; */ public class Storage { - private Class clazz; - - // 当前配置表是否在当前项目中使用,没有被使用的会清楚data数据,以达到节省内存的目的 - private boolean recycle = true; - private Map dataMap = new HashMap<>(); // 非唯一索引 - private Map>> indexMap = new HashMap<>(); + protected Map>> indexMap = new HashMap<>(); // 唯一索引 - private Map> uniqueIndexMap = new HashMap<>(); + protected Map> uniqueIndexMap = new HashMap<>(); - private IdDef idDef; - private Map indexDefMap; + protected Class clazz; + protected IdDef idDef; + protected Map indexDefMap; + // 当前配置表是否在当前项目中使用,没有被使用的会清楚data数据,以达到节省内存的目的 + protected boolean recycle = true; - public void init(InputStream inputStream, Class resourceClazz, String suffix) { + + public static Storage parse(InputStream inputStream, Class resourceClazz, String suffix) { try { - this.clazz = (Class) resourceClazz; - idDef = IdDef.valueOf(resourceClazz); - indexDefMap = IndexDef.createResourceIndexes(resourceClazz); - + Storage storage = new Storage<>(); + storage.clazz = resourceClazz; + var idDef = IdDef.valueOf(resourceClazz); + storage.idDef = idDef; + storage.indexDefMap = IndexDef.createResourceIndexes(resourceClazz); var list = ResourceInterpreter.read(inputStream, resourceClazz, suffix); - - dataMap.clear(); - indexMap.clear(); - uniqueIndexMap.clear(); - for (var object : list) { - put((V) object); + storage.put(object); + } + var idType = idDef.getField().getType(); + if (idType == int.class || idType == Integer.class) { + return new StorageInt<>(storage); + } else if (idType == long.class || idType == Long.class) { + return new StorageLong<>(storage); + } else { + return storage; } } catch (Throwable e) { throw new RuntimeException(e.getMessage(), e); @@ -66,6 +69,32 @@ public class Storage { } } + public boolean contain(K key) { + return dataMap.containsKey(key); + } + + public boolean contain(int key) { + return contain((K) Integer.valueOf(key)); + } + + public boolean contain(long key) { + return contain((K) Long.valueOf(key)); + } + + public V get(K id) { + V result = dataMap.get(id); + AssertionUtils.notNull(result, "The static resource represented as [id:{}] in the static resource [resource:{}] does not exist", id, clazz.getSimpleName()); + return result; + } + + public V get(int id) { + return get((K) Integer.valueOf(id)); + } + + public V get(long id) { + return get((K) Long.valueOf(id)); + } + public void recycleStorage() { recycle = true; dataMap = null; @@ -84,7 +113,7 @@ public class Storage { } public Collection getAll() { - return Collections.unmodifiableCollection(dataMap.values()); + return dataMap.values(); } public Map getData() { @@ -95,16 +124,6 @@ public class Storage { return idDef; } - public boolean contain(K key) { - return dataMap.containsKey(key); - } - - public V get(K id) { - V result = dataMap.get(id); - AssertionUtils.notNull(result, "The static resource represented as [id:{}] in the static resource [resource:{}] does not exist", id, clazz.getSimpleName()); - return result; - } - public List getIndex(String indexName, Object key) { var indexValues = indexMap.get(indexName); AssertionUtils.notNull(indexValues, "The index of [indexName:{}] does not exist in the static resource [resource:{}]", indexName, clazz.getSimpleName()); @@ -123,8 +142,11 @@ public class Storage { return value; } + public int size() { + return dataMap.size(); + } - private V put(V value) { + private V put(Object value) { var key = (K) ReflectionUtils.getField(idDef.getField(), value); if (key == null) { @@ -136,7 +158,7 @@ public class Storage { } // 添加资源 - var result = dataMap.put(key, value); + var result = dataMap.put(key, (V) value); // 添加索引 for (var def : indexDefMap.values()) { @@ -145,20 +167,16 @@ public class Storage { var indexValue = ReflectionUtils.getField(def.getField(), value); if (def.isUnique()) {// 唯一索引 var index = uniqueIndexMap.computeIfAbsent(indexKey, k -> new HashMap<>()); - if (index.put(indexValue, value) != null) { + if (index.put(indexValue, (V) value) != null) { throw new RuntimeException(StringUtils.format("Duplicate unique index [index:{}][value:{}] of static resource [class:{}]", indexKey, indexValue, clazz.getName())); } } else {// 不是唯一索引 var index = indexMap.computeIfAbsent(indexKey, k -> new HashMap<>()); var list = index.computeIfAbsent(indexValue, k -> new ArrayList()); - list.add(value); + list.add((V) value); } } return result; } - public int size() { - return dataMap.size(); - } - } diff --git a/storage/src/main/java/com/zfoo/storage/model/vo/StorageInt.java b/storage/src/main/java/com/zfoo/storage/model/vo/StorageInt.java new file mode 100644 index 00000000..0212e732 --- /dev/null +++ b/storage/src/main/java/com/zfoo/storage/model/vo/StorageInt.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2020 The zfoo Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and limitations under the License. + */ + +package com.zfoo.storage.model.vo; + +import com.zfoo.protocol.util.AssertionUtils; +import io.netty.util.collection.IntObjectHashMap; + +import java.util.*; + +/** + * @author godotg + * @version 4.0 + */ +public class StorageInt extends Storage { + + private IntObjectHashMap dataMap = new IntObjectHashMap(); + + public StorageInt(Storage storage) { + super.indexMap = storage.indexMap; + super.uniqueIndexMap = storage.uniqueIndexMap; + super.clazz = storage.clazz; + super.idDef = storage.idDef; + super.indexDefMap = storage.indexDefMap; + super.recycle = storage.recycle; + this.dataMap.putAll((Map) storage.getData()); + } + + @Override + public boolean contain(K key) { + return contain((int) key); + } + + @Override + public boolean contain(int key) { + return dataMap.containsKey(key); + } + + @Override + public boolean contain(long key) { + return contain((int) key); + } + + @Override + public V get(K id) { + return get((int) id); + } + + @Override + public V get(int id) { + V result = dataMap.get(id); + AssertionUtils.notNull(result, "The static resource represented as [id:{}] in the static resource [resource:{}] does not exist", id, clazz.getSimpleName()); + return result; + } + + @Override + public V get(long id) { + return get((int) id); + } + + @Override + public int size() { + return dataMap.size(); + } + + @Override + public void recycleStorage() { + super.recycleStorage(); + dataMap = null; + } + + @Override + public Collection getAll() { + return dataMap.values(); + } + + @Override + public Map getData() { + return (Map) Collections.unmodifiableMap(dataMap); + } + +} diff --git a/storage/src/main/java/com/zfoo/storage/model/vo/StorageLong.java b/storage/src/main/java/com/zfoo/storage/model/vo/StorageLong.java new file mode 100644 index 00000000..94a3554d --- /dev/null +++ b/storage/src/main/java/com/zfoo/storage/model/vo/StorageLong.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2020 The zfoo Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and limitations under the License. + */ + +package com.zfoo.storage.model.vo; + +import com.zfoo.protocol.util.AssertionUtils; +import io.netty.util.collection.LongObjectHashMap; + +import java.util.Collection; +import java.util.Collections; +import java.util.Map; + +/** + * @author godotg + * @version 4.0 + */ +public class StorageLong extends Storage { + + private LongObjectHashMap dataMap = new LongObjectHashMap(); + + public StorageLong(Storage storage) { + super.indexMap = storage.indexMap; + super.uniqueIndexMap = storage.uniqueIndexMap; + super.clazz = storage.clazz; + super.idDef = storage.idDef; + super.indexDefMap = storage.indexDefMap; + super.recycle = storage.recycle; + this.dataMap.putAll((Map) storage.getData()); + } + + @Override + public boolean contain(K key) { + return contain((long) key); + } + + @Override + public boolean contain(int key) { + return contain((long) key); + } + + @Override + public boolean contain(long key) { + return dataMap.containsKey(key); + } + + @Override + public V get(K id) { + return get((long) id); + } + + @Override + public V get(int id) { + return get((long) id); + } + + @Override + public V get(long id) { + V result = dataMap.get(id); + AssertionUtils.notNull(result, "The static resource represented as [id:{}] in the static resource [resource:{}] does not exist", id, clazz.getSimpleName()); + return result; + } + + @Override + public int size() { + return dataMap.size(); + } + + @Override + public void recycleStorage() { + super.recycleStorage(); + dataMap = null; + } + + @Override + public Collection getAll() { + return dataMap.values(); + } + + @Override + public Map getData() { + return (Map) Collections.unmodifiableMap(dataMap); + } + +}