@@ -639,31 +639,24 @@ cast ring =
639639eqArrayN :: RingArray a -> Array a -> Int -> IO Bool
640640eqArrayN RingArray {.. } Array. Array {.. } nBytes
641641 | nBytes < 0 = error " eqArrayN: n should be >= 0"
642- | arrLen < nBytes = error " eqArrayN: array is shorter than n"
642+ | arrEnd - arrStart < nBytes = error " eqArrayN: array is shorter than n"
643643 | ringSize < nBytes = error " eqArrayN: ring is shorter than n"
644644 | nBytes == 0 = return True
645- | otherwise = check ringHead 0
646-
645+ | nBytesC <= p1Len = do
646+ part1 <- MutArray. c_memcmp_index arr# 0 ring# p1Off nBytesC
647+ pure $ part1 == 0
648+ | otherwise = do
649+ part1 <- MutArray. c_memcmp_index arr# 0 ring# p1Off p1Len
650+ part2 <- MutArray. c_memcmp_index arr# p1Len ring# p2Off p2Len
651+ pure $ part1 == 0 && part2 == 0
647652 where
648-
649- arrLen = arrEnd - arrStart
650-
651- -- XXX compare Word64 at a time
652- check ringIndex arrayIndex = do
653- (relem :: Word8 ) <- peekAt ringIndex ringContents
654- aelem <- peekAt arrayIndex arrContents
655- if relem == aelem
656- then go (ringIndex + 1 ) (arrayIndex + 1 )
657- else return False
658-
659- go ringIndex arrayIndex
660- -- Checking ringIndex == rh is enough
661- -- | arrayIndex == nBytes = return True
662- | ringIndex == ringSize = go 0 arrayIndex
663- | ringIndex == ringHead = return True
664- | otherwise = check ringIndex arrayIndex
665-
666- -- XXX We can use memcmp over two segments.
653+ nBytesC = fromIntegral nBytes
654+ arr# = MutByteArray. getMutByteArray# arrContents
655+ ring# = MutByteArray. getMutByteArray# ringContents
656+ p1Off = fromIntegral ringHead
657+ p1Len = fromIntegral $ ringSize - ringHead
658+ p2Off = 0
659+ p2Len = nBytesC - p1Len
667660
668661-- | Byte compare the entire length of ringBuffer with the given array,
669662-- starting at the supplied ring head index. Returns true if the Array and
@@ -674,25 +667,18 @@ eqArrayN RingArray{..} Array.Array{..} nBytes
674667{-# INLINE eqArray #-}
675668eqArray :: RingArray a -> Array a -> IO Bool
676669eqArray RingArray {.. } Array. Array {.. }
677- | arrLen < ringSize = error " eqArrayN: array is shorter than ring"
678- | otherwise = check ringHead 0
679-
670+ | arrEnd - arrStart < ringSize = error " eqArrayN: array is shorter than ring"
671+ | otherwise = do
672+ part1 <- MutArray. c_memcmp_index arr# 0 ring# p1Off p1Len
673+ part2 <- MutArray. c_memcmp_index arr# p1Len ring# p2Off p2Len
674+ pure $ part1 == 0 && part2 == 0
680675 where
681-
682- arrLen = arrEnd - arrStart
683-
684- -- XXX compare Word64 at a time
685- check ringIndex arrayIndex = do
686- (relem :: Word8 ) <- peekAt ringIndex ringContents
687- aelem <- peekAt arrayIndex arrContents
688- if relem == aelem
689- then go (ringIndex + 1 ) (arrayIndex + 1 )
690- else return False
691-
692- go ringIndex arrayIndex
693- | ringIndex == ringSize = go 0 arrayIndex
694- | ringIndex == ringHead = return True
695- | otherwise = check ringIndex arrayIndex
676+ arr# = MutByteArray. getMutByteArray# arrContents
677+ ring# = MutByteArray. getMutByteArray# ringContents
678+ p1Off = fromIntegral ringHead
679+ p1Len = fromIntegral $ ringSize - ringHead
680+ p2Off = 0
681+ p2Len = fromIntegral $ ringHead
696682
697683-------------------------------------------------------------------------------
698684-- Folding
0 commit comments