Ejemplo n.º 1
0
func storeBlob(blob *Blob) error {
	// TODO(ortutay): in the case of a failed write, we need to garbage collect
	for _, block := range blob.Blocks {
		path := blockPath(block.ID)
		if _, err := os.Stat(path); err == nil {
			continue
		}
		func() {
			f, err := os.Create(path)
			defer f.Close()
			util.Ferr(err)
			_, err = f.Write(block.Data)
			util.Ferr(err)
		}()
	}

	// Write blob -> blocks mapping
	ids := blob.BlockIDs()
	d := util.GetOrCreateDB(blobToBlocksDB())
	ser, err := json.Marshal(ids)
	util.Ferr(err)
	err = d.Write(blob.ID.String(), ser)
	util.Ferr(err)
	return nil
}
Ejemplo n.º 2
0
func NewBlobFromDisk(id BlobID) (*Blob, error) {
	d := util.GetOrCreateDB(blobToBlocksDB())
	idsSer, err := d.Read(id.String())
	if idsSer == nil || len(idsSer) == 0 {
		return nil, fmt.Errorf("not found")
	}
	var ids []BlockID
	err = json.Unmarshal(idsSer, &ids)
	util.Ferr(err)
	var blocks []*Block
	for _, id := range ids {
		block, err := func() (*Block, error) {
			f, err := os.Open(blockPath(id))
			defer f.Close()
			if err != nil {
				return nil, err
			}
			data, err := ioutil.ReadAll(f)
			if len(data) > BYTES_PER_BLOCK {
				log.Fatalf("too big block %v of size %v", id, len(data))
			}
			block, err := NewBlock(data)
			util.Ferr(err)
			if block.ID != id {
				log.Fatalf("mismatched id's %v != %v", id, block.ID)
			}
			return block, nil
		}()
		if err != nil {
			return nil, err
		}
		blocks = append(blocks, block)
	}
	return NewBlob(blocks)
}
Ejemplo n.º 3
0
func setOcIDForCoin(coin string, ocID *msg.OcID) error {
	fmt.Printf("set oc ID for coin %v\n", coin)
	d := util.GetOrCreateDB(peerDBPath())
	err := d.Write(coin, []byte(ocID.String()))
	util.Ferr(err)

	return nil
}
Ejemplo n.º 4
0
func (c *Container) WriteNewBlobID(id BlobID) {
	d := util.GetOrCreateDB(containersDB())
	c.BlobIDs = append(c.BlobIDs, id)
	blobIDsSer, err := json.Marshal(c)
	util.Ferr(err)
	err = d.Write(c.OwnerID.String(), blobIDsSer)
	util.Ferr(err)
}
Ejemplo n.º 5
0
func ocIDForCoin(coin string) (*msg.OcID, error) {
	fmt.Printf("get oc ID for coin: %v\n", coin)
	d := util.GetOrCreateDB(peerDBPath())
	v, _ := d.Read(coin)
	if v == nil || len(v) == 0 {
		return nil, nil
	}
	id := msg.OcID(v)
	return &id, nil
}
Ejemplo n.º 6
0
func NewContainerFromDisk(id msg.OcID) *Container {
	d := util.GetOrCreateDB(containersDB())
	containerID := ocIDToContainerID(id)
	ser, _ := d.Read(id.String())
	if ser == nil || len(ser) == 0 {
		return &Container{ID: containerID, OwnerID: id}
	} else {
		var container Container
		err := json.Unmarshal(ser, &container)
		util.Ferr(err)
		return &container
	}
}
Ejemplo n.º 7
0
func (ss *StoreService) PeriodicWake() {
	now := time.Now().Unix()
	if ss.lastWake == 0 {
		ss.lastWake = now
	}
	period := int64(10)
	if now-ss.lastWake < period {
		return
	}
	ss.lastWake = now
	d := util.GetOrCreateDB(containersDB())
	keys := d.Keys()
	for {
		key := <-keys
		if len(key) == 0 {
			break
		}
		bytesUsed := 0
		id := msg.OcID(key)
		container := NewContainerFromDisk(id)
		seenBlocks := make(map[string]bool)
		for _, blobID := range container.BlobIDs {
			// TODO(ortutay): don't read blocks from disk just to find sizes
			blob, err := NewBlobFromDisk(blobID)
			if err != nil {
				continue
			}
			for _, block := range blob.Blocks {
				if _, ok := seenBlocks[block.ID.String()]; ok {
					continue
				}
				seenBlocks[block.ID.String()] = true
				bytesUsed += len(block.Data)
			}
		}
		costPv := costForBytesSeconds(bytesUsed, int(period))
		fmt.Printf("bytes %v used by %v..., cost += %f %v\n",
			bytesUsed, id.String()[:8], util.S2B(costPv.Amount), costPv.Currency)
		rec := rep.Record{
			Role:         rep.SERVER,
			Service:      SERVICE_NAME,
			Method:       PUT_METHOD,
			Timestamp:    int(now),
			ID:           id,
			Status:       rep.SUCCESS_UNPAID,
			PaymentValue: costPv,
			Perf:         nil,
		}
		rep.Put(&rec)
	}
}
Ejemplo n.º 8
0
func (p *Peer) readPaymentAddrs() []string {
	d := util.GetOrCreateDB(addrDBPath())
	fmt.Printf("p: %v\n", p)
	addrsSer, _ := d.Read(p.ID.String())
	if addrsSer == nil || len(addrsSer) == 0 {
		return []string{}
	} else {
		var addrs []string
		err := json.Unmarshal(addrsSer, &addrs)
		if err != nil {
			return []string{}
		}
		return addrs
	}
}
Ejemplo n.º 9
0
func (p *Peer) PaymentAddr(maxToMake int, btcConf *util.BitcoindConf) (string, error) {
	if maxToMake == -1 {
		// TODO(ortutay): This is a parameter for testing. See if there is a better
		// solution.
		maxToMake = DEFAULT_MAX_TO_MAKE
	}
	d := util.GetOrCreateDB(addrDBPath())
	addrsSer, _ := d.Read(p.ID.String())
	fmt.Printf("read addrs: %v\n", addrsSer)
	if addrsSer == nil || len(addrsSer) == 0 {
		fmt.Printf("no addrs read, making...\n")
		var addrs []string
		for i := 0; i < maxToMake; i++ {
			btcAddr, err := p.fetchNewBtcAddr(btcConf)
			if err != nil {
				log.Printf("error while generating addresses: %v\n", err)
				return "", err
			}
			addrs = append(addrs, btcAddr)
		}
		ser, err := json.Marshal(addrs)
		if err != nil {
			return "", err
		}
		err = d.Write(p.ID.String(), ser)
		if err != nil {
			return "", err
		}
		fmt.Printf("generated addresses: %v ser: %v\n", addrs, string(ser))
		addrsSer, _ = d.Read(p.ID.String())
	}
	var addrs []string
	err := json.Unmarshal(addrsSer, &addrs)
	if err != nil {
		return "", err
	}
	if addrs == nil || len(addrs) == 0 {
		panic("unexpected empty list")
	}
	return addrs[rand.Int()%len(addrs)], nil
}