diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/api/home/HomeService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/api/home/HomeService.kt index 7501745..7283f5c 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/api/home/HomeService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/api/home/HomeService.kt @@ -304,14 +304,17 @@ class HomeService( val memberId = member?.id val isAdult = member?.auth != null && isAdultContentVisible - // 최대 3회까지 동일 로직으로 추가 조회하며, 중복을 제거하고 20개가 되면 조기 반환한다. - val unique = LinkedHashMap() // contentId 기준 중복 제거 + 순서 보존 + // Set + List 조합으로 중복 제거 및 순서 보존, 각 시도마다 limit=60으로 조회 + val seen = HashSet(RECOMMEND_TARGET_SIZE * 2) + val result = ArrayList(RECOMMEND_TARGET_SIZE) var attempt = 0 - while (attempt < RECOMMEND_MAX_ATTEMPTS && unique.size < RECOMMEND_TARGET_SIZE) { + while (attempt < RECOMMEND_MAX_ATTEMPTS && result.size < RECOMMEND_TARGET_SIZE) { attempt += 1 val batch = contentService.getLatestContentByTheme( theme = emptyList(), // 특정 테마에 종속되지 않도록 전체에서 랜덤 조회 contentType = contentType, + offset = 0, + limit = (RECOMMEND_TARGET_SIZE * RECOMMEND_MAX_ATTEMPTS).toLong(), // 60개 조회 isFree = false, isAdult = isAdult, orderByRandom = true @@ -324,13 +327,13 @@ class HomeService( } for (item in batch) { - if (unique.size >= RECOMMEND_TARGET_SIZE) break - if (!unique.containsKey(item.contentId)) { - unique[item.contentId] = item + if (result.size >= RECOMMEND_TARGET_SIZE) break + if (seen.add(item.contentId)) { + result.add(item) } } } - return unique.values.take(RECOMMEND_TARGET_SIZE) + return result } }