Skip to content

Commit f82d76a

Browse files
committed
refactor v2 code
1 parent 062b6ac commit f82d76a

16 files changed

Lines changed: 1530 additions & 1088 deletions

src/main/java/org/hdf5javalib/dataclass/HdfFixedPoint.java

Lines changed: 49 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -196,38 +196,62 @@ public int compareTo(HdfFixedPoint other) {
196196
if (other == null) {
197197
throw new NullPointerException("Cannot compare to null");
198198
}
199+
200+
// Optimization: If datatypes are the same, use the faster byte comparison
199201
if (Objects.equals(datatype, other.datatype)) {
200202
return compareToBytes(bytes, other.getBytes());
201-
} else {
202-
// Handle undefined values
203-
boolean thisUndefined = isUndefined();
204-
boolean otherUndefined = other.isUndefined();
205-
if (thisUndefined && otherUndefined) {
206-
return 0; // Both undefined, considered equal
207-
}
208-
if (thisUndefined) {
209-
return 1; // Undefined is less than defined
210-
}
211-
if (otherUndefined) {
212-
return -1; // Defined is greater than undefined
213-
}
203+
}
214204

215-
// Convert byte arrays to BigInteger for comparison
216-
byte[] thisBytes = bytes.clone();
217-
byte[] otherBytes = other.getBytes();
205+
// Handle undefined values check and comparison result
206+
int undefinedComparison = compareUndefined(this, other);
207+
if (undefinedComparison != Integer.MIN_VALUE) {
208+
return undefinedComparison;
209+
}
218210

219-
// Adjust for endianness if necessary
220-
if (!datatype.isBigEndian()) {
221-
HdfReadUtils.reverseBytesInPlace(thisBytes);
222-
HdfReadUtils.reverseBytesInPlace(otherBytes);
223-
}
211+
// Datatypes differ and neither is undefined, perform conversion and comparison
212+
213+
// Convert byte arrays to BigInteger for comparison
214+
byte[] thisBytes = bytes.clone();
215+
byte[] otherBytes = other.getBytes();
216+
217+
// Adjust for endianness if necessary
218+
if (!datatype.isBigEndian()) {
219+
HdfReadUtils.reverseBytesInPlace(thisBytes);
220+
}
221+
if (!other.getDatatype().isBigEndian()) {
222+
HdfReadUtils.reverseBytesInPlace(otherBytes);
223+
}
224+
225+
// Interpret bytes as BigInteger, considering signedness
226+
BigInteger thisValue = datatype.isSigned() ? new BigInteger(thisBytes) : new BigInteger(1, thisBytes);
227+
BigInteger otherValue = other.getDatatype().isSigned() ? new BigInteger(otherBytes) : new BigInteger(1, otherBytes);
228+
229+
return thisValue.compareTo(otherValue);
230+
}
224231

225-
// Interpret bytes as BigInteger, considering signedness
226-
BigInteger thisValue = datatype.isSigned() ? new BigInteger(thisBytes) : new BigInteger(1, thisBytes);
227-
BigInteger otherValue = other.getDatatype().isSigned() ? new BigInteger(otherBytes) : new BigInteger(1, otherBytes);
232+
/**
233+
* Compares two HdfFixedPoint objects based on their undefined status.
234+
*
235+
* @param a The first HdfFixedPoint.
236+
* @param b The second HdfFixedPoint.
237+
* @return 0 if both are undefined, 1 if 'a' is undefined and 'b' is defined,
238+
* -1 if 'a' is defined and 'b' is undefined,
239+
* Integer.MIN_VALUE if neither is undefined (comparison should continue).
240+
*/
241+
private int compareUndefined(HdfFixedPoint a, HdfFixedPoint b) {
242+
boolean thisUndefined = a.isUndefined();
243+
boolean otherUndefined = b.isUndefined();
228244

229-
return thisValue.compareTo(otherValue);
245+
if (thisUndefined && otherUndefined) {
246+
return 0; // Both undefined, considered equal
247+
}
248+
if (thisUndefined) {
249+
return 1; // Undefined is greater than defined (following the original logic)
250+
}
251+
if (otherUndefined) {
252+
return -1; // Defined is less than undefined (following the original logic)
230253
}
254+
return Integer.MIN_VALUE; // Neither is undefined
231255
}
232256

233257
public static int compareToBytes(byte[] first, byte[] second) {

src/main/java/org/hdf5javalib/dataclass/reference/HdfDataspaceSelectionInstance.java

Lines changed: 140 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -46,115 +46,151 @@ public static HdfSelectionType fromValue(int value) {
4646
}
4747
}
4848

