package com.crawler.repository; import com.crawler.model.Article; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; public class InMemoryArticleRepository implements ArticleRepository { private final Map articles = new ConcurrentHashMap<>(); private final Map urlToIdMap = new ConcurrentHashMap<>(); private final AtomicInteger idGenerator = new AtomicInteger(1); @Override public void save(Article article) { if (article.getId() == null) { article.setId(String.valueOf(idGenerator.getAndIncrement())); } articles.put(article.getId(), article); if (article.getUrl() != null) { urlToIdMap.put(article.getUrl(), article.getId()); } } @Override public void saveAll(List
articleList) { for (Article article : articleList) { save(article); } } @Override public Optional
findById(String id) { return Optional.ofNullable(articles.get(id)); } @Override public Optional
findByUrl(String url) { String id = urlToIdMap.get(url); return id != null ? Optional.ofNullable(articles.get(id)) : Optional.empty(); } @Override public List
findAll() { return new ArrayList<>(articles.values()); } @Override public List
findBySource(String source) { return articles.values().stream() .filter(a -> source.equals(a.getSource())) .collect(Collectors.toList()); } @Override public void deleteById(String id) { Article article = articles.remove(id); if (article != null && article.getUrl() != null) { urlToIdMap.remove(article.getUrl()); } } @Override public void deleteAll() { articles.clear(); urlToIdMap.clear(); } @Override public int count() { return articles.size(); } @Override public boolean existsByUrl(String url) { return urlToIdMap.containsKey(url); } }