Mercurial > dive4elements > river
comparison backend/src/main/java/org/dive4elements/river/importer/ImportCrossSectionLine.java @ 8986:392bbcd8a88b
Database inserts accelerated by suppressing unnecessary database queries for new data series
author | mschaefer |
---|---|
date | Sun, 08 Apr 2018 18:07:06 +0200 |
parents | 36455dfcb788 |
children |
comparison
equal
deleted
inserted
replaced
8985:27851cfda84a | 8986:392bbcd8a88b |
---|---|
6 * documentation coming with Dive4Elements River for details. | 6 * documentation coming with Dive4Elements River for details. |
7 */ | 7 */ |
8 | 8 |
9 package org.dive4elements.river.importer; | 9 package org.dive4elements.river.importer; |
10 | 10 |
11 import org.dive4elements.river.model.CrossSection; | 11 import java.util.Comparator; |
12 import org.dive4elements.river.model.CrossSectionPoint; | |
13 import org.dive4elements.river.model.CrossSectionLine; | |
14 | |
15 import org.hibernate.Session; | |
16 import org.hibernate.Query; | |
17 | |
18 import java.util.List; | 12 import java.util.List; |
19 import java.util.Comparator; | |
20 import java.util.Map; | 13 import java.util.Map; |
21 import java.util.TreeMap; | 14 import java.util.TreeMap; |
15 | |
16 import org.dive4elements.river.importer.common.StoreMode; | |
17 import org.dive4elements.river.model.CrossSection; | |
18 import org.dive4elements.river.model.CrossSectionLine; | |
19 import org.dive4elements.river.model.CrossSectionPoint; | |
20 import org.hibernate.Query; | |
21 import org.hibernate.Session; | |
22 | 22 |
23 /** | 23 /** |
24 * A CrossSectionLine (containing points) ready to be transformed into a mapped | 24 * A CrossSectionLine (containing points) ready to be transformed into a mapped |
25 * object and written to db (used in importer). | 25 * object and written to db (used in importer). |
26 */ | 26 */ |
27 public class ImportCrossSectionLine | 27 public class ImportCrossSectionLine |
28 { | 28 { |
29 public static final Comparator<CrossSectionPoint> INDEX_CMP = | 29 public static final Comparator<CrossSectionPoint> INDEX_CMP = |
30 new Comparator<CrossSectionPoint>() { | 30 new Comparator<CrossSectionPoint>() { |
31 public int compare(CrossSectionPoint a, CrossSectionPoint b) { | 31 @Override |
32 return a.getColPos().compareTo(b.getColPos()); | 32 public int compare(final CrossSectionPoint a, final CrossSectionPoint b) { |
33 } | 33 return a.getColPos().compareTo(b.getColPos()); |
34 }; | 34 } |
35 }; | |
35 | 36 |
36 protected Double km; | 37 protected Double km; |
37 protected ImportCrossSection crossSection; | 38 protected ImportCrossSection crossSection; |
38 protected List<XY> points; | 39 protected List<XY> points; |
40 protected StoreMode storeMode; | |
39 | 41 |
40 protected CrossSectionLine peer; | 42 protected CrossSectionLine peer; |
41 | 43 |
42 public ImportCrossSectionLine() { | 44 public ImportCrossSectionLine() { |
43 } | 45 } |
44 | 46 |
45 public ImportCrossSectionLine(Double km, List<XY> points) { | 47 public ImportCrossSectionLine(final Double km, final List<XY> points) { |
46 this.km = km; | 48 this.km = km; |
47 this.points = points; | 49 this.points = points; |
50 this.storeMode = StoreMode.NONE; | |
48 } | 51 } |
49 | 52 |
50 public ImportCrossSection getCrossSection() { | 53 public ImportCrossSection getCrossSection() { |
51 return crossSection; | 54 return this.crossSection; |
52 } | 55 } |
53 | 56 |
54 public void setCrossSection(ImportCrossSection crossSection) { | 57 public void setCrossSection(final ImportCrossSection crossSection) { |
55 this.crossSection = crossSection; | 58 this.crossSection = crossSection; |
56 } | 59 } |
57 | 60 |
58 public Double getKm() { | 61 public Double getKm() { |
59 return km; | 62 return this.km; |
60 } | 63 } |
61 | 64 |
62 public void setKm(Double km) { | 65 public void setKm(final Double km) { |
63 this.km = km; | 66 this.km = km; |
64 } | 67 } |
65 | 68 |
66 public void storeDependencies() { | 69 public void storeDependencies() { |
67 storePoints(); | 70 storePoints(); |
68 } | 71 } |
69 | 72 |
70 | 73 |
71 /** Write a line and its points. */ | 74 /** Write a line and its points. */ |
72 protected void storePoints() { | 75 protected void storePoints() { |
73 CrossSectionLine csl = getPeer(); | 76 final CrossSectionLine csl = getPeer(); |
74 | 77 if (this.storeMode == StoreMode.INSERT) { |
75 Map<CrossSectionPoint, CrossSectionPoint> map = | 78 insertPoints(); |
76 new TreeMap<CrossSectionPoint, CrossSectionPoint>(INDEX_CMP); | 79 return; |
80 } | |
81 final Map<CrossSectionPoint, CrossSectionPoint> map = | |
82 new TreeMap<>(INDEX_CMP); | |
77 | 83 |
78 // Build index for faster (index) collision lookup. | 84 // Build index for faster (index) collision lookup. |
79 List<CrossSectionPoint> ps = csl.getPoints(); | 85 final List<CrossSectionPoint> ps = csl.getPoints(); |
80 if (ps != null) { | 86 if (ps != null) { |
81 for (CrossSectionPoint point: ps) { | 87 for (final CrossSectionPoint point: ps) { |
82 map.put(point, point); | 88 map.put(point, point); |
83 } | 89 } |
84 } | 90 } |
85 | 91 |
86 Session session = | 92 final Session session = ImporterSession.getInstance().getDatabaseSession(); |
87 ImporterSession.getInstance().getDatabaseSession(); | |
88 | 93 |
89 CrossSectionPoint key = new CrossSectionPoint(); | 94 final CrossSectionPoint key = new CrossSectionPoint(); |
90 | 95 |
91 // Somehow it looks as if even with the map it is still possible that | 96 // Somehow it looks as if even with the map it is still possible that |
92 // multiple points with same id enter hibernate (and then violate a | 97 // multiple points with same id enter hibernate (and then violate a |
93 // constraint). -> TODO | 98 // constraint). -> TODO |
94 for (XY xy: points) { | 99 for (final XY xy: this.points) { |
95 key.setColPos(xy.getIndex()); | 100 key.setColPos(xy.getIndex()); |
96 CrossSectionPoint csp = map.get(key); | 101 CrossSectionPoint csp = map.get(key); |
97 if (csp == null) { // create new | 102 if (csp == null) { // create new |
98 csp = new CrossSectionPoint( | 103 csp = new CrossSectionPoint( |
99 csl, key.getColPos(), | 104 csl, key.getColPos(), |
100 Double.valueOf(xy.getX()), | 105 Double.valueOf(xy.getX()), |
101 Double.valueOf(xy.getY())); | 106 Double.valueOf(xy.getY())); |
102 } | 107 } |
103 else { // update old | 108 else { // update old |
104 csp.setX(Double.valueOf(xy.getX())); | 109 csp.setX(Double.valueOf(xy.getX())); |
105 csp.setY(Double.valueOf(xy.getY())); | 110 csp.setY(Double.valueOf(xy.getY())); |
106 } | 111 } |
107 session.save(csp); | 112 session.save(csp); |
108 } | 113 } |
109 } | 114 } |
110 | 115 |
116 /** | |
117 * Insert the points of a new line into the database without previously querying the database | |
118 */ | |
119 private void insertPoints() { | |
120 final Session session = ImporterSession.getInstance().getDatabaseSession(); | |
121 for (final XY xy : this.points) { | |
122 session.save(new CrossSectionPoint(getPeer(), xy.getIndex(), xy.getX(), xy.getY())); | |
123 } | |
124 } | |
125 | |
111 /** Pull database-mapped object from db, or create (and save) one. */ | 126 /** Pull database-mapped object from db, or create (and save) one. */ |
112 public CrossSectionLine getPeer() { | 127 public CrossSectionLine getPeer() { |
113 if (peer == null) { | 128 if (this.peer == null) { |
114 CrossSection cs = crossSection.getPeer(); | 129 final CrossSection cs = this.crossSection.getPeer(); |
115 | 130 final Session session = ImporterSession.getInstance().getDatabaseSession(); |
116 Session session = | 131 List<CrossSectionLine> lines; |
117 ImporterSession.getInstance().getDatabaseSession(); | 132 if (this.crossSection.storeMode == StoreMode.INSERT) |
118 | 133 lines = null; |
119 Query query = session.createQuery( | 134 else { |
120 "from CrossSectionLine where crossSection=:cs and km=:km"); | 135 final Query query = session.createQuery("from CrossSectionLine where crossSection=:cs and km=:km"); |
121 query.setParameter("cs", cs); | 136 query.setParameter("cs", cs); |
122 query.setParameter("km", km); | 137 query.setParameter("km", this.km); |
123 | 138 lines = query.list(); |
124 List<CrossSectionLine> lines = query.list(); | 139 } |
125 if (lines.isEmpty()) { | 140 if ((lines == null) || lines.isEmpty()) { |
126 peer = new CrossSectionLine(cs, km); | 141 this.peer = new CrossSectionLine(cs, this.km); |
127 session.save(peer); | 142 session.save(this.peer); |
143 this.storeMode = StoreMode.INSERT; | |
128 } | 144 } |
129 else { | 145 else { |
130 peer = lines.get(0); | 146 this.peer = lines.get(0); |
147 this.storeMode = StoreMode.UPDATE; | |
131 } | 148 } |
132 } | 149 } |
133 return peer; | 150 return this.peer; |
134 } | 151 } |
135 } | 152 } |
136 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : | 153 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : |