如何在Java中实现以二进制数组为键、以二进制数组为值的缓存
我需要创建一个包含所有城市和机场的java缓存。因此,如果我查询缓存中的某个位置,比如某个城市,它应该返回该城市中的所有机场,如果我查询的位置是机场,我应该返回该机场。 此外,每个位置都必须存储为缓存中的字节数组。(因为用于查询缓存的公开接口将byte[]作为位置的参数) 其他考虑因素包括:如何在Java中实现以二进制数组为键、以二进制数组为值的缓存,java,arrays,caching,hashmap,Java,Arrays,Caching,Hashmap,我需要创建一个包含所有城市和机场的java缓存。因此,如果我查询缓存中的某个位置,比如某个城市,它应该返回该城市中的所有机场,如果我查询的位置是机场,我应该返回该机场。 此外,每个位置都必须存储为缓存中的字节数组。(因为用于查询缓存的公开接口将byte[]作为位置的参数) 其他考虑因素包括: 检索必须非常快,尽可能快 缓存仅在系统启动时加载一次。获取后不会更改 上膛了 由于它只加载了一次,如果这样可以加快检索速度的话,我们可以对它进行排序 到目前为止,我得到的是: 方法1 在byte[]数组上创
谢谢您不需要字节数组,字符串就可以了 将项目添加到此缓存的频率?我猜这完全是静态的,因为他们不是每天都在建造新的城市或机场 因此,您可以使用两个多散列图,一个键入城市,另一个键入机场。签出谷歌多重地图 如果您正在使用mySQL,那么实际上可以使用基于内存存储引擎的表
许多数据库可以在内存中固定一个表,Oracle绝对可以,所以这是另一种方法。您不需要字节数组,字符串就可以了 将项目添加到此缓存的频率?我猜这完全是静态的,因为他们不是每天都在建造新的城市或机场 因此,您可以使用两个多散列图,一个键入城市,另一个键入机场。签出谷歌多重地图 如果您正在使用mySQL,那么实际上可以使用基于内存存储引擎的表
许多数据库可以将表固定在内存中,Oracle绝对可以,因此这是另一种方式。公开的API基于字节[]这一事实不一定决定缓存的内部细节 第二个观察结果是,这不是一个广义的数据结构问题。所有机场的空间和所有城市的空间都是有限的,都是众所周知的。(你甚至知道尺寸) 哈希映射、树等都是算法,可以保证某些性能特性在通用的既定范围内 既然数据完整性不是问题(“数据不变”),而且如果空间考虑不重要(“尽可能快”),那么为什么不: [编辑:这部分内容在剪切和粘贴过程中不知何故被剪切掉了:如果您知道这些集合,并且它们实际上是静态的,那么您可以为您的城市和机场编制索引(编号)。]
// these need to get initialized on startup
// this initialization can be optimized.
Map<byte[], Long> airportIndexes = new HashMap<byte[], Long>(NUMBER_OF_AIRPORTS);
Map<byte[], Long> citiesIndexes = new HashMap<byte[], Long>(NUMBER_OF_CITIES);
Map<Long, byte[]> airports = new HashMap<Long, byte[]>(NUMBER_OF_AIRPORTS);
Map<Long, byte[]> cities = new HashMap<Long, byte[]>(NUMBER_OF_CITIES);
long[][] airportToCitiesMappings = new byte[NUMBER_OF_AIRPORTS][];
long[][] citiesToAirportMappings = new byte[NUMBER_OF_CITIES][];
public List<byte[]> getCitiesNearAirport(byte[] airportName) {
Long[] cityIndexes = getCitiesByIdxNearAirport(airportName);
List<byte[]> cities = new ArrayList<byte[]>(cityIndexes.length);
for(Long cityIdx : cityIndexes) {
cities.add(cities.get(cityIdx));
}
return cities;
}
public long[] getCitiesByIdxNearAirport(Long airportIdx) {
return airportToCitiesMappings[airportIdx];
}
public long[] getCitiesNearAirport(byte[] airportName) {
return getCitiesNearAirport(airportIndexes.get(airportName));
}
public long[] getCitiesNearAirport(Long airportIdx) {
return airportToCitiesMappings[airportIdx];
}
// .. repeat above pattern for airports.
//这些需要在启动时初始化
//可以优化此初始化。
Map airportIndexes=新HashMap(机场数量);
Map CitiesIndex=新的HashMap(城市数量);
地图机场=新HashMap(机场数量);
地图城市=新HashMap(城市数量);
long[][]airportToCitiesMappings=新字节[机场数量][];
long[]citiesToAirportMappings=新字节[城市数量][];
公共列表getCitiesNearAirport(字节[]airportName){
Long[]CityIndex=getCitiesByIdxNearAirport(airportName);
列表城市=新阵列列表(cityindex.length);
用于(长城市索引:城市索引){
cities.add(cities.get(cityIdx));
}
回归城市;
}
公共长[]getCitiesByIdxNearAirport(长机场){
返回airportToCitiesMappings[AirportDX];
}
公共长[]getCitiesNearAirport(字节[]airportName){
返回getCitiesNearAirport(airportIndexes.get(airportName));
}
公共长[]getCitiesNearAirport(长机场){
返回airportToCitiesMappings[AirportDX];
}
// .. 对机场重复上述模式。
这将为您提供O(1)时间性能特征。就空间而言,有相当多的冗余 公开的API基于字节[]这一事实不一定决定缓存的内部细节 第二个观察结果是,这不是一个广义的数据结构问题。所有机场的空间和所有城市的空间都是有限的,都是众所周知的。(你甚至知道尺寸) 哈希映射、树等都是算法,可以保证某些性能特性在通用的既定范围内 既然数据完整性不是问题(“数据不变”),而且如果空间考虑不重要(“尽可能快”),那么为什么不: [编辑:这部分内容在剪切和粘贴过程中不知何故被剪切掉了:如果您知道这些集合,并且它们实际上是静态的,那么您可以为您的城市和机场编制索引(编号)。]
// these need to get initialized on startup
// this initialization can be optimized.
Map<byte[], Long> airportIndexes = new HashMap<byte[], Long>(NUMBER_OF_AIRPORTS);
Map<byte[], Long> citiesIndexes = new HashMap<byte[], Long>(NUMBER_OF_CITIES);
Map<Long, byte[]> airports = new HashMap<Long, byte[]>(NUMBER_OF_AIRPORTS);
Map<Long, byte[]> cities = new HashMap<Long, byte[]>(NUMBER_OF_CITIES);
long[][] airportToCitiesMappings = new byte[NUMBER_OF_AIRPORTS][];
long[][] citiesToAirportMappings = new byte[NUMBER_OF_CITIES][];
public List<byte[]> getCitiesNearAirport(byte[] airportName) {
Long[] cityIndexes = getCitiesByIdxNearAirport(airportName);
List<byte[]> cities = new ArrayList<byte[]>(cityIndexes.length);
for(Long cityIdx : cityIndexes) {
cities.add(cities.get(cityIdx));
}
return cities;
}
public long[] getCitiesByIdxNearAirport(Long airportIdx) {
return airportToCitiesMappings[airportIdx];
}
public long[] getCitiesNearAirport(byte[] airportName) {
return getCitiesNearAirport(airportIndexes.get(airportName));
}
public long[] getCitiesNearAirport(Long airportIdx) {
return airportToCitiesMappings[airportIdx];
}
// .. repeat above pattern for airports.
//这些需要在启动时初始化
//可以优化此初始化。
Map airportIndexes=新HashMap(机场数量);
Map CitiesIndex=新的HashMap(城市数量);
地图机场=新HashMap(机场数量);
地图城市=新HashMap(城市数量);
long[][]airportToCitiesMappings=新字节[机场数量][];
long[]citiesToAirportMappings=新字节[城市数量][];
公共列表getCitiesNearAirport(字节[]airportName){
Long[]CityIndex=getCitiesByIdxNearAirport(airportName);
列表城市=新阵列列表(cityindex.length);
用于(长城市索引:城市索引){
cities.add(cities.get(cityIdx));
}
回归城市;
}
公共长[]getCitiesByIdxNearAirport(长
Map<byte[], List<byte[]>> m = new TreeMap<byte[], List<byte[]>>(new Comparator<byte[]>() {
public int compare(byte[] o1, byte[] o2) {
int result = (o1.length < o2.length ? -1 : (o1.length == o2.length ? 0 : 1));
int index = 0;
while (result == 0 && index < o1.length) {
result = (o1[index] < o2[index] ? -1 : (o1[index] == o2[index] ? 0 : 1));
index++;
}
return result;
}
});
private static byte[][][] cache = null; // this is the actual cache
// this map has ByteArrayWrapper(a wrapper over byte[]) as key which
// can be an airport or city and index of corresponding
// airport/airports in byte[][][]cache as value
Map<ByteArrayWrapper, Integer> byteLocationIndexes = null;
/**
* This is how cache is queried. You can pass an airport or city as a location parameter
* It will fetch the corresponding airport/airports
*/
private byte[][] getAllAirportsForLocation(ByteArrayWrapper location) {
byte[][] airports = null;
airports = byteLocationIndexes.get(location)== null ? null : cache[byteLocationIndexes.get(location).intValue()];
return airports;
}