From 4f38f9b7fc277aa55e69a7524a77c03b93d5d4d6 Mon Sep 17 00:00:00 2001 From: sungjindev Date: Fri, 2 Feb 2024 18:03:25 +0900 Subject: [PATCH 1/3] =?UTF-8?q?feat=20:=20=EC=A0=84=EC=B2=B4=20=EA=B0=80?= =?UTF-8?q?=EA=B2=8C=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=EC=A4=91=2015?= =?UTF-8?q?=EA=B0=9C=EC=94=A9=20=EC=B5=9C=EB=8C=80=2075=EA=B0=9C=EB=A5=BC?= =?UTF-8?q?=20=EB=9E=9C=EB=8D=A4=ED=95=98=EA=B2=8C=20=EB=BD=91=EC=95=84?= =?UTF-8?q?=EB=82=B4=EB=8A=94=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?(#78)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/StoreCertificationApi.java | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/nainga/nainga/domain/storecertification/api/StoreCertificationApi.java b/src/main/java/com/nainga/nainga/domain/storecertification/api/StoreCertificationApi.java index 4d4dcad..5827904 100644 --- a/src/main/java/com/nainga/nainga/domain/storecertification/api/StoreCertificationApi.java +++ b/src/main/java/com/nainga/nainga/domain/storecertification/api/StoreCertificationApi.java @@ -16,6 +16,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.ThreadLocalRandom; @RestController @RequiredArgsConstructor @@ -43,7 +44,7 @@ public class StoreCertificationApi { "certificationName: 가게의 인증제 목록
" + "=> 각 인증제별 순서는 보장되지 않습니다.") @GetMapping("api/v1/storecertification/byLocation") - public Result> findStoreCertificationsByLocation(@RequestParam("nwLong") double nwLong, @RequestParam("nwLat") double nwLat, @RequestParam("swLong") double swLong, @RequestParam("swLat") double swLat, @RequestParam("seLong") double seLong, @RequestParam("seLat") double seLat, @RequestParam("neLong") double neLong, @RequestParam("neLat") double neLat) { + public Result>> findStoreCertificationsByLocation(@RequestParam("nwLong") double nwLong, @RequestParam("nwLat") double nwLat, @RequestParam("swLong") double swLong, @RequestParam("swLat") double swLat, @RequestParam("seLong") double seLong, @RequestParam("seLat") double seLat, @RequestParam("neLong") double neLong, @RequestParam("neLat") double neLat) { List storeCertificationsByLocation = storeCertificationService.findStoreCertificationsByLocation(new Location(nwLong, nwLat), new Location(swLong, swLat), new Location(seLong, seLat), new Location(neLong, neLat)); List storeIdsWithMultipleCertifications = storeCertificationService.getDuplicatedStoreIds(); //여러 인증제를 가지고 있는 가게의 id 리스트 List storeCertificationsByLocationResponses = new ArrayList<>(); //반환해줄 StoreCertificationsByLocationResponse들의 List @@ -66,6 +67,31 @@ public Result> findStoreCertificatio storeCertificationsByLocationResponses.add(value); }); - return new Result<>(Result.CODE_SUCCESS, Result.MESSAGE_OK, storeCertificationsByLocationResponses); + List> storeCertificationsByLocationListResponses = new ArrayList<>(); + + //아래 로직은 Multi threads 환경에도 safe한 ThreadLocalRandom을 통해 영역 안에 들어가는 전체 가게 리스트 중 랜덤하게 최대 75개를 뽑는 과정 + int[] randomInts = ThreadLocalRandom.current() + .ints(0, storeCertificationsByLocationResponses.size()) + .distinct() + .limit(75) + .toArray(); + + int count = 0; + List subArray = new ArrayList<>(); + for (int i=0; i < randomInts.length; ++i) { //난수로 뽑은 인덱스를 활용해서 전체 가게 리스트에서 15개씩 가게를 뽑아 배열에 담는 과정 + ++count; + subArray.add(storeCertificationsByLocationResponses.get(randomInts[i])); + + if (count == 15) { + storeCertificationsByLocationListResponses.add(subArray); + subArray = new ArrayList<>(); + count = 0; + } else if (i == randomInts.length - 1) { + storeCertificationsByLocationListResponses.add(subArray); + break; + } + } + + return new Result<>(Result.CODE_SUCCESS, Result.MESSAGE_OK, storeCertificationsByLocationListResponses); } } From d66a2abb550bcec6d10e7407a927fc7f87776e0c Mon Sep 17 00:00:00 2001 From: sungjindev Date: Fri, 2 Feb 2024 18:05:00 +0900 Subject: [PATCH 2/3] =?UTF-8?q?fix=20:=20ThreadLocalRandom=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=EC=9D=98=20ints=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20boundary=20exception=20=EB=B0=A9=EC=A7=80=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80=20(#78)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/storecertification/api/StoreCertificationApi.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/com/nainga/nainga/domain/storecertification/api/StoreCertificationApi.java b/src/main/java/com/nainga/nainga/domain/storecertification/api/StoreCertificationApi.java index 5827904..0146e43 100644 --- a/src/main/java/com/nainga/nainga/domain/storecertification/api/StoreCertificationApi.java +++ b/src/main/java/com/nainga/nainga/domain/storecertification/api/StoreCertificationApi.java @@ -68,6 +68,9 @@ public Result>> findStoreCertif }); List> storeCertificationsByLocationListResponses = new ArrayList<>(); + if (storeCertificationsByLocationResponses.size() == 0) { //size가 0일 때 예외 처리를 안해주면, 밑에 난수 뽑을 때 ints 메서드에서 boundary exception 발생 + return new Result<>(Result.CODE_SUCCESS, Result.MESSAGE_OK, storeCertificationsByLocationListResponses); + } //아래 로직은 Multi threads 환경에도 safe한 ThreadLocalRandom을 통해 영역 안에 들어가는 전체 가게 리스트 중 랜덤하게 최대 75개를 뽑는 과정 int[] randomInts = ThreadLocalRandom.current() From b0af0693b1767e5f542160b24709e5a302088d16 Mon Sep 17 00:00:00 2001 From: sungjindev Date: Fri, 2 Feb 2024 18:09:03 +0900 Subject: [PATCH 3/3] =?UTF-8?q?fix=20:=20ThreadLocalRandom=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=EC=9D=98=20limit=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EB=AC=B4=ED=95=9C=20=EB=A3=A8=ED=94=84=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=EC=88=98=EC=A0=95=20(#78)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/storecertification/api/StoreCertificationApi.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/nainga/nainga/domain/storecertification/api/StoreCertificationApi.java b/src/main/java/com/nainga/nainga/domain/storecertification/api/StoreCertificationApi.java index 0146e43..6eeb006 100644 --- a/src/main/java/com/nainga/nainga/domain/storecertification/api/StoreCertificationApi.java +++ b/src/main/java/com/nainga/nainga/domain/storecertification/api/StoreCertificationApi.java @@ -76,7 +76,7 @@ public Result>> findStoreCertif int[] randomInts = ThreadLocalRandom.current() .ints(0, storeCertificationsByLocationResponses.size()) .distinct() - .limit(75) + .limit(Math.min(storeCertificationsByLocationResponses.size(), 75)) //여기서 limit를 75로만 설정해버리면, 검색 결과의 사이즈가 75개보다 작을 때 무한 루프가 돔 .toArray(); int count = 0;