|
6 | 6 | import io.github.randomcodespace.iq.model.EdgeKind; |
7 | 7 | import io.github.randomcodespace.iq.model.NodeKind; |
8 | 8 | import org.neo4j.graphdb.GraphDatabaseService; |
| 9 | +import org.neo4j.graphdb.Result; |
9 | 10 | import org.neo4j.graphdb.Transaction; |
10 | 11 | import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; |
11 | 12 | import org.springframework.stereotype.Service; |
@@ -658,12 +659,18 @@ public record FilePathResult(List<Map<String, Object>> rows, boolean truncated) |
658 | 659 | public FilePathResult getFilePathsWithCounts(int maxFiles) { |
659 | 660 | List<Map<String, Object>> rows = new ArrayList<>(); |
660 | 661 | try (Transaction tx = graphDb.beginTx()) { |
661 | | - var result = tx.execute( |
662 | | - "MATCH (n:CodeNode) WHERE n.filePath IS NOT NULL " |
663 | | - + "RETURN n.filePath AS filePath, count(n) AS nodeCount " |
664 | | - + "ORDER BY n.filePath " |
665 | | - + "LIMIT $limit", |
666 | | - Map.of(PROP_LIMIT, (long) (maxFiles + 1))); |
| 662 | + // When maxFiles is very large (e.g., Integer.MAX_VALUE for unlimited treemap), |
| 663 | + // skip the LIMIT clause entirely to avoid integer overflow |
| 664 | + String query = "MATCH (n:CodeNode) WHERE n.filePath IS NOT NULL " |
| 665 | + + "RETURN n.filePath AS filePath, count(n) AS nodeCount " |
| 666 | + + "ORDER BY n.filePath"; |
| 667 | + Result result; |
| 668 | + if (maxFiles < 1_000_000) { |
| 669 | + result = tx.execute(query + " LIMIT $limit", |
| 670 | + Map.of(PROP_LIMIT, (long) (maxFiles + 1))); |
| 671 | + } else { |
| 672 | + result = tx.execute(query); |
| 673 | + } |
667 | 674 | while (result.hasNext()) { |
668 | 675 | var row = result.next(); |
669 | 676 | Map<String, Object> m = new LinkedHashMap<>(); |
@@ -866,6 +873,19 @@ private Map<String, Object> computeGraphStats() { |
866 | 873 | "MATCH (n:CodeNode) WHERE n.filePath IS NOT NULL AND n.filePath <> '' " |
867 | 874 | + "RETURN count(DISTINCT n.filePath) AS cnt"); |
868 | 875 | graph.put("files", r3.hasNext() ? ((Number) r3.next().get(PROP_CNT)).longValue() : 0L); |
| 876 | + |
| 877 | + // Edge kind breakdown |
| 878 | + var r4 = tx.execute( |
| 879 | + "MATCH ()-[r:RELATES_TO]->() " |
| 880 | + + "RETURN r.kind AS kind, count(r) AS cnt ORDER BY cnt DESC"); |
| 881 | + Map<String, Long> edgesByKind = new LinkedHashMap<>(); |
| 882 | + while (r4.hasNext()) { |
| 883 | + var row = r4.next(); |
| 884 | + String kind = (String) row.get(PROP_KIND); |
| 885 | + long cnt = ((Number) row.get(PROP_CNT)).longValue(); |
| 886 | + if (kind != null) edgesByKind.put(kind, cnt); |
| 887 | + } |
| 888 | + graph.put("edges_by_kind", edgesByKind); |
869 | 889 | } |
870 | 890 | return graph; |
871 | 891 | } |
|
0 commit comments