コード例 #1
0
// Inserts a key into the database.
func simulatePutHandler(tx *bolt.Tx, qdb *QuickDB) {
	var err error
	keys, value := randKeys(), randValue()

	// Retrieve root bucket.
	b := tx.Bucket(keys[0])
	if b == nil {
		b, err = tx.CreateBucket(keys[0])
		if err != nil {
			panic("create bucket: " + err.Error())
		}
	}

	// Create nested buckets, if necessary.
	for _, key := range keys[1 : len(keys)-1] {
		child := b.Bucket(key)
		if child != nil {
			b = child
		} else {
			b, err = b.CreateBucket(key)
			if err != nil {
				panic("create bucket: " + err.Error())
			}
		}
	}

	// Insert into database.
	if err := b.Put(keys[len(keys)-1], value); err != nil {
		panic("put: " + err.Error())
	}

	// Insert into in-memory database.
	qdb.Put(keys, value)
}
コード例 #2
0
// Retrieves a key from the database and verifies that it is what is expected.
func simulateGetHandler(tx *bolt.Tx, qdb *QuickDB) {
	// Randomly retrieve an existing exist.
	keys := qdb.Rand()
	if len(keys) == 0 {
		return
	}

	// Retrieve root bucket.
	b := tx.Bucket(keys[0])
	if b == nil {
		panic(fmt.Sprintf("bucket[0] expected: %08x\n", trunc(keys[0], 4)))
	}

	// Drill into nested buckets.
	for _, key := range keys[1 : len(keys)-1] {
		b = b.Bucket(key)
		if b == nil {
			panic(fmt.Sprintf("bucket[n] expected: %v -> %v\n", keys, key))
		}
	}

	// Verify key/value on the final bucket.
	expected := qdb.Get(keys)
	actual := b.Get(keys[len(keys)-1])
	if !bytes.Equal(actual, expected) {
		fmt.Println("=== EXPECTED ===")
		fmt.Println(expected)
		fmt.Println("=== ACTUAL ===")
		fmt.Println(actual)
		fmt.Println("=== END ===")
		panic("value mismatch")
	}
}
コード例 #3
0
ファイル: manager.go プロジェクト: technosophos/flynn
func (m *Manager) persistProvider(tx *bolt.Tx, id string) error {
	// Note: This method does *not* include re-serializing per-volume state,
	// because we assume that hasn't changed unless the change request
	// for the volume came through us and was handled elsewhere already.
	provider, ok := m.providers[id]
	if !ok {
		return tx.Bucket([]byte("providers")).DeleteBucket([]byte(id))
	}
	providersBucket, err := m.getProviderBucket(tx, id)
	if err != nil {
		return fmt.Errorf("could not persist provider info to boltdb: %s", err)
	}
	pspec := &volume.ProviderSpec{}
	pspec.Kind = provider.Kind()
	b, err := provider.MarshalGlobalState()
	if err != nil {
		return fmt.Errorf("failed to serialize provider info: %s", err)
	}
	pspec.Config = b
	b, err = json.Marshal(pspec)
	if err != nil {
		return fmt.Errorf("failed to serialize provider info: %s", err)
	}
	err = providersBucket.Put([]byte("global"), b)
	if err != nil {
		return fmt.Errorf("could not persist provider info to boltdb: %s", err)
	}
	return nil
}
コード例 #4
0
ファイル: manager.go プロジェクト: technosophos/flynn
func (m *Manager) getProviderBucket(tx *bolt.Tx, providerID string) (*bolt.Bucket, error) {
	// Schema is roughly `"providers" -> "$provID" -> { "global" -> literal, "volumes" -> "$volID" -> literals }`.
	// ... This is getting complicated enough it might make sense to split the whole bolt thing out into its own structure.
	providerKey := []byte(providerID)
	providerBucket, err := tx.Bucket([]byte("providers")).CreateBucketIfNotExists(providerKey)
	if err != nil {
		return nil, err
	}
	_, err = providerBucket.CreateBucketIfNotExists([]byte("volumes"))
	return providerBucket, err
}
コード例 #5
0
ファイル: manager.go プロジェクト: technosophos/flynn
// Called to sync changes to disk when a volume is updated
func (m *Manager) persistVolume(tx *bolt.Tx, vol volume.Volume) error {
	// Save the general volume info
	volumesBucket := tx.Bucket([]byte("volumes"))
	id := vol.Info().ID
	k := []byte(id)
	_, volExists := m.volumes[id]
	if !volExists {
		volumesBucket.Delete(k)
	} else {
		b, err := json.Marshal(vol.Info())
		if err != nil {
			return fmt.Errorf("failed to serialize volume info: %s", err)
		}
		err = volumesBucket.Put(k, b)
		if err != nil {
			return fmt.Errorf("could not persist volume info to boltdb: %s", err)
		}
	}
	// Save any provider-specific metadata associated with the volume.
	// These are saved per-provider since the deserialization is also only defined per-provider implementation.
	providerBucket, err := m.getProviderBucket(tx, m.providerIDs[vol.Provider()])
	if err != nil {
		return fmt.Errorf("could not persist provider volume info to boltdb: %s", err)
	}
	providerVolumesBucket := providerBucket.Bucket([]byte("volumes"))
	if !volExists {
		providerVolumesBucket.Delete(k)
	} else {
		b, err := vol.Provider().MarshalVolumeState(id)
		if err != nil {
			return fmt.Errorf("failed to serialize provider volume info: %s", err)
		}
		err = providerVolumesBucket.Put(k, b)
		if err != nil {
			return fmt.Errorf("could not persist provider volume info to boltdb: %s", err)
		}
	}
	return nil
}