Fix mereger function, moved it to PhoneService; Use previous logic for PhoneService2

This commit is contained in:
Mikhail Trofimov 2025-10-02 17:19:08 +03:00
parent daceff96af
commit f95b547a81
3 changed files with 96 additions and 44 deletions

View file

@ -5,56 +5,106 @@ import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import ru.nbch.credit_tracker.entities.dto.PhoneFidMap; import ru.nbch.credit_tracker.entities.dto.PhoneFidMap;
import ru.nbch.credit_tracker.mapper.indic.PhoneMapper;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.*; import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j @Slf4j
@Service @Service
public class PhoneService { public class PhoneService {
private final PhoneMapper mapper; private static final String SELCT_FIDS = """
SELECT
pn.number,
pn.fid,
pn.file_since_dt
FROM PHONE_NORM pn
JOIN (SELECT DISTINCT fid FROM NAME) nf
ON nf.fid = pn.fid
WHERE number in (:phones)
ORDER BY
pn.number ASC,
pn.file_since_dt DESC,
pn.fid DESC
WITH UR
""";
public PhoneService(PhoneMapper mapper) { private final NamedParameterJdbcTemplate jdbcTemplate;
this.mapper = mapper;
public PhoneService(@Qualifier("jdbcTemplateIndic") NamedParameterJdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
} }
/** /**
* Ищет фиды по номерам телефона * Ищет фиды по номерам телефона
*
* @return Map: key - fid; value - {@link PhoneFidMap} * @return Map: key - fid; value - {@link PhoneFidMap}
*/ */
public Map<Integer, PhoneFidMap> defineFidByPhone(List<PhoneFidMap> subjects) { public Map<Integer, PhoneFidMap> defineFidByPhone(List<PhoneFidMap> subjects) {
Map<Integer, PhoneFidMap> phoneFidMap = new HashMap<>();
List<String> phones = subjects.stream(). List<String> phones = subjects.stream().
map(subject -> "9" + subject.getPhone()) map(subject -> "9" + subject.getPhone())
.toList(); .toList();
subjects.sort( subjects.sort(
Comparator.comparing( Comparator.comparing(
PhoneFidMap::getPhone, PhoneFidMap::getPhone,
Comparator.naturalOrder() Comparator.naturalOrder()
) )
);
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue("phones", phones);
List<FidsData> phonesByFid = jdbcTemplate.query(SELCT_FIDS, params, (rs, rowNum) ->
new FidsData(rs.getInt("fid"), Long.parseLong(rs.getString("number")), rs.getObject("file_since_dt", LocalDate.class))
); );
//отсортированный список по NUMBER, FID и FILE_SINCE_DT
List<FidsData> phonesByFid = mapper.findFids(phones);
log.debug("Start merging fids"); log.debug("Start merging fids");
for (PhoneFidMap phoneFid : subjects) { Map<Integer, PhoneFidMap> phoneFidMap = merger(subjects, phonesByFid);
Iterator<FidsData> iterator = phonesByFid.iterator(); log.debug("End merging fids");
while (iterator.hasNext()) {
FidsData fidsData = iterator.next(); return phoneFidMap;
if (fidsData.getPhone().equals(9 + phoneFid.getPhone())) { }
//fixme доступ по ссылке, страшно, придумать что-то еще
phoneFidMap.put(fidsData.getFid(), phoneFid); private Map<Integer, PhoneFidMap> merger(List<PhoneFidMap> subjects, List<FidsData> phonesByFid) {
iterator.remove(); Map<Integer, PhoneFidMap> phoneFidMap = new HashMap<>();
if (phonesByFid.isEmpty()) {
return phoneFidMap;
}
int index = 0;
for (PhoneFidMap subject : subjects) {
Long normalizedPhone = Long.parseLong("9" + subject.getPhone());
while (index < phonesByFid.size()) {
FidsData currentFidData = phonesByFid.get(index);
if (currentFidData.getPhone() < normalizedPhone) {
index++;
continue;
}
if (currentFidData.getPhone().equals(normalizedPhone)) {
phoneFidMap.put(currentFidData.getFid(), subject);
index++;
break; break;
} }
break;
}
if (index >= phonesByFid.size()) {
break;
} }
} }
log.debug("End merging fids");
return phoneFidMap; return phoneFidMap;
} }
@ -65,7 +115,7 @@ public class PhoneService {
@NoArgsConstructor @NoArgsConstructor
public static class FidsData { public static class FidsData {
private Integer fid; private Integer fid;
private String phone; private Long phone;
private LocalDate fileSinceDate; private LocalDate fileSinceDate;
} }
} }

View file

@ -75,15 +75,14 @@ public class PhoneService2 {
} }
log.debug("Start merging fids"); log.debug("Start merging fids");
// for (PhoneFidMap phoneFid : subjects) { for (PhoneFidMap phoneFid : subjects) {
// String phone = "9" + phoneFid.getPhone(); String phone = "9" + phoneFid.getPhone();
// Integer fid = phoneToFidsMap.get(phone); Integer fid = phoneToFidsMap.get(phone);
// if (fid != null) { if (fid != null) {
// phoneFidMap.put(fid, phoneFid); phoneFidMap.put(fid, phoneFid);
// phoneToFidsMap.remove(phone); phoneToFidsMap.remove(phone);
// } }
// } }
phoneFidMap = merger(subjects, phonesByFid);
log.debug("End merging fids"); log.debug("End merging fids");
return phoneFidMap; return phoneFidMap;

