绑定完请刷新页面
取消
刷新

分享好友

×
取消 复制
MapDB的spring整合使用
2022-06-22 14:52:37

MapDB是一个快速、易用的嵌入式Java数据库引擎,它提供了基于磁盘或者堆外(off-heap允许Java直接操作内存空间, 类似于C的malloc和free)存储的并发的Maps、Sets、Queues。

业务场景:

朋友公司需要根据坐标,在200m的地址库中寻找离该坐标近的经纬度坐标,难点主要有以下两个:

1.快速把坐标落点到二维的平面上区域,假设(-1,-1),应该落点到xy二维的左下方,这里我采用KDTree的方式

2.因为考虑到tree构建成功后,不想每次都重新构建树,那就需要把树缓存起来,但是通过redis等分布式的cache觉得网络带宽是瓶颈,而且我们的地址库可能会频繁更新,如果用jvm等map的缓存,内存马上就被爆仓了,后来转用MapDB发现它提供多种缓存方式,而且对比后,不管速率以及占用空间都相对较小

3.计算点点之间的距离,在二维平面上其实并不难,通过向量,计算sin、cos等常用手段,马上计算所得结果

 

Spring中但配置

 

  1. <bean id="dbFile" class="java.io.File">
  2. <constructor-arg value="/usr/local/DB/monitor.DB"></constructor-arg>
  3. </bean>
  4. <bean id="dbFactory" class="org.mapdb.DBMaker"
  5. factory-method="newFileDB">
  6. <constructor-arg ref="dbFile" />
  7. </bean>
  8. <bean id="shutdownHook"
  9. factory-bean="dbFactory"
  10. factory-method="closeOnJvmShutdown">
  11. </bean>
  12. <bean id="database"
  13. factory-bean="dbFactory"
  14. factory-method="make">
  15. </bean>

Spring应用启动时加载

 

  1. public class StartupListener implements ServletContextListener {
  2. private static final Logger LOG = LoggerFactory.getLogger(StartupListener.class);
  3. @Override
  4. public void contextInitialized(ServletContextEvent e) {
  5. ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(e.getServletContext());
  6. // AddressInfoMapper addressInfoMapper = (AddressInfoMapper)ctx.getBean("addressInfoMapper");
  7. DB db = (DB) ctx.getBean("database");
  8. BTreeMap<String, String> monitorDataMap = db.getTreeMap("monitorDataMap");
  9. // monitorDataMap.put("name", "Young");
  10. //you can load address information to mapdb
  11. db.commit();
  12. if (ctx == null) {
  13. LOG.error("app start fail!", e);
  14. throw new RuntimeException("WebApplicationContextUtils.getWebApplicationContext() Fail!");
  15. }
  16. LOG.info("app start success.");
  17. }
  18. @Override
  19. public void contextDestroyed(ServletContextEvent sce) {
  20. }
  21. }

  Service中使用

 

  1. // Injected database the map are obtained from it.
  2. private DB database;
  3. private BTreeMap<String, String> monitorDataMap;
  4. public void setDatabase(DB database) {
  5. this.database = database;
  6. }
  7. @PostConstruct
  8. public void init() throws Exception {
  9. this.monitorDataMap = database.getTreeMap("monitorDataMap");
  10. }

 

 

KDTree构建

 

  1. public class KDTree {
  2. // prevent instantiation
  3. private KDTree() {}
  4. private KDTreeNode root;
  5. public static KDTree build(List<? extends Point> points) {
  6. KDTree tree = new KDTree();
  7. tree.root = build(points, );
  8. return tree;
  9. }
  10. private static KDTreeNode build(List<? extends Point> points, int depth) {
  11. if (points.isEmpty()) return null;
  12. final int axis = depth % 2;
  13. Collections.sort(points, new Comparator<Point>() {
  14. public int compare(Point p1, Point p2) {
  15. double coord1 = p1.getCoords()[axis];
  16. double coord2 = p2.getCoords()[axis];
  17. return Double.compare(coord1, coord2);
  18. }
  19. });
  20. int index = points.size() / 2;
  21. KDTreeNode leftChild = build(points.subList(, index), depth + 1);
  22. KDTreeNode rightChild = build(points.subList(index + 1, points.size()), depth + 1);
  23. Point point = points.get(index);
  24. return new KDTreeNode(point, axis, leftChild, rightChild);
  25. }
  26. @SuppressWarnings({"unchecked"})
  27. public <T extends Point> T findNearest(Point point) {
  28. return (T) findNearest(point, 1).get();
  29. }
  30. public List<? extends Point> findNearest(Point point, int amount) {
  31. return root.findNearest(point, amount);
  32. }
  33. @SuppressWarnings({"unchecked"})
  34. public <T extends Point> T getRootPoint() {
  35. return (T) root.getPoint();
  36. }
  37. }

 

 

个人结论:

在使用mapdb的使用后,本人并未去深入了解mapdb的底层原理,只是应急使用,后续肯定会有很多bug显现,但是在使用其框架后,确实性能不少,3-5ms内就能够很容易的找到点之间近关联的,内存损耗40多m左右。

分享好友

分享这个小栈给你的朋友们,一起进步吧。

MapDB
创建时间:2022-04-13 17:18:51
MapDB
展开
订阅须知

• 所有用户可根据关注领域订阅专区或所有专区

• 付费订阅:虚拟交易,一经交易不退款;若特殊情况,可3日内客服咨询

• 专区发布评论属默认订阅所评论专区(除付费小栈外)

技术专家

查看更多
  • LCR_
    专家
戳我,来吐槽~