MCPcopy Create free account
hub / github.com/couchbase/sync_gateway / load

Method load

db/revision_cache_lru.go:660–728  ·  view source on GitHub ↗

Gets the body etc. out of a revCacheValue. If they aren't present already, the loader func will be called. This is synchronized so that the loader will only be called once even if multiple goroutines try to load at the same time.

(ctx context.Context, backingStore RevisionCacheBackingStore, includeDelta bool, loadBackup bool)

Source from the content-addressed store, hash-verified

658// will be called. This is synchronized so that the loader will only be called once even if
659// multiple goroutines try to load at the same time.
660func (value *revCacheValue) load(ctx context.Context, backingStore RevisionCacheBackingStore, includeDelta bool, loadBackup bool) (docRev DocumentRevision, cacheHit bool, err error) {
661
662 // Reading the delta from the revCacheValue requires holding the read lock, so it's managed outside asDocumentRevision,
663 // to reduce locking when includeDelta=false
664 var delta *RevisionDelta
665 var revid string
666
667 // Attempt to read cached value.
668 value.lock.RLock()
669 if value.bodyBytes != nil || value.err != nil {
670 if includeDelta {
671 delta = value.delta
672 }
673 value.lock.RUnlock()
674
675 docRev, err = value.asDocumentRevision(delta)
676
677 return docRev, true, err
678 }
679 value.lock.RUnlock()
680
681 value.lock.Lock()
682 defer value.lock.Unlock()
683 // Check if the value was loaded while we waited for the lock - if so, return.
684 if value.bodyBytes != nil || value.err != nil {
685 cacheHit = true
686 } else {
687 // we only want to set can evict if we are having to load the doc from the bucket into value,
688 // avoiding setting this value multiple times in the case other goroutines are loading the same value
689 defer func() {
690 value.canEvict.Store(true) // once done loading doc we can set the value to be ready for eviction
691 }()
692
693 cacheHit = false
694 hlv := &HybridLogicalVector{}
695 if value.revID == "" {
696 hlvKey := IDandCV{DocID: value.id, Source: value.cv.SourceID, Version: value.cv.Value}
697 value.bodyBytes, value.history, value.channels, value.removed, value.attachments, value.deleted, value.expiry, revid, hlv, value.err = revCacheLoaderForCv(ctx, backingStore, hlvKey, loadBackup)
698 // based off the current value load we need to populate the revid key with what has been fetched from the bucket (for use of populating the opposite lookup map)
699 if revid != "" {
700 value.revID = revid
701 }
702 if hlv != nil {
703 value.hlvHistory = hlv.ToHistoryForHLV()
704 }
705 } else {
706 revKey := IDAndRev{DocID: value.id, RevID: value.revID}
707 value.bodyBytes, value.history, value.channels, value.removed, value.attachments, value.deleted, value.expiry, hlv, value.err = revCacheLoader(ctx, backingStore, revKey)
708 // based off the revision load we need to populate the hlv key with what has been fetched from the bucket (for use of populating the opposite lookup map)
709 if hlv != nil {
710 value.cv = *hlv.ExtractCurrentVersionFromHLV()
711 value.hlvHistory = hlv.ToHistoryForHLV()
712 }
713 }
714 }
715
716 if includeDelta {
717 delta = value.delta

Callers 5

get_db_listFunction · 0.45
get_paths_from_expvarsFunction · 0.45
can_connect_to_sg_urlFunction · 0.45
getFromCacheByRevMethod · 0.45
getFromCacheByCVMethod · 0.45

Calls 11

asDocumentRevisionMethod · 0.95
ToHistoryForHLVMethod · 0.95
revCacheLoaderForCvFunction · 0.85
revCacheLoaderFunction · 0.85
RLockMethod · 0.80
RUnlockMethod · 0.80
StoreMethod · 0.80
CalculateBytesMethod · 0.80
LockMethod · 0.45
UnlockMethod · 0.45

Tested by

no test coverage detected