github.com/cockroachdb/cockroachdb-parser@v0.23.3-0.20240213214944-911057d40c9a/pkg/sql/sessiondatapb/sequence_cache.go (about) 1 // Copyright 2020 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package sessiondatapb 12 13 // SequenceCache stores sequence values that have already been created in KV 14 // and are available to be given out as sequence numbers. Values for sequences 15 // are keyed by the descpb.ID of each sequence. These IDs are represented as 16 // uint32 to prevent an import cycle with the descpb package. The cache should 17 // only be accessed using the provided API. 18 // 19 // The cache ensures that values are invalidated when new descriptor versions are seen. Note that 20 // new descriptor versions may not monotonically increase. For example, the sequence schema 21 // may be altered in a txn, so the cache sees a new version V and invalidates/repopulates itself. Then, 22 // the txn may get rolled back, so the cache will see version V-1 and invalidate/repopulate itself again. 23 type SequenceCache map[uint32]*SequenceCacheEntry 24 25 // NextValue fetches the next value in the sequence cache. If the values in the cache have all been 26 // given out or if the descriptor version has changed, then fetchNextValues() is used to repopulate the cache. 27 func (sc SequenceCache) NextValue( 28 seqID uint32, clientVersion uint32, fetchNextValues func() (int64, int64, int64, error), 29 ) (int64, error) { 30 // Create entry for this sequence ID if there are no existing entries. 31 if _, found := sc[seqID]; !found { 32 sc[seqID] = &SequenceCacheEntry{} 33 } 34 cacheEntry := sc[seqID] 35 36 if cacheEntry.NumValues > 0 && cacheEntry.CachedVersion == clientVersion { 37 cacheEntry.CurrentValue += cacheEntry.Increment 38 cacheEntry.NumValues-- 39 return cacheEntry.CurrentValue - cacheEntry.Increment, nil 40 } 41 42 currentValue, increment, numValues, err := fetchNextValues() 43 if err != nil { 44 return 0, err 45 } 46 47 // One value must be returned, and the rest of the values are stored. 48 val := currentValue 49 cacheEntry.CurrentValue = currentValue + increment 50 cacheEntry.Increment = increment 51 cacheEntry.NumValues = numValues - 1 52 cacheEntry.CachedVersion = clientVersion 53 return val, nil 54 }