• R/O
  • SSH
  • HTTPS

eirrepo: Commit


Commit MetaInfo

Revision173 (tree)
Time2018-12-26 01:49:43
Authorquiret

Log Message

- added eir::SortedSliceSector::ScanSharedSlices method which is very useful for buffered files
- added some nice methods + cleanlyness updates

Change Summary

Incremental Difference

--- common/sdk/MathSlice.h (revision 172)
+++ common/sdk/MathSlice.h (revision 173)
@@ -714,6 +714,39 @@
714714 return !( operator < ( left, right ) );
715715 }
716716
717+// *** Equality operators between upperBound and lowerBound.
718+
719+template <typename numberType>
720+AINLINE bool operator == ( const lowerBound <numberType>& left, const upperBound <numberType>& right ) noexcept
721+{
722+ if ( left.get_value() != right.get_value() )
723+ {
724+ return false;
725+ }
726+
727+ if ( left.is_included() || right.is_included() )
728+ {
729+ return false;
730+ }
731+
732+ return true;
733+}
734+template <typename numberType>
735+AINLINE bool operator != ( const lowerBound <numberType>& left, const upperBound <numberType>& right ) noexcept
736+{
737+ return !( operator == ( left, right ) );
738+}
739+template <typename numberType>
740+AINLINE bool operator == ( const upperBound <numberType>& left, const lowerBound <numberType>& right ) noexcept
741+{
742+ return operator == ( right, left );
743+}
744+template <typename numberType>
745+AINLINE bool operator != ( const upperBound <numberType>& left, const lowerBound <numberType>& right ) noexcept
746+{
747+ return operator != ( right, left );
748+}
749+
717750 enum eIntersectionResult
718751 {
719752 INTERSECT_EQUAL,
@@ -764,6 +797,11 @@
764797 return mathSlice( startOffset, endOffset, startIncluded, endIncluded );
765798 }
766799
800+ static AINLINE mathSlice fromBounds( const lowerBound <numberType>& low, const upperBound <numberType>& high )
801+ {
802+ return mathSlice( low.get_value(), high.get_value(), low.is_included(), high.is_included() );
803+ }
804+
767805 AINLINE bool IsEmpty( void ) const noexcept
768806 {
769807 return ( this->startBound > this->endBound );
@@ -802,6 +840,11 @@
802840 return startBound.get_value();
803841 }
804842
843+ AINLINE const lowerBound <numberType>& GetSliceStartBound( void ) const noexcept
844+ {
845+ return startBound;
846+ }
847+
805848 AINLINE bool IsStartIncluded( void ) const noexcept
806849 {
807850 return startBound.is_included();
@@ -812,11 +855,26 @@
812855 return endBound.get_value();
813856 }
814857
858+ AINLINE const upperBound <numberType>& GetSliceEndBound( void ) const noexcept
859+ {
860+ return endBound;
861+ }
862+
815863 AINLINE bool IsEndIncluded( void ) const noexcept
816864 {
817865 return endBound.is_included();
818866 }
819867
868+ // Quick helper. You should consider using the intersectWith method instead.
869+ AINLINE friend bool operator == ( const mathSlice& left, const mathSlice& right )
870+ {
871+ return ( left.startBound == right.startBound && left.endBound == right.endBound );
872+ }
873+ AINLINE friend bool operator != ( const mathSlice& left, const mathSlice& right )
874+ {
875+ return !( operator == ( left, right ) );
876+ }
877+
820878 AINLINE void collapse( void ) noexcept
821879 {
822880 this->endBound = upperBound( this->startBound.get_value(), false );
@@ -889,48 +947,36 @@
889947 {
890948 eIntersectionResult intResult = this->intersectWith( right );
891949
892- numberType startPos, endPos;
893- bool startIncluded, endIncluded;
950+ lowerBound <numberType> start;
951+ upperBound <numberType> end;
894952 bool hasPosition = false;
895953
896954 if ( intResult == INTERSECT_EQUAL || intResult == INTERSECT_ENCLOSING )
897955 {
898- startPos = right.GetSliceStartPoint();
899- endPos = right.GetSliceEndPoint();
956+ start = right.GetSliceStartBound();
957+ end = right.GetSliceEndBound();
900958
901- startIncluded = right.IsStartIncluded();
902- endIncluded = right.IsEndIncluded();
903-
904959 hasPosition = true;
905960 }
906961 else if ( intResult == INTERSECT_INSIDE )
907962 {
908- startPos = this->GetSliceStartPoint();
909- endPos = this->GetSliceEndPoint();
963+ start = this->GetSliceStartBound();
964+ end = this->GetSliceEndBound();
910965
911- startIncluded = this->IsStartIncluded();
912- endIncluded = this->IsEndIncluded();
913-
914966 hasPosition = true;
915967 }
916968 else if ( intResult == INTERSECT_BORDER_START )
917969 {
918- startPos = this->GetSliceStartPoint();
919- endPos = right.GetSliceEndPoint();
970+ start = this->GetSliceStartBound();
971+ end = right.GetSliceEndBound();
920972
921- startIncluded = this->IsStartIncluded();
922- endIncluded = right.IsEndIncluded();
923-
924973 hasPosition = true;
925974 }
926975 else if ( intResult == INTERSECT_BORDER_END )
927976 {
928- startPos = right.GetSliceStartPoint();
929- endPos = this->GetSliceEndPoint();
977+ start = right.GetSliceStartBound();
978+ end = this->GetSliceEndBound();
930979
931- startIncluded = right.IsStartIncluded();
932- endIncluded = this->IsEndIncluded();
933-
934980 hasPosition = true;
935981 }
936982 else if ( intResult == INTERSECT_FLOATING_START || intResult == INTERSECT_FLOATING_END )
@@ -941,7 +987,7 @@
941987
942988 if ( hasPosition )
943989 {
944- sharedOut = fromOffsets( startPos, endPos, startIncluded, endIncluded );
990+ sharedOut = fromBounds( start, end );
945991 }
946992
947993 return hasPosition;
--- common/sdk/SortedSliceSector.h (revision 172)
+++ common/sdk/SortedSliceSector.h (revision 173)
@@ -164,7 +164,7 @@
164164 sliceNode *beginMergeWithNode = AVL_GETITEM( sliceNode, avlBeginMergeWithNode, node );
165165
166166 // Need to collect the region minimum and maximum.
167- numberType regionMin = beginMergeWithNode->GetNodeSlice().GetSliceStartPoint();
167+ lowerBound <numberType> regionMin = beginMergeWithNode->GetNodeSlice().GetSliceStartBound();
168168
169169 AVLNode *avlEndMergeWithNode = this->data.avlSliceTree.FindMaximumNodeByCriteria(
170170 [&]( AVLNode *leftNode )
@@ -176,12 +176,12 @@
176176
177177 sliceNode *endMergeWithNode = AVL_GETITEM( sliceNode, avlEndMergeWithNode, node );
178178
179- numberType regionMax = endMergeWithNode->GetNodeSlice().GetSliceEndPoint();
179+ upperBound <numberType> regionMax = endMergeWithNode->GetNodeSlice().GetSliceEndBound();
180180
181181 // Now remove all nodes that intersect this region from the AVL tree.
182182 this->data.avlSliceTree.RemoveByNode( avlBeginMergeWithNode ); // important so we do not delete the memory.
183183 {
184- sectorSlice_t intersectSlice = sectorSlice_t::fromOffsets( regionMin, regionMax );
184+ sectorSlice_t intersectSlice = sectorSlice_t::fromBounds( regionMin, regionMax );
185185
186186 while ( AVLNode *avlIntersectNode = this->data.avlSliceTree.FindNodeCustom <nodeWithoutNeighborComparator> ( intersectSlice ) )
187187 {
@@ -194,9 +194,9 @@
194194 }
195195 }
196196
197- sectorSlice_t newSlice = sectorSlice_t::fromOffsets(
198- std::min( regionMin, slice.GetSliceStartPoint() ),
199- std::max( regionMax, slice.GetSliceEndPoint() )
197+ sectorSlice_t newSlice = sectorSlice_t::fromBounds(
198+ std::min( regionMin, slice.GetSliceStartBound() ),
199+ std::max( regionMax, slice.GetSliceEndBound() )
200200 );
201201
202202 beginMergeWithNode->metaData.Update( std::move( newSlice ), std::forward <constrArgs> ( args )... );
@@ -351,8 +351,12 @@
351351 // them to the callback. Also passes all slices inbetween that are not in the
352352 // list, if desired.
353353 template <typename callbackType>
354- AINLINE void ScanSharedSlices( const sectorSlice_t& sliceShared, const callbackType& cb, bool includeNotPresent = false )
354+ AINLINE void ScanSharedSlices( sectorSlice_t sliceShared, const callbackType& cb, bool includeNotPresent = false, bool availableSliceWhole = false )
355355 {
356+ // Nothing to do if empty.
357+ if ( sliceShared.IsEmpty() )
358+ return;
359+
356360 AVLNode *avlBeginNode = this->data.avlSliceTree.FindMinimumNodeByCriteria(
357361 [&]( AVLNode *leftNode )
358362 {
@@ -362,13 +366,8 @@
362366 if ( avlBeginNode == nullptr )
363367 return;
364368
365- numberType lastSliceContinuationPoint;
369+ lowerBound <numberType> curStartBound = sliceShared.GetSliceStartBound();
366370
367- if ( includeNotPresent )
368- {
369- lastSliceContinuationPoint = sliceShared.GetSliceStartPoint();
370- }
371-
372371 avlSliceTree_t::diff_node_iterator iter( avlBeginNode );
373372
374373 sliceNode *curNode = AVL_GETITEM( sliceNode, avlBeginNode, node );
@@ -380,9 +379,43 @@
380379 if ( includeNotPresent )
381380 {
382381 // If we have a region prior to our region, then we must report it.
383-
382+ if ( curStartBound < curSlice.GetSliceStartBound() )
383+ {
384+ const sectorSlice_t unavailSlice = sectorSlice_t::fromOffsets(
385+ curStartBound.get_value(), curSlice.GetSliceStartPoint(),
386+ curStartBound.is_included(), !curSlice.IsStartIncluded()
387+ );
388+
389+ cb( unavailSlice, false );
390+ }
391+
392+ // Update the current start point.
393+ if ( curStartBound <= curSlice.GetSliceEndBound() )
394+ {
395+ curStartBound = lowerBound <numberType> ( curSlice.GetSliceEndPoint(), !curSlice.IsEndIncluded() );
396+ }
384397 }
385398
399+ // Now report the available slice.
400+ {
401+ if ( availableSliceWhole )
402+ {
403+ cb( (const sectorSlice_t&)curSlice, true );
404+ }
405+ else
406+ {
407+ sectorSlice_t objSharedSlice;
408+
409+ bool gotShared = curSlice.getSharedRegion( sliceShared, objSharedSlice );
410+
411+#ifdef _DEBUG
412+ assert( gotShared == true );
413+#endif //_DEBUG
414+
415+ cb( (const sectorSlice_t&)objSharedSlice, true );
416+ }
417+ }
418+
386419 iter.Increment();
387420
388421 if ( iter.IsEnd() )
@@ -403,6 +436,17 @@
403436 break;
404437 }
405438 }
439+
440+ if ( includeNotPresent )
441+ {
442+ // Check if we have any unavailable slice at the end.
443+ if ( curStartBound <= sliceShared.GetSliceEndBound() )
444+ {
445+ const sectorSlice_t unavailSlice = sectorSlice_t::fromBounds( curStartBound, sliceShared.GetSliceEndBound() );
446+
447+ cb( unavailSlice, false );
448+ }
449+ }
406450 }
407451
408452 private:
@@ -415,10 +459,14 @@
415459 {
416460 if ( doCountInNeighbors )
417461 {
418- // We are also the same if we are neighboring slices.
419- if ( IsNumberInNeighborhood( leftSlice.GetSliceEndPoint(), rightSlice.GetSliceStartPoint() ) )
462+ // Both slices have to have meeting points.
463+ if ( leftSlice.IsEndIncluded() && rightSlice.IsStartIncluded() )
420464 {
421- return eCompResult::EQUAL;
465+ // We are also the same if we are neighboring slices.
466+ if ( IsNumberInNeighborhood( leftSlice.GetSliceEndPoint(), rightSlice.GetSliceStartPoint() ) )
467+ {
468+ return eCompResult::EQUAL;
469+ }
422470 }
423471 }
424472
@@ -428,9 +476,13 @@
428476 {
429477 if ( doCountInNeighbors )
430478 {
431- if ( IsNumberInNeighborhood( rightSlice.GetSliceEndPoint(), leftSlice.GetSliceStartPoint() ) )
479+ // Both slices have to have meeting points.
480+ if ( rightSlice.IsEndIncluded() && leftSlice.IsStartIncluded() )
432481 {
433- return eCompResult::EQUAL;
482+ if ( IsNumberInNeighborhood( rightSlice.GetSliceEndPoint(), leftSlice.GetSliceStartPoint() ) )
483+ {
484+ return eCompResult::EQUAL;
485+ }
434486 }
435487 }
436488
--- unittests/src/sortedslicesector.cpp (revision 172)
+++ unittests/src/sortedslicesector.cpp (revision 173)
@@ -383,6 +383,141 @@
383383 }
384384 printf( "ok.\n" );
385385
386+ printf( "testing sorted-slice-sector not merge excluded ends..." );
387+ {
388+ eir::SortedSliceSector <float, EirHeapAllocator> slices;
389+
390+ slices.Insert( eir::mathSlice <float>::fromOffsets( 4, 6, true, false ) );
391+ slices.Insert( eir::mathSlice <float>::fromOffsets( 6, 8, false, true ) );
392+
393+ assert( slices.GetSliceCount() == 2 );
394+
395+ slices.Clear();
396+
397+ slices.Insert( eir::mathSlice <float>::fromOffsets( 4, 6, true, true ) );
398+ slices.Insert( eir::mathSlice <float>::fromOffsets( 6, 8, true, true ) );
399+
400+ assert( slices.GetSliceCount() == 1 );
401+
402+ slices.Clear();
403+
404+ slices.Insert( eir::mathSlice <float>::fromOffsets( 4, 6, true, false ) );
405+ slices.Insert( eir::mathSlice <float>::fromOffsets( 6, 8, true, true ) );
406+
407+ assert( slices.GetSliceCount() == 2 );
408+ }
409+ printf( "ok.\n" );
410+
411+ printf( "testing sorted-slice-sector excluded subtract..." );
412+ {
413+ eir::SortedSliceSector <float, EirHeapAllocator> slices;
414+
415+ slices.Insert( eir::mathSlice <float>::fromOffsets( 1, 10, true, true ) );
416+ slices.Remove( eir::mathSlice <float>::fromOffsets( 1, 10, false, false ) );
417+
418+ assert( slices.GetSliceCount() == 2 );
419+ }
420+ printf( "ok.\n" );
421+
422+ printf( "testing sorted-slice-sector ScanSharedSlices method..." );
423+ {
424+ eir::SortedSliceSector <float, EirHeapAllocator> slices;
425+
426+ // Test simple big-overlap scenario
427+ {
428+ slices.Insert( eir::mathSlice <float>::fromOffsets( 2, 4 ) );
429+ slices.Insert( eir::mathSlice <float>::fromOffsets( 6, 8 ) );
430+
431+ size_t availIdx = 0;
432+ size_t unavailIdx = 0;
433+
434+ slices.ScanSharedSlices( eir::mathSlice <float>::fromOffsets( 1, 10, true, true ),
435+ [&]( const eir::mathSlice <float>& slice, bool available )
436+ {
437+ if ( available )
438+ {
439+ if ( availIdx == 0 )
440+ {
441+ assert( slice == eir::mathSlice <float>::fromOffsets( 2, 4, true, true ) );
442+ }
443+ else if ( availIdx == 1 )
444+ {
445+ assert( slice == eir::mathSlice <float>::fromOffsets( 6, 8, true, true ) );
446+ }
447+
448+ availIdx++;
449+ }
450+ else
451+ {
452+ if ( unavailIdx == 0 )
453+ {
454+ assert( slice == eir::mathSlice <float>::fromOffsets( 1, 2, true, false ) );
455+ }
456+ else if ( unavailIdx == 1 )
457+ {
458+ assert( slice == eir::mathSlice <float>::fromOffsets( 4, 6, false, false ) );
459+ }
460+ else if ( unavailIdx == 2 )
461+ {
462+ assert( slice == eir::mathSlice <float>::fromOffsets( 8, 10, false, true ) );
463+ }
464+
465+ unavailIdx++;
466+ }
467+ }, true );
468+
469+ assert( availIdx == 2 );
470+ assert( unavailIdx == 3 );
471+ }
472+
473+ // Test small shared scenario.
474+ {
475+ slices.Clear();
476+
477+ slices.Insert( eir::mathSlice <float>::fromOffsets( 1, 3 ) );
478+
479+ slices.ScanSharedSlices( eir::mathSlice <float>::fromOffsets( 0, 3 ),
480+ [&]( const eir::mathSlice <float>& slice, bool available )
481+ {
482+ if ( !available )
483+ {
484+ assert( slice == eir::mathSlice <float>::fromOffsets( 0, 1, true, false ) );
485+ }
486+ else
487+ {
488+ assert( slice == eir::mathSlice <float>::fromOffsets( 1, 3 ) );
489+ }
490+ }, true );
491+
492+ slices.ScanSharedSlices( eir::mathSlice <float>::fromOffsets( 1, 5 ),
493+ [&]( const eir::mathSlice <float>& slice, bool available )
494+ {
495+ if ( !available )
496+ {
497+ assert( slice == eir::mathSlice <float>::fromOffsets( 3, 5, false, true ) );
498+ }
499+ else
500+ {
501+ assert( slice == eir::mathSlice <float>::fromOffsets( 1, 3 ) );
502+ }
503+ }, true );
504+
505+ slices.ScanSharedSlices( eir::mathSlice <float>::fromOffsets( 2, 2 ),
506+ [&]( const eir::mathSlice <float>& slice, bool available )
507+ {
508+ if ( available )
509+ {
510+ assert( slice == eir::mathSlice <float>::fromOffsets( 2, 2 ) );
511+ }
512+ else
513+ {
514+ assert( 0 );
515+ }
516+ }, true );
517+ }
518+ }
519+ printf( "ok.\n" );
520+
386521 printf( "testing sorted-slice-sector with object allocator..." );
387522 {
388523 eir::SortedSliceSector <size_t, EirHeapLinkAllocator> slices( eir::constr_with_alloc::DEFAULT, &globalHeapAlloc );
Show on old repository browser