61 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			Go
		
	
	
			
		
		
	
	
			61 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			Go
		
	
	
package azure
 | 
						|
 | 
						|
import (
 | 
						|
	"encoding/base64"
 | 
						|
	"fmt"
 | 
						|
	"math/rand"
 | 
						|
	"sync"
 | 
						|
	"time"
 | 
						|
 | 
						|
	azure "github.com/Azure/azure-sdk-for-go/storage"
 | 
						|
)
 | 
						|
 | 
						|
type blockIDGenerator struct {
 | 
						|
	pool map[string]bool
 | 
						|
	r    *rand.Rand
 | 
						|
	m    sync.Mutex
 | 
						|
}
 | 
						|
 | 
						|
// Generate returns an unused random block id and adds the generated ID
 | 
						|
// to list of used IDs so that the same block name is not used again.
 | 
						|
func (b *blockIDGenerator) Generate() string {
 | 
						|
	b.m.Lock()
 | 
						|
	defer b.m.Unlock()
 | 
						|
 | 
						|
	var id string
 | 
						|
	for {
 | 
						|
		id = toBlockID(int(b.r.Int()))
 | 
						|
		if !b.exists(id) {
 | 
						|
			break
 | 
						|
		}
 | 
						|
	}
 | 
						|
	b.pool[id] = true
 | 
						|
	return id
 | 
						|
}
 | 
						|
 | 
						|
func (b *blockIDGenerator) exists(id string) bool {
 | 
						|
	_, used := b.pool[id]
 | 
						|
	return used
 | 
						|
}
 | 
						|
 | 
						|
func (b *blockIDGenerator) Feed(blocks azure.BlockListResponse) {
 | 
						|
	b.m.Lock()
 | 
						|
	defer b.m.Unlock()
 | 
						|
 | 
						|
	for _, bl := range append(blocks.CommittedBlocks, blocks.UncommittedBlocks...) {
 | 
						|
		b.pool[bl.Name] = true
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func newBlockIDGenerator() *blockIDGenerator {
 | 
						|
	return &blockIDGenerator{
 | 
						|
		pool: make(map[string]bool),
 | 
						|
		r:    rand.New(rand.NewSource(time.Now().UnixNano()))}
 | 
						|
}
 | 
						|
 | 
						|
// toBlockId converts given integer to base64-encoded block ID of a fixed length.
 | 
						|
func toBlockID(i int) string {
 | 
						|
	s := fmt.Sprintf("%029d", i) // add zero padding for same length-blobs
 | 
						|
	return base64.StdEncoding.EncodeToString([]byte(s))
 | 
						|
}
 |