// Get can be called from any goroutine to retrieve the chunk referenced by hash. If the chunk is not present, Get returns the empty Chunk. func (p *orderedChunkCache) Get(hash hash.Hash) chunks.Chunk { // Don't use defer p.mu.RUnlock() here, because I want reading from orderedChunks NOT to be guarded by the lock. LevelDB handles its own goroutine-safety. p.mu.RLock() dbKey, ok := p.chunkIndex[hash] p.mu.RUnlock() if !ok { return chunks.EmptyChunk } compressed, err := p.orderedChunks.Get(dbKey, nil) d.Chk.NoError(err) data, err := snappy.Decode(nil, compressed) d.Chk.NoError(err) return chunks.NewChunkWithHash(hash, data) }
// ExtractChunks can be called from any goroutine to write Chunks referenced by the given hashes to w. The chunks are ordered by ref-height. Chunks of the same height are written in an unspecified order, relative to one another. func (p *orderedChunkCache) ExtractChunks(hashes hash.HashSet, chunkChan chan *chunks.Chunk) error { iter := p.orderedChunks.NewIterator(nil, nil) defer iter.Release() for iter.Next() { _, hash := fromDbKey(iter.Key()) if !hashes.Has(hash) { continue } compressed := iter.Value() data, err := snappy.Decode(nil, compressed) d.Chk.NoError(err) c := chunks.NewChunkWithHash(hash, data) chunkChan <- &c } return nil }