github.com/nats-io/nats-server/v2@v2.11.0-preview.2/server/memstore.go (about) 1 // Copyright 2019-2024 The NATS Authors 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package server 15 16 import ( 17 crand "crypto/rand" 18 "encoding/binary" 19 "fmt" 20 "sort" 21 "sync" 22 "time" 23 24 "github.com/nats-io/nats-server/v2/server/avl" 25 "github.com/nats-io/nats-server/v2/server/stree" 26 ) 27 28 // TODO(dlc) - This is a fairly simplistic approach but should do for now. 29 type memStore struct { 30 mu sync.RWMutex 31 cfg StreamConfig 32 state StreamState 33 msgs map[uint64]*StoreMsg 34 fss *stree.SubjectTree[SimpleState] 35 dmap avl.SequenceSet 36 maxp int64 37 scb StorageUpdateHandler 38 ageChk *time.Timer 39 consumers int 40 receivedAny bool 41 } 42 43 func newMemStore(cfg *StreamConfig) (*memStore, error) { 44 if cfg == nil { 45 return nil, fmt.Errorf("config required") 46 } 47 if cfg.Storage != MemoryStorage { 48 return nil, fmt.Errorf("memStore requires memory storage type in config") 49 } 50 ms := &memStore{ 51 msgs: make(map[uint64]*StoreMsg), 52 fss: stree.NewSubjectTree[SimpleState](), 53 maxp: cfg.MaxMsgsPer, 54 cfg: *cfg, 55 } 56 if cfg.FirstSeq > 0 { 57 if _, err := ms.purge(cfg.FirstSeq); err != nil { 58 return nil, err 59 } 60 } 61 62 return ms, nil 63 } 64 65 func (ms *memStore) UpdateConfig(cfg *StreamConfig) error { 66 if cfg == nil { 67 return fmt.Errorf("config required") 68 } 69 if cfg.Storage != MemoryStorage { 70 return fmt.Errorf("memStore requires memory storage type in config") 71 } 72 73 ms.mu.Lock() 74 ms.cfg = *cfg 75 // Limits checks and enforcement. 76 ms.enforceMsgLimit() 77 ms.enforceBytesLimit() 78 // Do age timers. 79 if ms.ageChk == nil && ms.cfg.MaxAge != 0 { 80 ms.startAgeChk() 81 } 82 if ms.ageChk != nil && ms.cfg.MaxAge == 0 { 83 ms.ageChk.Stop() 84 ms.ageChk = nil 85 } 86 // Make sure to update MaxMsgsPer 87 maxp := ms.maxp 88 ms.maxp = cfg.MaxMsgsPer 89 // If the value is smaller we need to enforce that. 90 if ms.maxp != 0 && ms.maxp < maxp { 91 lm := uint64(ms.maxp) 92 ms.fss.Iter(func(subj []byte, ss *SimpleState) bool { 93 if ss.Msgs > lm { 94 ms.enforcePerSubjectLimit(bytesToString(subj), ss) 95 } 96 return true 97 }) 98 } 99 ms.mu.Unlock() 100 101 if cfg.MaxAge != 0 { 102 ms.expireMsgs() 103 } 104 return nil 105 } 106 107 // Stores a raw message with expected sequence number and timestamp. 108 // Lock should be held. 109 func (ms *memStore) storeRawMsg(subj string, hdr, msg []byte, seq uint64, ts int64) error { 110 if ms.msgs == nil { 111 return ErrStoreClosed 112 } 113 114 // Tracking by subject. 115 var ss *SimpleState 116 var asl bool 117 if len(subj) > 0 { 118 var ok bool 119 if ss, ok = ms.fss.Find(stringToBytes(subj)); ok { 120 asl = ms.maxp > 0 && ss.Msgs >= uint64(ms.maxp) 121 } 122 } 123 124 // Check if we are discarding new messages when we reach the limit. 125 if ms.cfg.Discard == DiscardNew { 126 if asl && ms.cfg.DiscardNewPer { 127 return ErrMaxMsgsPerSubject 128 } 129 // If we are discard new and limits policy and clustered, we do the enforcement 130 // above and should not disqualify the message here since it could cause replicas to drift. 131 if ms.cfg.Retention == LimitsPolicy || ms.cfg.Replicas == 1 { 132 if ms.cfg.MaxMsgs > 0 && ms.state.Msgs >= uint64(ms.cfg.MaxMsgs) { 133 // If we are tracking max messages per subject and are at the limit we will replace, so this is ok. 134 if !asl { 135 return ErrMaxMsgs 136 } 137 } 138 if ms.cfg.MaxBytes > 0 && ms.state.Bytes+memStoreMsgSize(subj, hdr, msg) >= uint64(ms.cfg.MaxBytes) { 139 if !asl { 140 return ErrMaxBytes 141 } 142 // If we are here we are at a subject maximum, need to determine if dropping last message gives us enough room. 143 if ss.firstNeedsUpdate { 144 ms.recalculateFirstForSubj(subj, ss.First, ss) 145 } 146 sm, ok := ms.msgs[ss.First] 147 if !ok || memStoreMsgSize(sm.subj, sm.hdr, sm.msg) < memStoreMsgSize(subj, hdr, msg) { 148 return ErrMaxBytes 149 } 150 } 151 } 152 } 153 154 if seq != ms.state.LastSeq+1 { 155 if seq > 0 { 156 return ErrSequenceMismatch 157 } 158 seq = ms.state.LastSeq + 1 159 } 160 161 // Adjust first if needed. 162 now := time.Unix(0, ts).UTC() 163 if ms.state.Msgs == 0 { 164 ms.state.FirstSeq = seq 165 ms.state.FirstTime = now 166 } 167 168 // Make copies 169 // TODO(dlc) - Maybe be smarter here. 170 if len(msg) > 0 { 171 msg = copyBytes(msg) 172 } 173 if len(hdr) > 0 { 174 hdr = copyBytes(hdr) 175 } 176 177 // FIXME(dlc) - Could pool at this level? 178 sm := &StoreMsg{subj, nil, nil, make([]byte, 0, len(hdr)+len(msg)), seq, ts} 179 sm.buf = append(sm.buf, hdr...) 180 sm.buf = append(sm.buf, msg...) 181 if len(hdr) > 0 { 182 sm.hdr = sm.buf[:len(hdr)] 183 } 184 sm.msg = sm.buf[len(hdr):] 185 ms.msgs[seq] = sm 186 ms.state.Msgs++ 187 ms.state.Bytes += memStoreMsgSize(subj, hdr, msg) 188 ms.state.LastSeq = seq 189 ms.state.LastTime = now 190 191 // Track per subject. 192 if len(subj) > 0 { 193 if ss != nil { 194 ss.Msgs++ 195 ss.Last = seq 196 // Check per subject limits. 197 if ms.maxp > 0 && ss.Msgs > uint64(ms.maxp) { 198 ms.enforcePerSubjectLimit(subj, ss) 199 } 200 } else { 201 ms.fss.Insert([]byte(subj), SimpleState{Msgs: 1, First: seq, Last: seq}) 202 } 203 } 204 205 // Limits checks and enforcement. 206 ms.enforceMsgLimit() 207 ms.enforceBytesLimit() 208 209 // Check if we have and need the age expiration timer running. 210 if ms.ageChk == nil && ms.cfg.MaxAge != 0 { 211 ms.startAgeChk() 212 } 213 return nil 214 } 215 216 // StoreRawMsg stores a raw message with expected sequence number and timestamp. 217 func (ms *memStore) StoreRawMsg(subj string, hdr, msg []byte, seq uint64, ts int64) error { 218 ms.mu.Lock() 219 err := ms.storeRawMsg(subj, hdr, msg, seq, ts) 220 cb := ms.scb 221 // Check if first message timestamp requires expiry 222 // sooner than initial replica expiry timer set to MaxAge when initializing. 223 if !ms.receivedAny && ms.cfg.MaxAge != 0 && ts > 0 { 224 ms.receivedAny = true 225 // Calculate duration when the next expireMsgs should be called. 226 ms.resetAgeChk(int64(time.Millisecond) * 50) 227 } 228 ms.mu.Unlock() 229 230 if err == nil && cb != nil { 231 cb(1, int64(memStoreMsgSize(subj, hdr, msg)), seq, subj) 232 } 233 234 return err 235 } 236 237 // Store stores a message. 238 func (ms *memStore) StoreMsg(subj string, hdr, msg []byte) (uint64, int64, error) { 239 ms.mu.Lock() 240 seq, ts := ms.state.LastSeq+1, time.Now().UnixNano() 241 err := ms.storeRawMsg(subj, hdr, msg, seq, ts) 242 cb := ms.scb 243 ms.mu.Unlock() 244 245 if err != nil { 246 seq, ts = 0, 0 247 } else if cb != nil { 248 cb(1, int64(memStoreMsgSize(subj, hdr, msg)), seq, subj) 249 } 250 251 return seq, ts, err 252 } 253 254 // SkipMsg will use the next sequence number but not store anything. 255 func (ms *memStore) SkipMsg() uint64 { 256 // Grab time. 257 now := time.Now().UTC() 258 259 ms.mu.Lock() 260 seq := ms.state.LastSeq + 1 261 ms.state.LastSeq = seq 262 ms.state.LastTime = now 263 if ms.state.Msgs == 0 { 264 ms.state.FirstSeq = seq 265 ms.state.FirstTime = now 266 } else { 267 ms.dmap.Insert(seq) 268 } 269 ms.mu.Unlock() 270 return seq 271 } 272 273 // Skip multiple msgs. 274 func (ms *memStore) SkipMsgs(seq uint64, num uint64) error { 275 // Grab time. 276 now := time.Now().UTC() 277 278 ms.mu.Lock() 279 defer ms.mu.Unlock() 280 281 // Check sequence matches our last sequence. 282 if seq != ms.state.LastSeq+1 { 283 if seq > 0 { 284 return ErrSequenceMismatch 285 } 286 seq = ms.state.LastSeq + 1 287 } 288 lseq := seq + num - 1 289 290 ms.state.LastSeq = lseq 291 ms.state.LastTime = now 292 if ms.state.Msgs == 0 { 293 ms.state.FirstSeq, ms.state.FirstTime = lseq+1, now 294 } else { 295 for ; seq <= lseq; seq++ { 296 ms.dmap.Insert(seq) 297 } 298 } 299 return nil 300 } 301 302 // RegisterStorageUpdates registers a callback for updates to storage changes. 303 // It will present number of messages and bytes as a signed integer and an 304 // optional sequence number of the message if a single. 305 func (ms *memStore) RegisterStorageUpdates(cb StorageUpdateHandler) { 306 ms.mu.Lock() 307 ms.scb = cb 308 ms.mu.Unlock() 309 } 310 311 // GetSeqFromTime looks for the first sequence number that has the message 312 // with >= timestamp. 313 // FIXME(dlc) - inefficient. 314 func (ms *memStore) GetSeqFromTime(t time.Time) uint64 { 315 ts := t.UnixNano() 316 ms.mu.RLock() 317 defer ms.mu.RUnlock() 318 if len(ms.msgs) == 0 { 319 return ms.state.LastSeq + 1 320 } 321 if ts <= ms.msgs[ms.state.FirstSeq].ts { 322 return ms.state.FirstSeq 323 } 324 // LastSeq is not guaranteed to be present since last does not go backwards. 325 var lmsg *StoreMsg 326 for lseq := ms.state.LastSeq; lseq > ms.state.FirstSeq; lseq-- { 327 if lmsg = ms.msgs[lseq]; lmsg != nil { 328 break 329 } 330 } 331 if lmsg == nil { 332 return ms.state.FirstSeq 333 } 334 335 last := lmsg.ts 336 if ts == last { 337 return ms.state.LastSeq 338 } 339 if ts > last { 340 return ms.state.LastSeq + 1 341 } 342 index := sort.Search(len(ms.msgs), func(i int) bool { 343 if msg := ms.msgs[ms.state.FirstSeq+uint64(i)]; msg != nil { 344 return msg.ts >= ts 345 } 346 return false 347 }) 348 return uint64(index) + ms.state.FirstSeq 349 } 350 351 // FilteredState will return the SimpleState associated with the filtered subject and a proposed starting sequence. 352 func (ms *memStore) FilteredState(sseq uint64, subj string) SimpleState { 353 // This needs to be a write lock, as filteredStateLocked can 354 // mutate the per-subject state. 355 ms.mu.Lock() 356 defer ms.mu.Unlock() 357 358 return ms.filteredStateLocked(sseq, subj, false) 359 } 360 361 func (ms *memStore) filteredStateLocked(sseq uint64, filter string, lastPerSubject bool) SimpleState { 362 var ss SimpleState 363 364 if sseq < ms.state.FirstSeq { 365 sseq = ms.state.FirstSeq 366 } 367 368 // If past the end no results. 369 if sseq > ms.state.LastSeq { 370 return ss 371 } 372 373 if filter == _EMPTY_ { 374 filter = fwcs 375 } 376 isAll := filter == fwcs 377 378 // First check if we can optimize this part. 379 // This means we want all and the starting sequence was before this block. 380 if isAll && sseq <= ms.state.FirstSeq { 381 total := ms.state.Msgs 382 if lastPerSubject { 383 total = uint64(ms.fss.Size()) 384 } 385 return SimpleState{ 386 Msgs: total, 387 First: ms.state.FirstSeq, 388 Last: ms.state.LastSeq, 389 } 390 } 391 392 tsa := [32]string{} 393 fsa := [32]string{} 394 fts := tokenizeSubjectIntoSlice(fsa[:0], filter) 395 wc := subjectHasWildcard(filter) 396 397 // 1. See if we match any subs from fss. 398 // 2. If we match and the sseq is past ss.Last then we can use meta only. 399 // 3. If we match we need to do a partial, break and clear any totals and do a full scan like num pending. 400 401 isMatch := func(subj string) bool { 402 if isAll { 403 return true 404 } 405 if !wc { 406 return subj == filter 407 } 408 tts := tokenizeSubjectIntoSlice(tsa[:0], subj) 409 return isSubsetMatchTokenized(tts, fts) 410 } 411 412 update := func(fss *SimpleState) { 413 msgs, first, last := fss.Msgs, fss.First, fss.Last 414 if lastPerSubject { 415 msgs, first = 1, last 416 } 417 ss.Msgs += msgs 418 if ss.First == 0 || first < ss.First { 419 ss.First = first 420 } 421 if last > ss.Last { 422 ss.Last = last 423 } 424 } 425 426 var havePartial bool 427 // We will track start and end sequences as we go. 428 ms.fss.Match(stringToBytes(filter), func(subj []byte, fss *SimpleState) { 429 subjs := bytesToString(subj) 430 if fss.firstNeedsUpdate { 431 ms.recalculateFirstForSubj(subjs, fss.First, fss) 432 } 433 if sseq <= fss.First { 434 update(fss) 435 } else if sseq <= fss.Last { 436 // We matched but it is a partial. 437 havePartial = true 438 // Don't break here, we will update to keep tracking last. 439 update(fss) 440 } 441 }) 442 443 // If we did not encounter any partials we can return here. 444 if !havePartial { 445 return ss 446 } 447 448 // If we are here we need to scan the msgs. 449 // Capture first and last sequences for scan and then clear what we had. 450 first, last := ss.First, ss.Last 451 // To track if we decide to exclude we need to calculate first. 452 var needScanFirst bool 453 if first < sseq { 454 first = sseq 455 needScanFirst = true 456 } 457 458 // Now we want to check if it is better to scan inclusive and recalculate that way 459 // or leave and scan exclusive and adjust our totals. 460 // ss.Last is always correct here. 461 toScan, toExclude := last-first, first-ms.state.FirstSeq+ms.state.LastSeq-ss.Last 462 var seen map[string]bool 463 if lastPerSubject { 464 seen = make(map[string]bool) 465 } 466 if toScan < toExclude { 467 ss.Msgs, ss.First = 0, 0 468 for seq := first; seq <= last; seq++ { 469 if sm, ok := ms.msgs[seq]; ok && !seen[sm.subj] && isMatch(sm.subj) { 470 ss.Msgs++ 471 if ss.First == 0 { 472 ss.First = seq 473 } 474 if seen != nil { 475 seen[sm.subj] = true 476 } 477 } 478 } 479 } else { 480 // We will adjust from the totals above by scanning what we need to exclude. 481 ss.First = first 482 var adjust uint64 483 var tss *SimpleState 484 485 for seq := ms.state.FirstSeq; seq < first; seq++ { 486 if sm, ok := ms.msgs[seq]; ok && !seen[sm.subj] && isMatch(sm.subj) { 487 if lastPerSubject { 488 tss, _ = ms.fss.Find(stringToBytes(sm.subj)) 489 } 490 // If we are last per subject, make sure to only adjust if all messages are before our first. 491 if tss == nil || tss.Last < first { 492 adjust++ 493 } 494 if seen != nil { 495 seen[sm.subj] = true 496 } 497 } 498 } 499 // Now do range at end. 500 for seq := last + 1; seq < ms.state.LastSeq; seq++ { 501 if sm, ok := ms.msgs[seq]; ok && !seen[sm.subj] && isMatch(sm.subj) { 502 adjust++ 503 if seen != nil { 504 seen[sm.subj] = true 505 } 506 } 507 } 508 ss.Msgs -= adjust 509 if needScanFirst { 510 for seq := first; seq < last; seq++ { 511 if sm, ok := ms.msgs[seq]; ok && isMatch(sm.subj) { 512 ss.First = seq 513 break 514 } 515 } 516 } 517 } 518 519 return ss 520 } 521 522 // SubjectsState returns a map of SimpleState for all matching subjects. 523 func (ms *memStore) SubjectsState(subject string) map[string]SimpleState { 524 ms.mu.RLock() 525 defer ms.mu.RUnlock() 526 527 if ms.fss.Size() == 0 { 528 return nil 529 } 530 531 if subject == _EMPTY_ { 532 subject = fwcs 533 } 534 535 fss := make(map[string]SimpleState) 536 ms.fss.Match(stringToBytes(subject), func(subj []byte, ss *SimpleState) { 537 subjs := string(subj) 538 if ss.firstNeedsUpdate { 539 ms.recalculateFirstForSubj(subjs, ss.First, ss) 540 } 541 oss := fss[subjs] 542 if oss.First == 0 { // New 543 fss[subjs] = *ss 544 } else { 545 // Merge here. 546 oss.Last, oss.Msgs = ss.Last, oss.Msgs+ss.Msgs 547 fss[subjs] = oss 548 } 549 }) 550 return fss 551 } 552 553 func (ms *memStore) MultiLastSeqs(filters []string, maxSeq uint64, maxAllowed int) ([]uint64, error) { 554 ms.mu.RLock() 555 defer ms.mu.RUnlock() 556 557 if len(ms.msgs) == 0 { 558 return nil, nil 559 } 560 561 // Implied last sequence. 562 if maxSeq == 0 { 563 maxSeq = ms.state.LastSeq 564 } 565 566 //subs := make(map[string]*SimpleState) 567 seqs := make([]uint64, 0, 64) 568 seen := make(map[uint64]struct{}) 569 570 addIfNotDupe := func(seq uint64) { 571 if _, ok := seen[seq]; !ok { 572 seqs = append(seqs, seq) 573 seen[seq] = struct{}{} 574 } 575 } 576 577 for _, filter := range filters { 578 ms.fss.Match(stringToBytes(filter), func(subj []byte, ss *SimpleState) { 579 if ss.Last <= maxSeq { 580 addIfNotDupe(ss.Last) 581 } else if ss.Msgs > 1 { 582 // The last is greater than maxSeq. 583 s := bytesToString(subj) 584 for seq := maxSeq; seq > 0; seq-- { 585 if sm, ok := ms.msgs[seq]; ok && sm.subj == s { 586 addIfNotDupe(seq) 587 break 588 } 589 } 590 } 591 }) 592 // If maxAllowed was sepcified check that we will not exceed that. 593 if maxAllowed > 0 && len(seqs) > maxAllowed { 594 return nil, ErrTooManyResults 595 } 596 } 597 sort.Slice(seqs, func(i, j int) bool { return seqs[i] < seqs[j] }) 598 return seqs, nil 599 } 600 601 // SubjectsTotal return message totals per subject. 602 func (ms *memStore) SubjectsTotals(filterSubject string) map[string]uint64 { 603 ms.mu.RLock() 604 defer ms.mu.RUnlock() 605 606 if ms.fss.Size() == 0 { 607 return nil 608 } 609 610 tsa := [32]string{} 611 fsa := [32]string{} 612 fts := tokenizeSubjectIntoSlice(fsa[:0], filterSubject) 613 isAll := filterSubject == _EMPTY_ || filterSubject == fwcs 614 615 fst := make(map[string]uint64) 616 ms.fss.Match(stringToBytes(filterSubject), func(subj []byte, ss *SimpleState) { 617 subjs := string(subj) 618 if isAll { 619 fst[subjs] = ss.Msgs 620 } else { 621 if tts := tokenizeSubjectIntoSlice(tsa[:0], subjs); isSubsetMatchTokenized(tts, fts) { 622 fst[subjs] = ss.Msgs 623 } 624 } 625 }) 626 return fst 627 } 628 629 // NumPending will return the number of pending messages matching the filter subject starting at sequence. 630 func (ms *memStore) NumPending(sseq uint64, filter string, lastPerSubject bool) (total, validThrough uint64) { 631 // This needs to be a write lock, as filteredStateLocked can mutate the per-subject state. 632 ms.mu.Lock() 633 defer ms.mu.Unlock() 634 635 ss := ms.filteredStateLocked(sseq, filter, lastPerSubject) 636 return ss.Msgs, ms.state.LastSeq 637 } 638 639 // Will check the msg limit for this tracked subject. 640 // Lock should be held. 641 func (ms *memStore) enforcePerSubjectLimit(subj string, ss *SimpleState) { 642 if ms.maxp <= 0 { 643 return 644 } 645 for nmsgs := ss.Msgs; nmsgs > uint64(ms.maxp); nmsgs = ss.Msgs { 646 if ss.firstNeedsUpdate { 647 ms.recalculateFirstForSubj(subj, ss.First, ss) 648 } 649 if !ms.removeMsg(ss.First, false) { 650 break 651 } 652 } 653 } 654 655 // Will check the msg limit and drop firstSeq msg if needed. 656 // Lock should be held. 657 func (ms *memStore) enforceMsgLimit() { 658 if ms.cfg.Discard != DiscardOld { 659 return 660 } 661 if ms.cfg.MaxMsgs <= 0 || ms.state.Msgs <= uint64(ms.cfg.MaxMsgs) { 662 return 663 } 664 for nmsgs := ms.state.Msgs; nmsgs > uint64(ms.cfg.MaxMsgs); nmsgs = ms.state.Msgs { 665 ms.deleteFirstMsgOrPanic() 666 } 667 } 668 669 // Will check the bytes limit and drop msgs if needed. 670 // Lock should be held. 671 func (ms *memStore) enforceBytesLimit() { 672 if ms.cfg.Discard != DiscardOld { 673 return 674 } 675 if ms.cfg.MaxBytes <= 0 || ms.state.Bytes <= uint64(ms.cfg.MaxBytes) { 676 return 677 } 678 for bs := ms.state.Bytes; bs > uint64(ms.cfg.MaxBytes); bs = ms.state.Bytes { 679 ms.deleteFirstMsgOrPanic() 680 } 681 } 682 683 // Will start the age check timer. 684 // Lock should be held. 685 func (ms *memStore) startAgeChk() { 686 if ms.ageChk == nil && ms.cfg.MaxAge != 0 { 687 ms.ageChk = time.AfterFunc(ms.cfg.MaxAge, ms.expireMsgs) 688 } 689 } 690 691 // Lock should be held. 692 func (ms *memStore) resetAgeChk(delta int64) { 693 if ms.cfg.MaxAge == 0 { 694 return 695 } 696 697 fireIn := ms.cfg.MaxAge 698 if delta > 0 && time.Duration(delta) < fireIn { 699 if fireIn = time.Duration(delta); fireIn < 250*time.Millisecond { 700 // Only fire at most once every 250ms. 701 // Excessive firing can effect ingest performance. 702 fireIn = time.Second 703 } 704 } 705 if ms.ageChk != nil { 706 ms.ageChk.Reset(fireIn) 707 } else { 708 ms.ageChk = time.AfterFunc(fireIn, ms.expireMsgs) 709 } 710 } 711 712 // Will expire msgs that are too old. 713 func (ms *memStore) expireMsgs() { 714 ms.mu.RLock() 715 now := time.Now().UnixNano() 716 minAge := now - int64(ms.cfg.MaxAge) 717 ms.mu.RUnlock() 718 719 for { 720 ms.mu.Lock() 721 if sm, ok := ms.msgs[ms.state.FirstSeq]; ok && sm.ts <= minAge { 722 ms.deleteFirstMsgOrPanic() 723 // Recalculate in case we are expiring a bunch. 724 now = time.Now().UnixNano() 725 minAge = now - int64(ms.cfg.MaxAge) 726 ms.mu.Unlock() 727 } else { 728 // We will exit here 729 if len(ms.msgs) == 0 { 730 if ms.ageChk != nil { 731 ms.ageChk.Stop() 732 ms.ageChk = nil 733 } 734 } else { 735 var fireIn time.Duration 736 if sm == nil { 737 fireIn = ms.cfg.MaxAge 738 } else { 739 fireIn = time.Duration(sm.ts - minAge) 740 } 741 if ms.ageChk != nil { 742 ms.ageChk.Reset(fireIn) 743 } else { 744 ms.ageChk = time.AfterFunc(fireIn, ms.expireMsgs) 745 } 746 } 747 ms.mu.Unlock() 748 break 749 } 750 } 751 } 752 753 // PurgeEx will remove messages based on subject filters, sequence and number of messages to keep. 754 // Will return the number of purged messages. 755 func (ms *memStore) PurgeEx(subject string, sequence, keep uint64) (purged uint64, err error) { 756 if subject == _EMPTY_ || subject == fwcs { 757 if keep == 0 && sequence == 0 { 758 return ms.Purge() 759 } 760 if sequence > 1 { 761 return ms.Compact(sequence) 762 } else if keep > 0 { 763 ms.mu.RLock() 764 msgs, lseq := ms.state.Msgs, ms.state.LastSeq 765 ms.mu.RUnlock() 766 if keep >= msgs { 767 return 0, nil 768 } 769 return ms.Compact(lseq - keep + 1) 770 } 771 return 0, nil 772 773 } 774 eq := compareFn(subject) 775 if ss := ms.FilteredState(1, subject); ss.Msgs > 0 { 776 if keep > 0 { 777 if keep >= ss.Msgs { 778 return 0, nil 779 } 780 ss.Msgs -= keep 781 } 782 last := ss.Last 783 if sequence > 1 { 784 last = sequence - 1 785 } 786 ms.mu.Lock() 787 for seq := ss.First; seq <= last; seq++ { 788 if sm, ok := ms.msgs[seq]; ok && eq(sm.subj, subject) { 789 if ok := ms.removeMsg(sm.seq, false); ok { 790 purged++ 791 if purged >= ss.Msgs { 792 break 793 } 794 } 795 } 796 } 797 ms.mu.Unlock() 798 } 799 return purged, nil 800 } 801 802 // Purge will remove all messages from this store. 803 // Will return the number of purged messages. 804 func (ms *memStore) Purge() (uint64, error) { 805 ms.mu.RLock() 806 first := ms.state.LastSeq + 1 807 ms.mu.RUnlock() 808 return ms.purge(first) 809 } 810 811 func (ms *memStore) purge(fseq uint64) (uint64, error) { 812 ms.mu.Lock() 813 purged := uint64(len(ms.msgs)) 814 cb := ms.scb 815 bytes := int64(ms.state.Bytes) 816 if fseq < ms.state.LastSeq { 817 ms.mu.Unlock() 818 return 0, fmt.Errorf("partial purges not supported on memory store") 819 } 820 ms.state.FirstSeq = fseq 821 ms.state.LastSeq = fseq - 1 822 ms.state.FirstTime = time.Time{} 823 ms.state.Bytes = 0 824 ms.state.Msgs = 0 825 ms.msgs = make(map[uint64]*StoreMsg) 826 ms.fss = stree.NewSubjectTree[SimpleState]() 827 ms.mu.Unlock() 828 829 if cb != nil { 830 cb(-int64(purged), -bytes, 0, _EMPTY_) 831 } 832 833 return purged, nil 834 } 835 836 // Compact will remove all messages from this store up to 837 // but not including the seq parameter. 838 // Will return the number of purged messages. 839 func (ms *memStore) Compact(seq uint64) (uint64, error) { 840 if seq == 0 { 841 return ms.Purge() 842 } 843 844 var purged, bytes uint64 845 846 ms.mu.Lock() 847 cb := ms.scb 848 if seq <= ms.state.LastSeq { 849 fseq := ms.state.FirstSeq 850 // Determine new first sequence. 851 for ; seq <= ms.state.LastSeq; seq++ { 852 if sm, ok := ms.msgs[seq]; ok { 853 ms.state.FirstSeq = seq 854 ms.state.FirstTime = time.Unix(0, sm.ts).UTC() 855 break 856 } 857 } 858 for seq := seq - 1; seq >= fseq; seq-- { 859 if sm := ms.msgs[seq]; sm != nil { 860 bytes += memStoreMsgSize(sm.subj, sm.hdr, sm.msg) 861 purged++ 862 delete(ms.msgs, seq) 863 ms.removeSeqPerSubject(sm.subj, seq) 864 } 865 } 866 if purged > ms.state.Msgs { 867 purged = ms.state.Msgs 868 } 869 ms.state.Msgs -= purged 870 if bytes > ms.state.Bytes { 871 bytes = ms.state.Bytes 872 } 873 ms.state.Bytes -= bytes 874 } else { 875 // We are compacting past the end of our range. Do purge and set sequences correctly 876 // such that the next message placed will have seq. 877 purged = uint64(len(ms.msgs)) 878 bytes = ms.state.Bytes 879 ms.state.Bytes = 0 880 ms.state.Msgs = 0 881 ms.state.FirstSeq = seq 882 ms.state.FirstTime = time.Time{} 883 ms.state.LastSeq = seq - 1 884 ms.msgs = make(map[uint64]*StoreMsg) 885 } 886 ms.mu.Unlock() 887 888 if cb != nil { 889 cb(-int64(purged), -int64(bytes), 0, _EMPTY_) 890 } 891 892 return purged, nil 893 } 894 895 // Will completely reset our store. 896 func (ms *memStore) reset() error { 897 898 ms.mu.Lock() 899 var purged, bytes uint64 900 cb := ms.scb 901 if cb != nil { 902 for _, sm := range ms.msgs { 903 purged++ 904 bytes += memStoreMsgSize(sm.subj, sm.hdr, sm.msg) 905 } 906 } 907 908 // Reset 909 ms.state.FirstSeq = 0 910 ms.state.FirstTime = time.Time{} 911 ms.state.LastSeq = 0 912 ms.state.LastTime = time.Now().UTC() 913 // Update msgs and bytes. 914 ms.state.Msgs = 0 915 ms.state.Bytes = 0 916 // Reset msgs and fss. 917 ms.msgs = make(map[uint64]*StoreMsg) 918 ms.fss = stree.NewSubjectTree[SimpleState]() 919 920 ms.mu.Unlock() 921 922 if cb != nil { 923 cb(-int64(purged), -int64(bytes), 0, _EMPTY_) 924 } 925 926 return nil 927 } 928 929 // Truncate will truncate a stream store up to seq. Sequence needs to be valid. 930 func (ms *memStore) Truncate(seq uint64) error { 931 // Check for request to reset. 932 if seq == 0 { 933 return ms.reset() 934 } 935 936 var purged, bytes uint64 937 938 ms.mu.Lock() 939 lsm, ok := ms.msgs[seq] 940 if !ok { 941 ms.mu.Unlock() 942 return ErrInvalidSequence 943 } 944 945 for i := ms.state.LastSeq; i > seq; i-- { 946 if sm := ms.msgs[i]; sm != nil { 947 purged++ 948 bytes += memStoreMsgSize(sm.subj, sm.hdr, sm.msg) 949 delete(ms.msgs, i) 950 ms.removeSeqPerSubject(sm.subj, i) 951 } 952 } 953 // Reset last. 954 ms.state.LastSeq = lsm.seq 955 ms.state.LastTime = time.Unix(0, lsm.ts).UTC() 956 // Update msgs and bytes. 957 if purged > ms.state.Msgs { 958 purged = ms.state.Msgs 959 } 960 ms.state.Msgs -= purged 961 if bytes > ms.state.Bytes { 962 bytes = ms.state.Bytes 963 } 964 ms.state.Bytes -= bytes 965 966 cb := ms.scb 967 ms.mu.Unlock() 968 969 if cb != nil { 970 cb(-int64(purged), -int64(bytes), 0, _EMPTY_) 971 } 972 973 return nil 974 } 975 976 func (ms *memStore) deleteFirstMsgOrPanic() { 977 if !ms.deleteFirstMsg() { 978 panic("jetstream memstore has inconsistent state, can't find first seq msg") 979 } 980 } 981 982 func (ms *memStore) deleteFirstMsg() bool { 983 return ms.removeMsg(ms.state.FirstSeq, false) 984 } 985 986 // LoadMsg will lookup the message by sequence number and return it if found. 987 func (ms *memStore) LoadMsg(seq uint64, smp *StoreMsg) (*StoreMsg, error) { 988 ms.mu.RLock() 989 sm, ok := ms.msgs[seq] 990 last := ms.state.LastSeq 991 ms.mu.RUnlock() 992 993 if !ok || sm == nil { 994 var err = ErrStoreEOF 995 if seq <= last { 996 err = ErrStoreMsgNotFound 997 } 998 return nil, err 999 } 1000 1001 if smp == nil { 1002 smp = new(StoreMsg) 1003 } 1004 sm.copy(smp) 1005 return smp, nil 1006 } 1007 1008 // LoadLastMsg will return the last message we have that matches a given subject. 1009 // The subject can be a wildcard. 1010 func (ms *memStore) LoadLastMsg(subject string, smp *StoreMsg) (*StoreMsg, error) { 1011 var sm *StoreMsg 1012 var ok bool 1013 1014 // This needs to be a write lock, as filteredStateLocked can 1015 // mutate the per-subject state. 1016 ms.mu.Lock() 1017 defer ms.mu.Unlock() 1018 1019 if subject == _EMPTY_ || subject == fwcs { 1020 sm, ok = ms.msgs[ms.state.LastSeq] 1021 } else if subjectIsLiteral(subject) { 1022 var ss *SimpleState 1023 if ss, ok = ms.fss.Find(stringToBytes(subject)); ok && ss.Msgs > 0 { 1024 sm, ok = ms.msgs[ss.Last] 1025 } 1026 } else if ss := ms.filteredStateLocked(1, subject, true); ss.Msgs > 0 { 1027 sm, ok = ms.msgs[ss.Last] 1028 } 1029 if !ok || sm == nil { 1030 return nil, ErrStoreMsgNotFound 1031 } 1032 1033 if smp == nil { 1034 smp = new(StoreMsg) 1035 } 1036 sm.copy(smp) 1037 return smp, nil 1038 } 1039 1040 // LoadNextMsgMulti will find the next message matching any entry in the sublist. 1041 func (ms *memStore) LoadNextMsgMulti(sl *Sublist, start uint64, smp *StoreMsg) (sm *StoreMsg, skip uint64, err error) { 1042 // TODO(dlc) - for now simple linear walk to get started. 1043 ms.mu.RLock() 1044 defer ms.mu.RUnlock() 1045 1046 if start < ms.state.FirstSeq { 1047 start = ms.state.FirstSeq 1048 } 1049 1050 // If past the end no results. 1051 if start > ms.state.LastSeq || ms.state.Msgs == 0 { 1052 return nil, ms.state.LastSeq, ErrStoreEOF 1053 } 1054 1055 // Initial setup. 1056 fseq, lseq := start, ms.state.LastSeq 1057 1058 var result SublistResult 1059 for nseq := fseq; nseq <= lseq; nseq++ { 1060 sm, ok := ms.msgs[nseq] 1061 if !ok { 1062 continue 1063 } 1064 if r := sl.MatchWithResult(sm.subj, &result); len(r.psubs) > 0 { 1065 if smp == nil { 1066 smp = new(StoreMsg) 1067 } 1068 sm.copy(smp) 1069 return smp, nseq, nil 1070 } 1071 } 1072 return nil, ms.state.LastSeq, ErrStoreEOF 1073 } 1074 1075 // LoadNextMsg will find the next message matching the filter subject starting at the start sequence. 1076 // The filter subject can be a wildcard. 1077 func (ms *memStore) LoadNextMsg(filter string, wc bool, start uint64, smp *StoreMsg) (*StoreMsg, uint64, error) { 1078 ms.mu.Lock() 1079 defer ms.mu.Unlock() 1080 1081 if start < ms.state.FirstSeq { 1082 start = ms.state.FirstSeq 1083 } 1084 1085 // If past the end no results. 1086 if start > ms.state.LastSeq || ms.state.Msgs == 0 { 1087 return nil, ms.state.LastSeq, ErrStoreEOF 1088 } 1089 1090 if filter == _EMPTY_ { 1091 filter = fwcs 1092 } 1093 isAll := filter == fwcs 1094 1095 // Skip scan of ms.fss if number of messages in the block are less than 1096 // 1/2 the number of subjects in ms.fss. Or we have a wc and lots of fss entries. 1097 const linearScanMaxFSS = 256 1098 doLinearScan := isAll || 2*int(ms.state.LastSeq-start) < ms.fss.Size() || (wc && ms.fss.Size() > linearScanMaxFSS) 1099 1100 // Initial setup. 1101 fseq, lseq := start, ms.state.LastSeq 1102 1103 if !doLinearScan { 1104 subs := []string{filter} 1105 if wc || isAll { 1106 subs = subs[:0] 1107 ms.fss.Match(stringToBytes(filter), func(subj []byte, val *SimpleState) { 1108 subs = append(subs, string(subj)) 1109 }) 1110 } 1111 fseq, lseq = ms.state.LastSeq, uint64(0) 1112 for _, subj := range subs { 1113 ss, ok := ms.fss.Find(stringToBytes(subj)) 1114 if !ok { 1115 continue 1116 } 1117 if ss.firstNeedsUpdate { 1118 ms.recalculateFirstForSubj(subj, ss.First, ss) 1119 } 1120 if ss.First < fseq { 1121 fseq = ss.First 1122 } 1123 if ss.Last > lseq { 1124 lseq = ss.Last 1125 } 1126 } 1127 if fseq < start { 1128 fseq = start 1129 } 1130 } 1131 1132 eq := subjectsEqual 1133 if wc { 1134 eq = subjectIsSubsetMatch 1135 } 1136 1137 for nseq := fseq; nseq <= lseq; nseq++ { 1138 if sm, ok := ms.msgs[nseq]; ok && (isAll || eq(sm.subj, filter)) { 1139 if smp == nil { 1140 smp = new(StoreMsg) 1141 } 1142 sm.copy(smp) 1143 return smp, nseq, nil 1144 } 1145 } 1146 return nil, ms.state.LastSeq, ErrStoreEOF 1147 } 1148 1149 // RemoveMsg will remove the message from this store. 1150 // Will return the number of bytes removed. 1151 func (ms *memStore) RemoveMsg(seq uint64) (bool, error) { 1152 ms.mu.Lock() 1153 removed := ms.removeMsg(seq, false) 1154 ms.mu.Unlock() 1155 return removed, nil 1156 } 1157 1158 // EraseMsg will remove the message and rewrite its contents. 1159 func (ms *memStore) EraseMsg(seq uint64) (bool, error) { 1160 ms.mu.Lock() 1161 removed := ms.removeMsg(seq, true) 1162 ms.mu.Unlock() 1163 return removed, nil 1164 } 1165 1166 // Performs logic to update first sequence number. 1167 // Lock should be held. 1168 func (ms *memStore) updateFirstSeq(seq uint64) { 1169 if seq != ms.state.FirstSeq { 1170 // Interior delete. 1171 return 1172 } 1173 var nsm *StoreMsg 1174 var ok bool 1175 for nseq := ms.state.FirstSeq + 1; nseq <= ms.state.LastSeq; nseq++ { 1176 if nsm, ok = ms.msgs[nseq]; ok { 1177 break 1178 } 1179 } 1180 oldFirst := ms.state.FirstSeq 1181 if nsm != nil { 1182 ms.state.FirstSeq = nsm.seq 1183 ms.state.FirstTime = time.Unix(0, nsm.ts).UTC() 1184 } else { 1185 // Like purge. 1186 ms.state.FirstSeq = ms.state.LastSeq + 1 1187 ms.state.FirstTime = time.Time{} 1188 } 1189 1190 if oldFirst == ms.state.FirstSeq-1 { 1191 ms.dmap.Delete(oldFirst) 1192 } else { 1193 for seq := oldFirst; seq < ms.state.FirstSeq; seq++ { 1194 ms.dmap.Delete(seq) 1195 } 1196 } 1197 } 1198 1199 // Remove a seq from the fss and select new first. 1200 // Lock should be held. 1201 func (ms *memStore) removeSeqPerSubject(subj string, seq uint64) { 1202 ss, ok := ms.fss.Find(stringToBytes(subj)) 1203 if !ok { 1204 return 1205 } 1206 if ss.Msgs == 1 { 1207 ms.fss.Delete(stringToBytes(subj)) 1208 return 1209 } 1210 ss.Msgs-- 1211 1212 // If we know we only have 1 msg left don't need to search for next first. 1213 if ss.Msgs == 1 { 1214 if seq == ss.Last { 1215 ss.Last = ss.First 1216 } else { 1217 ss.First = ss.Last 1218 } 1219 ss.firstNeedsUpdate = false 1220 } else { 1221 ss.firstNeedsUpdate = seq == ss.First || ss.firstNeedsUpdate 1222 } 1223 } 1224 1225 // Will recalculate the first sequence for this subject in this block. 1226 // Lock should be held. 1227 func (ms *memStore) recalculateFirstForSubj(subj string, startSeq uint64, ss *SimpleState) { 1228 for tseq := startSeq + 1; tseq <= ss.Last; tseq++ { 1229 if sm := ms.msgs[tseq]; sm != nil && sm.subj == subj { 1230 ss.First = tseq 1231 ss.firstNeedsUpdate = false 1232 return 1233 } 1234 } 1235 } 1236 1237 // Removes the message referenced by seq. 1238 // Lock should be held. 1239 func (ms *memStore) removeMsg(seq uint64, secure bool) bool { 1240 var ss uint64 1241 sm, ok := ms.msgs[seq] 1242 if !ok { 1243 return false 1244 } 1245 1246 ss = memStoreMsgSize(sm.subj, sm.hdr, sm.msg) 1247 1248 delete(ms.msgs, seq) 1249 if ms.state.Msgs > 0 { 1250 ms.state.Msgs-- 1251 if ss > ms.state.Bytes { 1252 ss = ms.state.Bytes 1253 } 1254 ms.state.Bytes -= ss 1255 } 1256 ms.dmap.Insert(seq) 1257 ms.updateFirstSeq(seq) 1258 1259 if secure { 1260 if len(sm.hdr) > 0 { 1261 sm.hdr = make([]byte, len(sm.hdr)) 1262 crand.Read(sm.hdr) 1263 } 1264 if len(sm.msg) > 0 { 1265 sm.msg = make([]byte, len(sm.msg)) 1266 crand.Read(sm.msg) 1267 } 1268 sm.seq, sm.ts = 0, 0 1269 } 1270 1271 // Remove any per subject tracking. 1272 ms.removeSeqPerSubject(sm.subj, seq) 1273 1274 if ms.scb != nil { 1275 // We do not want to hold any locks here. 1276 ms.mu.Unlock() 1277 delta := int64(ss) 1278 ms.scb(-1, -delta, seq, sm.subj) 1279 ms.mu.Lock() 1280 } 1281 1282 return ok 1283 } 1284 1285 // Type returns the type of the underlying store. 1286 func (ms *memStore) Type() StorageType { 1287 return MemoryStorage 1288 } 1289 1290 // FastState will fill in state with only the following. 1291 // Msgs, Bytes, First and Last Sequence and Time and NumDeleted. 1292 func (ms *memStore) FastState(state *StreamState) { 1293 ms.mu.RLock() 1294 state.Msgs = ms.state.Msgs 1295 state.Bytes = ms.state.Bytes 1296 state.FirstSeq = ms.state.FirstSeq 1297 state.FirstTime = ms.state.FirstTime 1298 state.LastSeq = ms.state.LastSeq 1299 state.LastTime = ms.state.LastTime 1300 if state.LastSeq > state.FirstSeq { 1301 state.NumDeleted = int((state.LastSeq - state.FirstSeq + 1) - state.Msgs) 1302 if state.NumDeleted < 0 { 1303 state.NumDeleted = 0 1304 } 1305 } 1306 state.Consumers = ms.consumers 1307 state.NumSubjects = ms.fss.Size() 1308 ms.mu.RUnlock() 1309 } 1310 1311 func (ms *memStore) State() StreamState { 1312 ms.mu.RLock() 1313 defer ms.mu.RUnlock() 1314 1315 state := ms.state 1316 state.Consumers = ms.consumers 1317 state.NumSubjects = ms.fss.Size() 1318 state.Deleted = nil 1319 1320 // Calculate interior delete details. 1321 if numDeleted := int((state.LastSeq - state.FirstSeq + 1) - state.Msgs); numDeleted > 0 { 1322 state.Deleted = make([]uint64, 0, numDeleted) 1323 fseq, lseq := state.FirstSeq, state.LastSeq 1324 ms.dmap.Range(func(seq uint64) bool { 1325 if seq < fseq || seq > lseq { 1326 ms.dmap.Delete(seq) 1327 } else { 1328 state.Deleted = append(state.Deleted, seq) 1329 } 1330 return true 1331 }) 1332 } 1333 if len(state.Deleted) > 0 { 1334 state.NumDeleted = len(state.Deleted) 1335 } 1336 1337 return state 1338 } 1339 1340 func (ms *memStore) Utilization() (total, reported uint64, err error) { 1341 ms.mu.RLock() 1342 defer ms.mu.RUnlock() 1343 return ms.state.Bytes, ms.state.Bytes, nil 1344 } 1345 1346 func memStoreMsgSize(subj string, hdr, msg []byte) uint64 { 1347 return uint64(len(subj) + len(hdr) + len(msg) + 16) // 8*2 for seq + age 1348 } 1349 1350 // Delete is same as Stop for memory store. 1351 func (ms *memStore) Delete() error { 1352 return ms.Stop() 1353 } 1354 1355 func (ms *memStore) Stop() error { 1356 // These can't come back, so stop is same as Delete. 1357 ms.Purge() 1358 ms.mu.Lock() 1359 if ms.ageChk != nil { 1360 ms.ageChk.Stop() 1361 ms.ageChk = nil 1362 } 1363 ms.msgs = nil 1364 ms.mu.Unlock() 1365 return nil 1366 } 1367 1368 func (ms *memStore) isClosed() bool { 1369 ms.mu.RLock() 1370 defer ms.mu.RUnlock() 1371 return ms.msgs == nil 1372 } 1373 1374 type consumerMemStore struct { 1375 mu sync.Mutex 1376 ms StreamStore 1377 cfg ConsumerConfig 1378 state ConsumerState 1379 closed bool 1380 } 1381 1382 func (ms *memStore) ConsumerStore(name string, cfg *ConsumerConfig) (ConsumerStore, error) { 1383 if ms == nil { 1384 return nil, fmt.Errorf("memstore is nil") 1385 } 1386 if ms.isClosed() { 1387 return nil, ErrStoreClosed 1388 } 1389 if cfg == nil || name == _EMPTY_ { 1390 return nil, fmt.Errorf("bad consumer config") 1391 } 1392 o := &consumerMemStore{ms: ms, cfg: *cfg} 1393 ms.AddConsumer(o) 1394 return o, nil 1395 } 1396 1397 func (ms *memStore) AddConsumer(o ConsumerStore) error { 1398 ms.mu.Lock() 1399 ms.consumers++ 1400 ms.mu.Unlock() 1401 return nil 1402 } 1403 1404 func (ms *memStore) RemoveConsumer(o ConsumerStore) error { 1405 ms.mu.Lock() 1406 if ms.consumers > 0 { 1407 ms.consumers-- 1408 } 1409 ms.mu.Unlock() 1410 return nil 1411 } 1412 1413 func (ms *memStore) Snapshot(_ time.Duration, _, _ bool) (*SnapshotResult, error) { 1414 return nil, fmt.Errorf("no impl") 1415 } 1416 1417 // Binary encoded state snapshot, >= v2.10 server. 1418 func (ms *memStore) EncodedStreamState(failed uint64) ([]byte, error) { 1419 ms.mu.RLock() 1420 defer ms.mu.RUnlock() 1421 1422 // Quick calculate num deleted. 1423 numDeleted := int((ms.state.LastSeq - ms.state.FirstSeq + 1) - ms.state.Msgs) 1424 if numDeleted < 0 { 1425 numDeleted = 0 1426 } 1427 1428 // Encoded is Msgs, Bytes, FirstSeq, LastSeq, Failed, NumDeleted and optional DeletedBlocks 1429 var buf [1024]byte 1430 buf[0], buf[1] = streamStateMagic, streamStateVersion 1431 n := hdrLen 1432 n += binary.PutUvarint(buf[n:], ms.state.Msgs) 1433 n += binary.PutUvarint(buf[n:], ms.state.Bytes) 1434 n += binary.PutUvarint(buf[n:], ms.state.FirstSeq) 1435 n += binary.PutUvarint(buf[n:], ms.state.LastSeq) 1436 n += binary.PutUvarint(buf[n:], failed) 1437 n += binary.PutUvarint(buf[n:], uint64(numDeleted)) 1438 1439 b := buf[0:n] 1440 1441 if numDeleted > 0 { 1442 buf, err := ms.dmap.Encode(nil) 1443 if err != nil { 1444 return nil, err 1445 } 1446 b = append(b, buf...) 1447 } 1448 1449 return b, nil 1450 } 1451 1452 // SyncDeleted will make sure this stream has same deleted state as dbs. 1453 func (ms *memStore) SyncDeleted(dbs DeleteBlocks) { 1454 // For now we share one dmap, so if we have one entry here check if states are the same. 1455 // Note this will work for any DeleteBlock type, but we expect this to be a dmap too. 1456 if len(dbs) == 1 { 1457 ms.mu.RLock() 1458 min, max, num := ms.dmap.State() 1459 ms.mu.RUnlock() 1460 if pmin, pmax, pnum := dbs[0].State(); pmin == min && pmax == max && pnum == num { 1461 return 1462 } 1463 } 1464 for _, db := range dbs { 1465 db.Range(func(dseq uint64) bool { 1466 ms.RemoveMsg(dseq) 1467 return true 1468 }) 1469 } 1470 } 1471 1472 func (o *consumerMemStore) Update(state *ConsumerState) error { 1473 // Sanity checks. 1474 if state.AckFloor.Consumer > state.Delivered.Consumer { 1475 return fmt.Errorf("bad ack floor for consumer") 1476 } 1477 if state.AckFloor.Stream > state.Delivered.Stream { 1478 return fmt.Errorf("bad ack floor for stream") 1479 } 1480 1481 // Copy to our state. 1482 var pending map[uint64]*Pending 1483 var redelivered map[uint64]uint64 1484 if len(state.Pending) > 0 { 1485 pending = make(map[uint64]*Pending, len(state.Pending)) 1486 for seq, p := range state.Pending { 1487 pending[seq] = &Pending{p.Sequence, p.Timestamp} 1488 } 1489 for seq := range pending { 1490 if seq <= state.AckFloor.Stream || seq > state.Delivered.Stream { 1491 return fmt.Errorf("bad pending entry, sequence [%d] out of range", seq) 1492 } 1493 } 1494 } 1495 if len(state.Redelivered) > 0 { 1496 redelivered = make(map[uint64]uint64, len(state.Redelivered)) 1497 for seq, dc := range state.Redelivered { 1498 redelivered[seq] = dc 1499 } 1500 } 1501 1502 // Replace our state. 1503 o.mu.Lock() 1504 1505 // Check to see if this is an outdated update. 1506 if state.Delivered.Consumer < o.state.Delivered.Consumer { 1507 o.mu.Unlock() 1508 return fmt.Errorf("old update ignored") 1509 } 1510 1511 o.state.Delivered = state.Delivered 1512 o.state.AckFloor = state.AckFloor 1513 o.state.Pending = pending 1514 o.state.Redelivered = redelivered 1515 o.mu.Unlock() 1516 1517 return nil 1518 } 1519 1520 // SetStarting sets our starting stream sequence. 1521 func (o *consumerMemStore) SetStarting(sseq uint64) error { 1522 o.mu.Lock() 1523 o.state.Delivered.Stream = sseq 1524 o.mu.Unlock() 1525 return nil 1526 } 1527 1528 // HasState returns if this store has a recorded state. 1529 func (o *consumerMemStore) HasState() bool { 1530 return false 1531 } 1532 1533 func (o *consumerMemStore) UpdateDelivered(dseq, sseq, dc uint64, ts int64) error { 1534 o.mu.Lock() 1535 defer o.mu.Unlock() 1536 1537 if dc != 1 && o.cfg.AckPolicy == AckNone { 1538 return ErrNoAckPolicy 1539 } 1540 1541 if dseq <= o.state.AckFloor.Consumer { 1542 return nil 1543 } 1544 1545 // See if we expect an ack for this. 1546 if o.cfg.AckPolicy != AckNone { 1547 // Need to create pending records here. 1548 if o.state.Pending == nil { 1549 o.state.Pending = make(map[uint64]*Pending) 1550 } 1551 var p *Pending 1552 // Check for an update to a message already delivered. 1553 if sseq <= o.state.Delivered.Stream { 1554 if p = o.state.Pending[sseq]; p != nil { 1555 p.Sequence, p.Timestamp = dseq, ts 1556 } 1557 } else { 1558 // Add to pending. 1559 o.state.Pending[sseq] = &Pending{dseq, ts} 1560 } 1561 // Update delivered as needed. 1562 if dseq > o.state.Delivered.Consumer { 1563 o.state.Delivered.Consumer = dseq 1564 } 1565 if sseq > o.state.Delivered.Stream { 1566 o.state.Delivered.Stream = sseq 1567 } 1568 1569 if dc > 1 { 1570 if maxdc := uint64(o.cfg.MaxDeliver); maxdc > 0 && dc > maxdc { 1571 // Make sure to remove from pending. 1572 delete(o.state.Pending, sseq) 1573 } 1574 if o.state.Redelivered == nil { 1575 o.state.Redelivered = make(map[uint64]uint64) 1576 } 1577 // Only update if greater than what we already have. 1578 if o.state.Redelivered[sseq] < dc-1 { 1579 o.state.Redelivered[sseq] = dc - 1 1580 } 1581 } 1582 } else { 1583 // For AckNone just update delivered and ackfloor at the same time. 1584 if dseq > o.state.Delivered.Consumer { 1585 o.state.Delivered.Consumer = dseq 1586 o.state.AckFloor.Consumer = dseq 1587 } 1588 if sseq > o.state.Delivered.Stream { 1589 o.state.Delivered.Stream = sseq 1590 o.state.AckFloor.Stream = sseq 1591 } 1592 } 1593 1594 return nil 1595 } 1596 1597 func (o *consumerMemStore) UpdateAcks(dseq, sseq uint64) error { 1598 o.mu.Lock() 1599 defer o.mu.Unlock() 1600 1601 if o.cfg.AckPolicy == AckNone { 1602 return ErrNoAckPolicy 1603 } 1604 if len(o.state.Pending) == 0 || o.state.Pending[sseq] == nil { 1605 return ErrStoreMsgNotFound 1606 } 1607 1608 // On restarts the old leader may get a replay from the raft logs that are old. 1609 if dseq <= o.state.AckFloor.Consumer { 1610 return nil 1611 } 1612 1613 // Check for AckAll here. 1614 if o.cfg.AckPolicy == AckAll { 1615 sgap := sseq - o.state.AckFloor.Stream 1616 o.state.AckFloor.Consumer = dseq 1617 o.state.AckFloor.Stream = sseq 1618 for seq := sseq; seq > sseq-sgap; seq-- { 1619 delete(o.state.Pending, seq) 1620 if len(o.state.Redelivered) > 0 { 1621 delete(o.state.Redelivered, seq) 1622 } 1623 } 1624 return nil 1625 } 1626 1627 // AckExplicit 1628 1629 // First delete from our pending state. 1630 if p, ok := o.state.Pending[sseq]; ok { 1631 delete(o.state.Pending, sseq) 1632 dseq = p.Sequence // Use the original. 1633 } 1634 // Now remove from redelivered. 1635 if len(o.state.Redelivered) > 0 { 1636 delete(o.state.Redelivered, sseq) 1637 } 1638 1639 if len(o.state.Pending) == 0 { 1640 o.state.AckFloor.Consumer = o.state.Delivered.Consumer 1641 o.state.AckFloor.Stream = o.state.Delivered.Stream 1642 } else if dseq == o.state.AckFloor.Consumer+1 { 1643 first := o.state.AckFloor.Consumer == 0 1644 o.state.AckFloor.Consumer = dseq 1645 o.state.AckFloor.Stream = sseq 1646 1647 if !first && o.state.Delivered.Consumer > dseq { 1648 for ss := sseq + 1; ss < o.state.Delivered.Stream; ss++ { 1649 if p, ok := o.state.Pending[ss]; ok { 1650 if p.Sequence > 0 { 1651 o.state.AckFloor.Consumer = p.Sequence - 1 1652 o.state.AckFloor.Stream = ss - 1 1653 } 1654 break 1655 } 1656 } 1657 } 1658 } 1659 1660 return nil 1661 } 1662 1663 func (o *consumerMemStore) UpdateConfig(cfg *ConsumerConfig) error { 1664 o.mu.Lock() 1665 defer o.mu.Unlock() 1666 1667 // This is mostly unchecked here. We are assuming the upper layers have done sanity checking. 1668 o.cfg = *cfg 1669 return nil 1670 } 1671 1672 func (o *consumerMemStore) Stop() error { 1673 o.mu.Lock() 1674 o.closed = true 1675 ms := o.ms 1676 o.mu.Unlock() 1677 ms.RemoveConsumer(o) 1678 return nil 1679 } 1680 1681 func (o *consumerMemStore) Delete() error { 1682 return o.Stop() 1683 } 1684 1685 func (o *consumerMemStore) StreamDelete() error { 1686 return o.Stop() 1687 } 1688 1689 func (o *consumerMemStore) State() (*ConsumerState, error) { 1690 return o.stateWithCopy(true) 1691 } 1692 1693 // This will not copy pending or redelivered, so should only be done under the 1694 // consumer owner's lock. 1695 func (o *consumerMemStore) BorrowState() (*ConsumerState, error) { 1696 return o.stateWithCopy(false) 1697 } 1698 1699 func (o *consumerMemStore) stateWithCopy(doCopy bool) (*ConsumerState, error) { 1700 o.mu.Lock() 1701 defer o.mu.Unlock() 1702 1703 if o.closed { 1704 return nil, ErrStoreClosed 1705 } 1706 1707 state := &ConsumerState{} 1708 1709 state.Delivered = o.state.Delivered 1710 state.AckFloor = o.state.AckFloor 1711 if len(o.state.Pending) > 0 { 1712 if doCopy { 1713 state.Pending = o.copyPending() 1714 } else { 1715 state.Pending = o.state.Pending 1716 } 1717 } 1718 if len(o.state.Redelivered) > 0 { 1719 if doCopy { 1720 state.Redelivered = o.copyRedelivered() 1721 } else { 1722 state.Redelivered = o.state.Redelivered 1723 } 1724 } 1725 return state, nil 1726 } 1727 1728 // EncodedState for this consumer store. 1729 func (o *consumerMemStore) EncodedState() ([]byte, error) { 1730 o.mu.Lock() 1731 defer o.mu.Unlock() 1732 1733 if o.closed { 1734 return nil, ErrStoreClosed 1735 } 1736 1737 return encodeConsumerState(&o.state), nil 1738 } 1739 1740 func (o *consumerMemStore) copyPending() map[uint64]*Pending { 1741 pending := make(map[uint64]*Pending, len(o.state.Pending)) 1742 for seq, p := range o.state.Pending { 1743 pending[seq] = &Pending{p.Sequence, p.Timestamp} 1744 } 1745 return pending 1746 } 1747 1748 func (o *consumerMemStore) copyRedelivered() map[uint64]uint64 { 1749 redelivered := make(map[uint64]uint64, len(o.state.Redelivered)) 1750 for seq, dc := range o.state.Redelivered { 1751 redelivered[seq] = dc 1752 } 1753 return redelivered 1754 } 1755 1756 // Type returns the type of the underlying store. 1757 func (o *consumerMemStore) Type() StorageType { return MemoryStorage } 1758 1759 // Templates 1760 type templateMemStore struct{} 1761 1762 func newTemplateMemStore() *templateMemStore { 1763 return &templateMemStore{} 1764 } 1765 1766 // No-ops for memstore. 1767 func (ts *templateMemStore) Store(t *streamTemplate) error { return nil } 1768 func (ts *templateMemStore) Delete(t *streamTemplate) error { return nil }