@@ -229,44 +229,120 @@ public static long calculateMaxPageEstimatedMemoryUsageInBytesWithBatchData(
229229
230230 public static List <Long > calculatePageEstimatedMemoryUsageInBytesWithBatchDataList (
231231 final Chunk timeChunk , final List <Chunk > valueChunkList ) throws IOException {
232- final ByteBuffer timeChunkDataBuffer = timeChunk .getData ().duplicate ();
233- final List <ByteBuffer > valueChunkDataBufferList = new ArrayList <>(valueChunkList .size ());
232+ final PageMemoryUsageEstimator estimator = new PageMemoryUsageEstimator (timeChunk );
234233 for (final Chunk valueChunk : valueChunkList ) {
235- valueChunkDataBufferList .add (
236- Objects .isNull (valueChunk ) ? null : valueChunk .getData ().duplicate ());
234+ estimator .addValueChunk (valueChunk );
237235 }
236+ return estimator .getPageEstimatedMemoryUsageInBytesList ();
237+ }
238238
239- final List <Long > pageEstimatedMemoryUsageInBytesList = new ArrayList <>();
240- while (timeChunkDataBuffer .remaining () > 0 ) {
241- long pageUncompressedSizeInBytes = 0 ;
242- final PageHeader timePageHeader =
243- SinglePageWholeChunkReader .deserializePageHeader (
244- timeChunkDataBuffer , timeChunk .getHeader ());
245- pageUncompressedSizeInBytes += timePageHeader .getUncompressedSize ();
246- SinglePageWholeChunkReader .skipCompressedPageData (timeChunkDataBuffer , timePageHeader );
247-
248- final List <TSDataType > valueDataTypeList = new ArrayList <>(valueChunkList .size ());
249- for (int i = 0 ; i < valueChunkList .size (); ++i ) {
250- final Chunk valueChunk = valueChunkList .get (i );
251- final ByteBuffer valueChunkDataBuffer = valueChunkDataBufferList .get (i );
252- if (Objects .isNull (valueChunk ) || Objects .isNull (valueChunkDataBuffer )) {
253- valueDataTypeList .add (null );
254- continue ;
255- }
239+ static final class PageMemoryUsageEstimator {
256240
257- final PageHeader valuePageHeader =
241+ private final List <Long > pageUncompressedSizeInBytesList = new ArrayList <>();
242+ private final List <Integer > pageRowCountList = new ArrayList <>();
243+ private List <Long > pageEstimatedMemoryUsageInBytesList = new ArrayList <>();
244+
245+ private int valueCount ;
246+ private TSDataType singleValueDataType ;
247+ private long vectorValueMemoryUsageInBytes ;
248+
249+ PageMemoryUsageEstimator (final Chunk timeChunk ) throws IOException {
250+ final ByteBuffer timeChunkDataBuffer = timeChunk .getData ().duplicate ();
251+ timeChunkDataBuffer .rewind ();
252+ while (timeChunkDataBuffer .remaining () > 0 ) {
253+ final PageHeader timePageHeader =
258254 SinglePageWholeChunkReader .deserializePageHeader (
259- valueChunkDataBuffer , valueChunk .getHeader ());
260- pageUncompressedSizeInBytes += valuePageHeader .getUncompressedSize ();
261- valueDataTypeList .add (valueChunk .getHeader ().getDataType ());
262- SinglePageWholeChunkReader .skipCompressedPageData (valueChunkDataBuffer , valuePageHeader );
255+ timeChunkDataBuffer , timeChunk .getHeader ());
256+ pageUncompressedSizeInBytesList .add ((long ) timePageHeader .getUncompressedSize ());
257+ pageRowCountList .add (SinglePageWholeChunkReader .getPageRowCount (timePageHeader , timeChunk ));
258+ SinglePageWholeChunkReader .skipCompressedPageData (timeChunkDataBuffer , timePageHeader );
259+ }
260+ pageEstimatedMemoryUsageInBytesList = calculatePageEstimatedMemoryUsageInBytesList ();
261+ }
262+
263+ long calculateMaxPageEstimatedMemoryUsageInBytesWithValueChunk (final Chunk valueChunk )
264+ throws IOException {
265+ final List <Long > pageEstimatedMemoryUsageInBytesList =
266+ calculatePageEstimatedMemoryUsageInBytesList (valueChunk , false );
267+ return pageEstimatedMemoryUsageInBytesList .isEmpty ()
268+ ? 0
269+ : pageEstimatedMemoryUsageInBytesList .get (0 );
270+ }
271+
272+ void addValueChunk (final Chunk valueChunk ) throws IOException {
273+ pageEstimatedMemoryUsageInBytesList =
274+ calculatePageEstimatedMemoryUsageInBytesList (valueChunk , true );
275+ }
276+
277+ List <Long > getPageEstimatedMemoryUsageInBytesList () {
278+ return pageEstimatedMemoryUsageInBytesList ;
279+ }
280+
281+ private List <Long > calculatePageEstimatedMemoryUsageInBytesList () {
282+ final List <Long > pageEstimatedMemoryUsageInBytesList =
283+ new ArrayList <>(pageUncompressedSizeInBytesList .size ());
284+ for (int i = 0 ; i < pageUncompressedSizeInBytesList .size (); ++i ) {
285+ pageEstimatedMemoryUsageInBytesList .add (
286+ SinglePageWholeChunkReader .estimatePageMemoryUsageInBytesWithBatchData (
287+ pageUncompressedSizeInBytesList .get (i ),
288+ pageRowCountList .get (i ),
289+ valueCount ,
290+ singleValueDataType ,
291+ vectorValueMemoryUsageInBytes ));
263292 }
264- pageEstimatedMemoryUsageInBytesList .add (
265- SinglePageWholeChunkReader .estimatePageMemoryUsageInBytesWithBatchData (
266- pageUncompressedSizeInBytes ,
267- SinglePageWholeChunkReader .getPageRowCount (timePageHeader , timeChunk ),
268- valueDataTypeList ));
293+ return SinglePageWholeChunkReader .toSuffixMaxList (pageEstimatedMemoryUsageInBytesList );
294+ }
295+
296+ private List <Long > calculatePageEstimatedMemoryUsageInBytesList (
297+ final Chunk valueChunk , final boolean commit ) throws IOException {
298+ final ByteBuffer valueChunkDataBuffer ;
299+ final TSDataType valueDataType ;
300+ if (Objects .isNull (valueChunk )) {
301+ valueChunkDataBuffer = null ;
302+ valueDataType = null ;
303+ } else {
304+ valueChunkDataBuffer = valueChunk .getData ().duplicate ();
305+ valueChunkDataBuffer .rewind ();
306+ valueDataType = valueChunk .getHeader ().getDataType ();
307+ }
308+
309+ final int newValueCount = valueCount + 1 ;
310+ final TSDataType newSingleValueDataType = valueCount == 0 ? valueDataType : null ;
311+ final long newVectorValueMemoryUsageInBytes =
312+ vectorValueMemoryUsageInBytes
313+ + SinglePageWholeChunkReader .estimateVectorValueMemoryUsageInBytes (valueDataType );
314+ final List <Long > newPageUncompressedSizeInBytesList =
315+ new ArrayList <>(pageUncompressedSizeInBytesList );
316+ final List <Long > pageEstimatedMemoryUsageInBytesList =
317+ new ArrayList <>(pageUncompressedSizeInBytesList .size ());
318+
319+ for (int i = 0 ; i < newPageUncompressedSizeInBytesList .size (); ++i ) {
320+ if (Objects .nonNull (valueChunkDataBuffer )) {
321+ final PageHeader valuePageHeader =
322+ SinglePageWholeChunkReader .deserializePageHeader (
323+ valueChunkDataBuffer , valueChunk .getHeader ());
324+ newPageUncompressedSizeInBytesList .set (
325+ i , newPageUncompressedSizeInBytesList .get (i ) + valuePageHeader .getUncompressedSize ());
326+ SinglePageWholeChunkReader .skipCompressedPageData (valueChunkDataBuffer , valuePageHeader );
327+ }
328+ pageEstimatedMemoryUsageInBytesList .add (
329+ SinglePageWholeChunkReader .estimatePageMemoryUsageInBytesWithBatchData (
330+ newPageUncompressedSizeInBytesList .get (i ),
331+ pageRowCountList .get (i ),
332+ newValueCount ,
333+ newSingleValueDataType ,
334+ newVectorValueMemoryUsageInBytes ));
335+ }
336+
337+ if (commit ) {
338+ pageUncompressedSizeInBytesList .clear ();
339+ pageUncompressedSizeInBytesList .addAll (newPageUncompressedSizeInBytesList );
340+ valueCount = newValueCount ;
341+ singleValueDataType = newSingleValueDataType ;
342+ vectorValueMemoryUsageInBytes = newVectorValueMemoryUsageInBytes ;
343+ }
344+
345+ return SinglePageWholeChunkReader .toSuffixMaxList (pageEstimatedMemoryUsageInBytesList );
269346 }
270- return SinglePageWholeChunkReader .toSuffixMaxList (pageEstimatedMemoryUsageInBytesList );
271347 }
272348}
0 commit comments