我想创建一个HashMap
可以通过仅查看用于为每个映射键创建哈希的第一个属性来快速找到映射值的实现。我希望其工作方式类似于在数据库查询的 WHERE 子句中仅使用 的第一个字段时如何MySQL
使用 acomposite B-tree index
来查找所有匹配的行。composite B-tree index
这听起来很复杂,所以让我解释一下。
可以说我有以下课程:
public class ApiRequest {
private String clientIpAddress;
private String endPoint;
public ApiRequest(String clientIpAddress, String endPoint) {
this.clientIpAddress = clientIpAddress;
this.endPoint = endPoint;
}
//Getters and setters....
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof ApiRequest)) return false;
ApiRequest that = (ApiRequest) o;
return getClientIpAddress().equals(that.getClientIpAddress()) && getEndPoint().equals(that.getEndPoint());
}
@Override
public int hashCode() {
return Objects.hash(getClientIpAddress(), getEndPoint());
}
}
我有以下HashMap
几个条目:
private LoadingCache<ApiRequest, Integer> requestCountMap = new HashMap();
requestCountMap.put(new ApiRequest("212.54.111.23", "/api/users"),3);
requestCountMap.put(new ApiRequest("212.54.111.23", "/api/products"),4);
requestCountMap.put(new ApiRequest("200.10.213.10", "/api/users"),1);
requestCountMap.get(new ApiRequest("212.54.111.23", "/api/users"))
当一个新请求进来时,我可以通过调用例如快速找到给定 ip 到给定 api 端点的先前请求的总数。
现在假设我想找到ApiRequest
ip address 的所有条目"212.54.111.23"
。我可以通过这样的stream()
操作来做到这一点:
requestCountMap.entrySet().stream().filter(entrySet -> entrySet.getKey().getClientIpAddress().equals("212.54.111.23")).collect(Collectors.toList());
但这需要遍历每个EntrySet
元素。我想做的是创建一个新的HashMap
实现,它有一种方法可以根据匹配的clientIpAddress
属性值快速找到所有条目。composite hash index
该方法将通过使用也可以在MySQL
数据库中使用的类似搜索方法来做到这一点。
所以HashMap
实现必须能够创建一个composite B-tree index
基于两个字段的,并且它还必须能够使用它composite B-tree index
来快速找到基于匹配的所有条目clientIpAddress
。生成方法将composite B-tree index
代替该类现在使用的标准Objects.hash(getClientIpAddress(), getEndPoint());
方法。ApiRequest
我已经找到了一个解释 HashMap 工作原理的网页。但是我找不到一个网站来解释如何MySQL
使用 a 的第一部分来composite B-tree index
快速找到使用.composite B-tree index
WHERE clause
所以我的第一个问题是;当 WHERE 子句中只使用一个字段比较时,MySQL 如何使用复合 B 树索引来查找行?
我的第二个问题是:我可以使用composite B-tree index
哈希索引而不是使用生成的常规哈希Objects.hash(getClientIpAddress(), getEndPoint());
吗?
我问第二个问题是因为get()
扩展HashMap
超类的默认方法仍然需要在自定义HashMap
实现中工作。
谢谢
编辑:Thomas Kläger 在评论中指出a的第一部分hash index
不能用于单字段过滤。这只能通过 B 树索引实现。我已将文本中的所有哈希索引引用更改为b-tree
.