View file

@ -4,10 +4,11 @@ import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import ru.nbch.credit_tracker.entities.dto.PhoneFidMap; import ru.nbch.credit_tracker.entities.dto.PhoneFidMap;
import ru.nbch.credit_tracker.mapper.indic.PhoneMapper;
import ru.nbch.credit_tracker.service.indic.PhoneService; import ru.nbch.credit_tracker.service.indic.PhoneService;
import java.time.LocalDate; import java.time.LocalDate;
@ -16,20 +17,22 @@ import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class) @ExtendWith(MockitoExtension.class)
public class PhoneServiceTest { public class PhoneServiceTest {
@Mock @Mock
PhoneMapper phoneMapper; NamedParameterJdbcTemplate jdbcTemplate;
@Test @Test
public void defineFidByPhoneTest() { public void defineFidByPhoneTest() {
PhoneService phoneService = new PhoneService(phoneMapper); PhoneService phoneService = new PhoneService(jdbcTemplate);
fidsDataWithEqualSinceDt.sort(byDbOrder); fidsDataWithEqualSinceDt.sort(byDbOrder);
when(phoneMapper.findFids(Mockito.anyList())).thenReturn(fidsDataWithEqualSinceDt); when(jdbcTemplate.query(anyString(), any(MapSqlParameterSource.class), any(RowMapper.class))).thenReturn(fidsDataWithEqualSinceDt);
List<PhoneFidMap> phoneFidMap = new ArrayList<>(); List<PhoneFidMap> phoneFidMap = new ArrayList<>();
phoneFidMap.add(PhoneFidMap.builder().phone("1111").build()); phoneFidMap.add(PhoneFidMap.builder().phone("1111").build());
@ -48,12 +51,12 @@ public class PhoneServiceTest {
private final List<PhoneService.FidsData> fidsDataWithEqualSinceDt = new ArrayList<>( private final List<PhoneService.FidsData> fidsDataWithEqualSinceDt = new ArrayList<>(
List.of( List.of(
new PhoneService.FidsData(123, "91111", LocalDate.of(2025, 9, 10)), new PhoneService.FidsData(123, 91111L, LocalDate.of(2025, 9, 10)),
new PhoneService.FidsData(124, "91111", LocalDate.of(2025, 9, 10)), new PhoneService.FidsData(124, 91111L, LocalDate.of(2025, 9, 10)),
new PhoneService.FidsData(125, "91112", LocalDate.of(2024, 10, 10)), new PhoneService.FidsData(125, 91112L, LocalDate.of(2024, 10, 10)),
new PhoneService.FidsData(126, "91114", LocalDate.of(2024, 10, 11)), new PhoneService.FidsData(126, 91114L, LocalDate.of(2024, 10, 11)),
new PhoneService.FidsData(127, "91115", LocalDate.of(2025, 9, 11)), new PhoneService.FidsData(127, 91115L, LocalDate.of(2025, 9, 11)),
new PhoneService.FidsData(128, "91115", LocalDate.of(2025, 9, 10)) new PhoneService.FidsData(128, 91115L, LocalDate.of(2025, 9, 10))
) )
); );