49+
/**
50+
* Parses the selection information from the remaining data buffer.
51+
*
52+
* <p>Delegates parsing logic based on the selection type (NONE, ALL, POINTS, HYPERSLABS).
53+
*
54+
* @param remaingData The {@link ByteBuffer} containing the selection details.
55+
* @return An instance of {@code HdfDataspaceSelectionInstance} corresponding to the parsed selection type and version.
56+
* @throws IllegalArgumentException if the selection type or version is invalid.
57+
*/
4958
public static HdfDataspaceSelectionInstance parseSelectionInfo(ByteBuffer remaingData) {
5059
HdfSelectionType selectionType = fromValue(remaingData.getInt());
51-
if (selectionType == H5S_SEL_NONE) {
52-
int version = remaingData.getInt();
53-
return new HdfSelectionNone(version);
60+
int version = remaingData.getInt();
61+
62+
return switch (selectionType) {
63+
case H5S_SEL_NONE -> new HdfSelectionNone(version);
64+
case H5S_SEL_ALL -> new HdfSelectionAll(version);
65+
case H5S_SEL_POINTS -> parsePointsSelection(version, remaingData);
66+
case H5S_SEL_HYPERSLABS -> parseHyperslabsSelection(version, remaingData);
67+
default -> throw new IllegalArgumentException("Invalid selection type: " + selectionType);
68+
};
69+
}
70+
71+
//
72+
// Helper Methods to Reduce Complexity
73+
//
74+
75+
private static HdfDataspaceSelectionInstance parsePointsSelection(int version, ByteBuffer remaingData) {
76+
return switch (version) {
77+
case 1 -> parsePointsV1(version, remaingData);
78+
case 2 -> parsePointsV2(version, remaingData);
79+
default -> throw new IllegalArgumentException("Invalid selection version for POINTS: " + version);
80+
};
81+
}
82+
83+
private static HdfDataspaceSelectionInstance parsePointsV1(int version, ByteBuffer remaingData) {
84+
remaingData.getInt(); // Skip/read padding
85+
int length = remaingData.getInt();
86+
int rank = remaingData.getInt();
87+
int numPoints = remaingData.getInt();
88+
int[][] values = new int[numPoints][rank];
89+
for (int pnum = 0; pnum < numPoints; pnum++) {
90+
for (int rnum = 0; rnum < rank; rnum++) {
91+
values[pnum][rnum] = remaingData.getInt();
92+
}
5493
}
55-
if (selectionType == H5S_SEL_POINTS) {
56-
int version = remaingData.getInt();
57-
if (version == 1) {
58-
remaingData.getInt();
59-
int length = remaingData.getInt();
60-
int rank = remaingData.getInt();
61-
int numPoints = remaingData.getInt();
62-
int[][] values = new int[numPoints][rank];
63-
for (int pnum = 0; pnum < numPoints; pnum++) {
64-
for (int rnum = 0; rnum < rank; rnum++) {
65-
values[pnum][rnum] = remaingData.getInt();
66-
}
67-
}
68-
return new HdfSelectPointsV1(version, length, rank, numPoints, values);
69-
} else if (version == 2) {
70-
int encodingSize = remaingData.getInt();
71-
int rank = remaingData.getInt();
72-
long numPoints = getSizeEncodedValue(encodingSize, remaingData);
73-
74-
long[][] values = new long[Math.toIntExact(numPoints)][rank];
75-
for (int pnum = 0; pnum < numPoints; pnum++) {
76-
for (int rnum = 0; rnum < rank; rnum++) {
77-
values[pnum][rnum] = getSizeEncodedValue(encodingSize, remaingData);
78-
}
79-
}
80-
return new HdfSelectPointsV2(version, encodingSize, rank, numPoints, values);
81-
} else {
82-
throw new IllegalArgumentException("Invalid selection type: " + selectionType);
94+
return new HdfSelectPointsV1(version, length, rank, numPoints, values);
95+
}
96+
97+
private static HdfDataspaceSelectionInstance parsePointsV2(int version, ByteBuffer remaingData) {
98+
int encodingSize = remaingData.getInt();
99+
int rank = remaingData.getInt();
100+
long numPoints = getSizeEncodedValue(encodingSize, remaingData);
101+
102+
long[][] values = new long[Math.toIntExact(numPoints)][rank];
103+
for (int pnum = 0; pnum < numPoints; pnum++) {
104+
for (int rnum = 0; rnum < rank; rnum++) {
105+
values[pnum][rnum] = getSizeEncodedValue(encodingSize, remaingData);
83106
}
84-
} else if (selectionType == H5S_SEL_HYPERSLABS) {
85-
int version = remaingData.getInt();
86-
if (version == 1) {
87-
remaingData.getInt();
88-
int length = remaingData.getInt();
89-
int rank = remaingData.getInt();
90-
int numBlocks = remaingData.getInt();
91-
int[][] startOffsets = new int[numBlocks][rank];
92-
int[][] endOffsets = new int[numBlocks][rank];
93-
for (int bnum = 0; bnum < numBlocks; bnum++) {
94-
for (int rnum = 0; rnum < rank; rnum++) {
95-
startOffsets[bnum][rnum] = remaingData.getInt();
96-
}
97-
for (int rnum = 0; rnum < rank; rnum++) {
98-
endOffsets[bnum][rnum] = remaingData.getInt();
99-
}
100-
}
101-
return new HdfSelectionHyperSlabV1(version, length, rank, numBlocks, startOffsets, endOffsets);
102-
} else if (version == 2) {
103-
int flags = remaingData.get();
104-
int length = remaingData.getInt();
105-
int rank = remaingData.getInt();
106-
long[] start = new long[rank];
107-
long[] stride = new long[rank];
108-
long[] count = new long[rank];
109-
long[] block = new long[rank];
110-
for (int s = 0; s < rank; s++) {
111-
start[s] = remaingData.getLong();
112-
stride[s] = remaingData.getLong();
113-
count[s] = remaingData.getLong();
114-
block[s] = remaingData.getLong();
115-
}
116-
return new HdfSelectionHyperSlabV2(version, flags, length, rank, start, stride, count, block);
117-
} else if (version == 3) {
118-
int flags = remaingData.get();
119-
int encodeSize = remaingData.get();
120-
int rank = remaingData.getInt();
121-
if (flags == 0) {
122-
long[] start = new long[rank];
123-
long[] stride = new long[rank];
124-
long[] count = new long[rank];
125-
long[] block = new long[rank];
126-
for (int s = 0; s < rank; s++) {
127-
start[s] = getSizeEncodedValue(encodeSize, remaingData);
128-
stride[s] = getSizeEncodedValue(encodeSize, remaingData);
129-
count[s] = getSizeEncodedValue(encodeSize, remaingData);
130-
block[s] = getSizeEncodedValue(encodeSize, remaingData);
131-
}
132-
return new HdfSelectionHyperSlabV3Regular(version, flags, encodeSize, rank, start, stride, count, block);
133-
} else if (flags == 1) {
134-
long numBlocks = getSizeEncodedValue(encodeSize, remaingData);
135-
long[][] startOffsets = new long[Math.toIntExact(numBlocks)][rank];
136-
long[][] endOffsets = new long[Math.toIntExact(numBlocks)][rank];
137-
for (int bnum = 0; bnum < numBlocks; bnum++) {
138-
for (int rnum = 0; rnum < rank; rnum++) {
139-
startOffsets[bnum][rnum] = getSizeEncodedValue(encodeSize, remaingData);
140-
}
141-
for (int rnum = 0; rnum < rank; rnum++) {
142-
endOffsets[bnum][rnum] = getSizeEncodedValue(encodeSize, remaingData);
143-
}
144-
}
145-
return new HdfSelectionHyperSlabV3Irregular(version, flags, encodeSize, rank, numBlocks, startOffsets, endOffsets);
146-
} else {
147-
throw new IllegalArgumentException("Invalid selection type: " + selectionType);
148-
}
149-
} else {
150-
throw new IllegalArgumentException("Invalid selection type: " + selectionType);
107+
}
108+
return new HdfSelectPointsV2(version, encodingSize, rank, numPoints, values);
109+
}
110+
111+
private static HdfDataspaceSelectionInstance parseHyperslabsSelection(int version, ByteBuffer remaingData) {
112+
return switch (version) {
113+
case 1 -> parseHyperslabsV1(version, remaingData);
114+
case 2 -> parseHyperslabsV2(version, remaingData);
115+
case 3 -> parseHyperslabsV3(version, remaingData);
116+
default -> throw new IllegalArgumentException("Invalid selection version for HYPERSLABS: " + version);
117+
};
118+
}
119+
120+
private static HdfDataspaceSelectionInstance parseHyperslabsV1(int version, ByteBuffer remaingData) {
121+
remaingData.getInt(); // Skip/read padding
122+
int length = remaingData.getInt();
123+
int rank = remaingData.getInt();
124+
int numBlocks = remaingData.getInt();
125+
int[][] startOffsets = new int[numBlocks][rank];
126+
int[][] endOffsets = new int[numBlocks][rank];
127+
for (int bnum = 0; bnum < numBlocks; bnum++) {
128+
for (int rnum = 0; rnum < rank; rnum++) {
129+
startOffsets[bnum][rnum] = remaingData.getInt();
130+
}
131+
for (int rnum = 0; rnum < rank; rnum++) {
132+
endOffsets[bnum][rnum] = remaingData.getInt();
133+
}
134+
}
135+
return new HdfSelectionHyperSlabV1(version, length, rank, numBlocks, startOffsets, endOffsets);
136+
}
137+
138+
private static HdfDataspaceSelectionInstance parseHyperslabsV2(int version, ByteBuffer remaingData) {
139+
int flags = remaingData.get();
140+
int length = remaingData.getInt();
141+
int rank = remaingData.getInt();
142+
long[] start = new long[rank];
143+
long[] stride = new long[rank];
144+
long[] count = new long[rank];
145+
long[] block = new long[rank];
146+
for (int s = 0; s < rank; s++) {
147+
start[s] = remaingData.getLong();
148+
stride[s] = remaingData.getLong();
149+
count[s] = remaingData.getLong();
150+
block[s] = remaingData.getLong();
151+
}
152+
return new HdfSelectionHyperSlabV2(version, flags, length, rank, start, stride, count, block);
153+
}
154+
155+
private static HdfDataspaceSelectionInstance parseHyperslabsV3(int version, ByteBuffer remaingData) {
156+
int flags = remaingData.get();
157+
int encodeSize = remaingData.get();
158+
int rank = remaingData.getInt();
159+
160+
return switch (flags) {
161+
case 0 -> parseHyperslabsV3Regular(version, flags, encodeSize, rank, remaingData);
162+
case 1 -> parseHyperslabsV3Irregular(version, flags, encodeSize, rank, remaingData);
163+
default -> throw new IllegalArgumentException("Invalid flags for HYPERSLABS V3: " + flags);
164+
};
165+
}
166+
167+
private static HdfDataspaceSelectionInstance parseHyperslabsV3Regular(int version, int flags, int encodeSize, int rank, ByteBuffer remaingData) {
168+
long[] start = new long[rank];
169+
long[] stride = new long[rank];
170+
long[] count = new long[rank];
171+
long[] block = new long[rank];
172+
for (int s = 0; s < rank; s++) {
173+
start[s] = getSizeEncodedValue(encodeSize, remaingData);
174+
stride[s] = getSizeEncodedValue(encodeSize, remaingData);
175+
count[s] = getSizeEncodedValue(encodeSize, remaingData);
176+
block[s] = getSizeEncodedValue(encodeSize, remaingData);
177+
}
178+
return new HdfSelectionHyperSlabV3Regular(version, flags, encodeSize, rank, start, stride, count, block);
179+
}
180+
181+
private static HdfDataspaceSelectionInstance parseHyperslabsV3Irregular(int version, int flags, int encodeSize, int rank, ByteBuffer remaingData) {
182+
long numBlocks = getSizeEncodedValue(encodeSize, remaingData);
183+
long[][] startOffsets = new long[Math.toIntExact(numBlocks)][rank];
184+
long[][] endOffsets = new long[Math.toIntExact(numBlocks)][rank];
185+
for (int bnum = 0; bnum < numBlocks; bnum++) {
186+
for (int rnum = 0; rnum < rank; rnum++) {
187+
startOffsets[bnum][rnum] = getSizeEncodedValue(encodeSize, remaingData);
188+
}
189+
for (int rnum = 0; rnum < rank; rnum++) {
190+
endOffsets[bnum][rnum] = getSizeEncodedValue(encodeSize, remaingData);
151191
}
152-
} else if (selectionType == H5S_SEL_ALL) {
153-
int version = remaingData.getInt();
154-
return new HdfSelectionAll(version);
155-
} else {
156-
throw new IllegalArgumentException("Invalid selection type: " + selectionType);
157192
}
193+
return new HdfSelectionHyperSlabV3Irregular(version, flags, encodeSize, rank, numBlocks, startOffsets, endOffsets);
158194
}
159195

160196
private static long getSizeEncodedValue(int encodingSize, ByteBuffer remaingData) {
@@ -165,5 +201,4 @@ private static long getSizeEncodedValue(int encodingSize, ByteBuffer remaingData
165201
default -> throw new IllegalArgumentException("Invalid encoding size " + encodingSize);
166202
};
167203
}
168-
169-
}
204+
}

0 commit comments

Comments
 (0)