From d9e14915f2f34543e8db39db088c7382aa5aa911 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20A=2E=20I=2E=20L=C3=B3pez?= <17472377+J-A-I-L@users.noreply.github.com> Date: Sat, 9 Jul 2022 01:26:10 +0200 Subject: [PATCH] Challenge #5 Implement `findSitesByGeoWithCapacity()` in `SiteGeoDaoRedisImpl.java`. --- .../RU102J/RediSolarApplication.java | 8 +- .../RU102J/dao/SiteGeoDaoRedisImpl.java | 98 +++++++++++-------- .../RU102J/dao/SiteGeoDaoRedisImplTest.java | 1 - 3 files changed, 61 insertions(+), 46 deletions(-) diff --git a/src/main/java/com/redislabs/university/RU102J/RediSolarApplication.java b/src/main/java/com/redislabs/university/RU102J/RediSolarApplication.java index 91d15ba..e3495e3 100644 --- a/src/main/java/com/redislabs/university/RU102J/RediSolarApplication.java +++ b/src/main/java/com/redislabs/university/RU102J/RediSolarApplication.java @@ -47,10 +47,10 @@ public void run(final RediSolarConfiguration configuration, } // To use the geospatial features, replace the following lines with: - // SiteGeoResource siteResource = - // new SiteGeoResource(new SiteGeoDaoRedisImpl(jedisPool)); - SiteResource siteResource = - new SiteResource(new SiteDaoRedisImpl(jedisPool)); + SiteGeoResource siteResource = + new SiteGeoResource(new SiteGeoDaoRedisImpl(jedisPool)); +// SiteResource siteResource = +// new SiteResource(new SiteDaoRedisImpl(jedisPool)); environment.jersey().register(siteResource); // For RedisTimeSeries: replace the next lines with diff --git a/src/main/java/com/redislabs/university/RU102J/dao/SiteGeoDaoRedisImpl.java b/src/main/java/com/redislabs/university/RU102J/dao/SiteGeoDaoRedisImpl.java index b3c69bf..9fdf776 100644 --- a/src/main/java/com/redislabs/university/RU102J/dao/SiteGeoDaoRedisImpl.java +++ b/src/main/java/com/redislabs/university/RU102J/dao/SiteGeoDaoRedisImpl.java @@ -33,12 +33,19 @@ public Set findAll() { try (Jedis jedis = jedisPool.getResource()) { Set keys = jedis.zrange(RedisSchema.getSiteGeoKey(), 0, -1); Set sites = new HashSet<>(keys.size()); - for (String key : keys) { - Map site = jedis.hgetAll(key); - if (!site.isEmpty()) { - sites.add(new Site(site)); - } - } + final Pipeline pipeline = jedis.pipelined(); +// for (String key : keys) { +// Map site = jedis.hgetAll(key); +// if (!site.isEmpty()) { +// sites.add(new Site(site)); +// } +// } + keys.forEach(pipeline::hgetAll); + sites = pipeline.syncAndReturnAll().stream() + .filter(siteObject -> siteObject instanceof Map) + .map(siteObject -> (Map) siteObject) + .filter(site -> !site.isEmpty()) + .map(Site::new).collect(Collectors.toSet()); return sites; } } @@ -53,42 +60,51 @@ public Set findByGeo(GeoQuery query) { } // Challenge #5 - private Set findSitesByGeoWithCapacity(GeoQuery query) { - return Collections.emptySet(); - } +// private Set findSitesByGeoWithCapacity(GeoQuery query) { +// return Collections.emptySet(); +// } // Comment out the above, and uncomment what's below -// private Set findSitesByGeoWithCapacity(GeoQuery query) { -// Set results = new HashSet<>(); -// Coordinate coord = query.getCoordinate(); -// Double radius = query.getRadius(); -// GeoUnit radiusUnit = query.getRadiusUnit(); -// -// try (Jedis jedis = jedisPool.getResource()) { -// // START Challenge #5 -// // TODO: Challenge #5: Get the sites matching the geo query, store them -// // in List radiusResponses; -// // END Challenge #5 -// -// Set sites = radiusResponses.stream() -// .map(response -> jedis.hgetAll(response.getMemberByString())) -// .filter(Objects::nonNull) -// .map(Site::new).collect(Collectors.toSet()); -// -// // START Challenge #5 -// Pipeline pipeline = jedis.pipelined(); -// Map> scores = new HashMap<>(sites.size()); -// // TODO: Challenge #5: Add the code that populates the scores HashMap... -// // END Challenge #5 -// -// for (Site site : sites) { -// if (scores.get(site.getId()).get() >= capacityThreshold) { -// results.add(site); -// } -// } -// } -// -// return results; -// } + private Set findSitesByGeoWithCapacity(GeoQuery query) { + Set results = new HashSet<>(); + Coordinate coord = query.getCoordinate(); + Double radius = query.getRadius(); + GeoUnit radiusUnit = query.getRadiusUnit(); + + try (Jedis jedis = jedisPool.getResource()) { + // START Challenge #5 + // TODO: Challenge #5: Get the sites matching the geo query, store them + // in List radiusResponses; + List radiusResponses = + jedis.georadius(RedisSchema.getSiteGeoKey(), coord.getLng(), + coord.getLat(), radius, radiusUnit); + // END Challenge #5 + + Set sites = radiusResponses.stream() + .map(response -> jedis.hgetAll(response.getMemberByString())) + .filter(Objects::nonNull) + .map(Site::new).collect(Collectors.toSet()); + + // START Challenge #5 + Pipeline pipeline = jedis.pipelined(); + Map> scores = new HashMap<>(sites.size()); + // TODO: Challenge #5: Add the code that populates the scores HashMap... + String key = RedisSchema.getCapacityRankingKey(); + for (Site site : sites) { + Response rankResponse = pipeline.zscore(key, site.getId().toString()); + scores.put(site.getId(), rankResponse); + } + pipeline.sync(); + // END Challenge #5 + + for (Site site : sites) { + if (scores.get(site.getId()).get() >= capacityThreshold) { + results.add(site); + } + } + } + + return results; + } private Set findSitesByGeo(GeoQuery query) { Coordinate coord = query.getCoordinate(); diff --git a/src/test/java/com/redislabs/university/RU102J/dao/SiteGeoDaoRedisImplTest.java b/src/test/java/com/redislabs/university/RU102J/dao/SiteGeoDaoRedisImplTest.java index e23b976..56bb57a 100644 --- a/src/test/java/com/redislabs/university/RU102J/dao/SiteGeoDaoRedisImplTest.java +++ b/src/test/java/com/redislabs/university/RU102J/dao/SiteGeoDaoRedisImplTest.java @@ -125,7 +125,6 @@ public void findByGeo() { } // Challenge #5 - @Ignore @Test public void findByGeoWithExcessCapacity() { SiteGeoDao siteDao = new SiteGeoDaoRedisImpl(jedisPool);