@@ -7263,6 +7263,58 @@ func TestFileStoreFilteredPendingPSIMFirstBlockUpdateNextBlock(t *testing.T) {
7263
7263
require_Equal (t , psi .lblk , 4 )
7264
7264
}
7265
7265
7266
+ func TestFileStoreLargeSparseMsgsDoNotLoadAfterLast (t * testing.T ) {
7267
+ sd := t .TempDir ()
7268
+ fs , err := newFileStore (
7269
+ FileStoreConfig {StoreDir : sd , BlockSize : 128 },
7270
+ StreamConfig {Name : "zzz" , Subjects : []string {"foo.*.*" }, Storage : FileStorage })
7271
+ require_NoError (t , err )
7272
+ defer fs .Stop ()
7273
+
7274
+ msg := []byte ("hello" )
7275
+ // Create 2 blocks with each, each block holds 2 msgs
7276
+ for i := 0 ; i < 2 ; i ++ {
7277
+ fs .StoreMsg ("foo.22.bar" , nil , msg )
7278
+ fs .StoreMsg ("foo.22.baz" , nil , msg )
7279
+ }
7280
+ // Now create 8 more blocks with just baz. So no matches for these 8 blocks
7281
+ // for "foo.22.bar".
7282
+ for i := 0 ; i < 8 ; i ++ {
7283
+ fs .StoreMsg ("foo.22.baz" , nil , msg )
7284
+ fs .StoreMsg ("foo.22.baz" , nil , msg )
7285
+ }
7286
+ require_Equal (t , fs .numMsgBlocks (), 10 )
7287
+
7288
+ // Remove all blk cache and fss.
7289
+ fs .mu .RLock ()
7290
+ for _ , mb := range fs .blks {
7291
+ mb .mu .Lock ()
7292
+ mb .fss , mb .cache = nil , nil
7293
+ mb .mu .Unlock ()
7294
+ }
7295
+ fs .mu .RUnlock ()
7296
+
7297
+ // "foo.22.bar" is at sequence 1 and 3.
7298
+ // Make sure if we do a LoadNextMsg() starting at 4 that we do not load
7299
+ // all the tail blocks.
7300
+ _ , _ , err = fs .LoadNextMsg ("foo.*.bar" , true , 4 , nil )
7301
+ require_Error (t , err , ErrStoreEOF )
7302
+
7303
+ // Now make sure we did not load fss and cache.
7304
+ var loaded int
7305
+ fs .mu .RLock ()
7306
+ for _ , mb := range fs .blks {
7307
+ mb .mu .RLock ()
7308
+ if mb .cache != nil || mb .fss != nil {
7309
+ loaded ++
7310
+ }
7311
+ mb .mu .RUnlock ()
7312
+ }
7313
+ fs .mu .RUnlock ()
7314
+ // We will load first block for starting seq 4, but no others should have loaded.
7315
+ require_Equal (t , loaded , 1 )
7316
+ }
7317
+
7266
7318
///////////////////////////////////////////////////////////////////////////
7267
7319
// Benchmarks
7268
7320
///////////////////////////////////////////////////////////////////////////
@@ -7520,3 +7572,32 @@ func Benchmark_FileStoreLoadNextMsgVerySparseMsgsInBetweenWithWildcard(b *testin
7520
7572
require_NoError (b , err )
7521
7573
}
7522
7574
}
7575
+
7576
+ func Benchmark_FileStoreLoadNextMsgVerySparseMsgsLargeTail (b * testing.B ) {
7577
+ fs , err := newFileStore (
7578
+ FileStoreConfig {StoreDir : b .TempDir ()},
7579
+ StreamConfig {Name : "zzz" , Subjects : []string {"foo.*.*" }, Storage : FileStorage })
7580
+ require_NoError (b , err )
7581
+ defer fs .Stop ()
7582
+
7583
+ // Small om purpose.
7584
+ msg := []byte ("ok" )
7585
+
7586
+ // Make first msg one that would match as well.
7587
+ fs .StoreMsg ("foo.1.baz" , nil , msg )
7588
+ // Add in a bunch of msgs.
7589
+ // We need to make sure we have a range of subjects that could kick in a linear scan.
7590
+ for i := 0 ; i < 1_000_000 ; i ++ {
7591
+ subj := fmt .Sprintf ("foo.%d.bar" , rand .Intn (100_000 )+ 2 )
7592
+ fs .StoreMsg (subj , nil , msg )
7593
+ }
7594
+
7595
+ b .ResetTimer ()
7596
+
7597
+ var smv StoreMsg
7598
+ for i := 0 ; i < b .N ; i ++ {
7599
+ // Make sure not first seq.
7600
+ _ , _ , err := fs .LoadNextMsg ("foo.*.baz" , true , 2 , & smv )
7601
+ require_Error (b , err , ErrStoreEOF )
7602
+ }
7603
+ }
0 commit comments