@@ -140,7 +140,7 @@ TempSpace::TempSpace(MemoryPool& p, const PathName& prefix, bool dynamic)
140140 logicalSize(0 ), physicalSize(0 ), localCacheUsage(0 ),
141141 head(NULL ), tail(NULL ), tempFiles(p),
142142 initialBuffer(p), initiallyDynamic(dynamic),
143- freeSegments(p)
143+ freeSegments(p), freeSegmentLastPointers(p)
144144{
145145 if (!tempDirs)
146146 {
@@ -180,6 +180,9 @@ TempSpace::~TempSpace()
180180 dbb->decTempCacheUsage (localCacheUsage);
181181 }
182182
183+ for (bool found = freeSegments.getFirst (); found; found = freeSegments.getNext ())
184+ delete freeSegments.current ();
185+
183186 while (tempFiles.getCount ())
184187 delete tempFiles.pop ();
185188}
@@ -476,13 +479,17 @@ offset_t TempSpace::allocateSpace(FB_SIZE_T size)
476479 Segment* best = NULL ;
477480
478481 // Search through the available space in the not used segments list
479- for ( bool found = freeSegments. getFirst (); found; found = freeSegments. getNext ( ))
482+ if (freeSegmentLastPointers. locate (locGreatEqual, size ))
480483 {
481- Segment* const space = &freeSegments.current ();
482- // If this is smaller than our previous best, use it
483- if (space->size >= size && (!best || (space->size < best->size ))) {
484- best = space;
485- }
484+ SegmentLastPointer* const cur = &freeSegmentLastPointers.current ();
485+ const offset_t position = cur->pop ();
486+ if (cur->isEmpty ())
487+ freeSegmentLastPointers.fastRemove ();
488+
489+ if (!freeSegments.locate (position))
490+ fb_assert (false );
491+
492+ best = freeSegments.current ();
486493 }
487494
488495 // If we didn't find any space, allocate it at the end of the file
@@ -503,8 +510,11 @@ offset_t TempSpace::allocateSpace(FB_SIZE_T size)
503510 if (!freeSegments.locate (best->position ))
504511 fb_assert (false );
505512
513+ delete freeSegments.current ();
506514 freeSegments.fastRemove ();
507515 }
516+ else
517+ lastPointerAdd (best);
508518
509519 return position;
510520}
@@ -526,37 +536,48 @@ void TempSpace::releaseSpace(offset_t position, FB_SIZE_T size)
526536 if (freeSegments.locate (locEqual, end))
527537 {
528538 // The next segment is found to be adjacent
529- Segment* const next_seg = &freeSegments.current ();
539+ Segment* const next_seg = freeSegments.current ();
540+ lastPointerRemove (next_seg);
541+
530542 next_seg->position -= size;
531543 next_seg->size += size;
532544
533545 if (freeSegments.getPrev ())
534546 {
535547 // Check the prior segment for being adjacent
536- Segment* const prior_seg = & freeSegments.current ();
548+ Segment* const prior_seg = freeSegments.current ();
537549 if (position == prior_seg->position + prior_seg->size )
538550 {
551+ lastPointerRemove (prior_seg);
552+
539553 next_seg->position -= prior_seg->size ;
540554 next_seg->size += prior_seg->size ;
555+
556+ delete prior_seg;
541557 freeSegments.fastRemove ();
542558 }
543559 }
544560
561+ lastPointerAdd (next_seg);
545562 return ;
546563 }
547564
548565 if (freeSegments.locate (locLess, position))
549566 {
550567 // Check the prior segment for being adjacent
551- Segment* const prior_seg = & freeSegments.current ();
568+ Segment* const prior_seg = freeSegments.current ();
552569 if (position == prior_seg->position + prior_seg->size )
553570 {
571+ lastPointerRemove (prior_seg);
554572 prior_seg->size += size;
573+ lastPointerAdd (prior_seg);
555574 return ;
556575 }
557576 }
558577
559- freeSegments.add (Segment (position, size));
578+ Segment* new_seg = FB_NEW_POOL (pool) Segment (position, size);
579+ freeSegments.add (new_seg);
580+ lastPointerAdd (new_seg);
560581}
561582
562583//
@@ -614,7 +635,7 @@ bool TempSpace::validate(offset_t& free) const
614635 FreeSegmentTree::ConstAccessor accessor (&freeSegments);
615636 for (bool found = accessor.getFirst (); found; found = accessor.getNext ())
616637 {
617- const offset_t size = accessor.current (). size ;
638+ const offset_t size = accessor.current ()-> size ;
618639 fb_assert (size != 0 );
619640 free += size;
620641 }
@@ -643,7 +664,7 @@ ULONG TempSpace::allocateBatch(ULONG count, FB_SIZE_T minSize, FB_SIZE_T maxSize
643664 offset_t freeMem = 0 ;
644665
645666 for (bool found = freeSegments.getFirst (); found; found = freeSegments.getNext ())
646- freeMem += freeSegments.current (). size ;
667+ freeMem += freeSegments.current ()-> size ;
647668
648669 freeMem = MIN (freeMem / count, maxSize);
649670 freeMem = MAX (freeMem, minSize);
@@ -653,7 +674,7 @@ ULONG TempSpace::allocateBatch(ULONG count, FB_SIZE_T minSize, FB_SIZE_T maxSize
653674 bool is_positioned = freeSegments.getFirst ();
654675 while (segments.getCount () < count && is_positioned)
655676 {
656- Segment* freeSpace = & freeSegments.current ();
677+ Segment* freeSpace = freeSegments.current ();
657678 offset_t freeSeek = freeSpace->position ;
658679 const offset_t freeEnd = freeSpace->position + freeSpace->size ;
659680
@@ -668,22 +689,25 @@ ULONG TempSpace::allocateBatch(ULONG count, FB_SIZE_T minSize, FB_SIZE_T maxSize
668689 fb_assert (p == mem);
669690 fb_assert (seek1 == freeSeek);
670691#endif
692+ lastPointerRemove (freeSpace);
693+
671694 if (freeSeek != freeSpace->position )
672695 {
673696 const offset_t skip_size = freeSeek - freeSpace->position ;
674- const Segment skip_space (freeSpace->position , skip_size);
697+ Segment* const skip_space = FB_NEW_POOL (pool) Segment (freeSpace->position , skip_size);
675698
676699 freeSpace->position += skip_size;
677700 freeSpace->size -= skip_size;
678701 fb_assert (freeSpace->size != 0 );
679702
680703 if (!freeSegments.add (skip_space))
681704 fb_assert (false );
705+ lastPointerAdd (skip_space);
682706
683- if (!freeSegments.locate (skip_space. position + skip_size ))
707+ if (!freeSegments.locate (freeSpace-> position ))
684708 fb_assert (false );
685709
686- freeSpace = & freeSegments.current ();
710+ freeSpace = freeSegments.current ();
687711 }
688712
689713 SegmentInMemory seg;
@@ -697,8 +721,11 @@ ULONG TempSpace::allocateBatch(ULONG count, FB_SIZE_T minSize, FB_SIZE_T maxSize
697721
698722 if (!freeSpace->size )
699723 {
724+ delete freeSegments.current ();
700725 is_positioned = freeSegments.fastRemove ();
701726 }
727+ else
728+ lastPointerAdd (freeSpace);
702729 }
703730 else
704731 {
0 commit comments