예제 #1
0
func (c *checkPoint) Restore(r *bitmap.File) (err error) {
	size := r.Size() // make sure is blksize-round
	off := size - (size & int64(c.blkSize-1))
	buf := make([]byte, 2)
	for {
		if off == 0 {
			break
		}
		off -= int64(c.blkSize)
		_, err = r.ReadAt(buf, off)
		if err != nil {
			return
		}
		if !bytes.Equal(buf, MagicBytes) {
			continue
		}

		bio := utils.NewBufio(utils.NewReader(r, off+2))
		if err = gob.NewDecoder(bio).Decode(&c.Data); err != nil {
			logex.Error(err)
			return
		}

		off = bio.Offset(-1)
		break
	}

	// move offset to next blk
	off = c.calFloor(off)

	if c.Data == nil {
		c.Data = make(map[string]int64)
	}
	updated := false
	if off < size {
		logex.Info("trying to resore ino into checkpoint")
	}
	bio := utils.NewBufio(utils.NewReader(r, off))
	for off < size {
		bio.Offset(off)
		ino, err := ReadInode(bio, c.blkBit)
		if err != nil {
			if logex.Equal(err, io.EOF) {
				break
			}
			off += int64(c.blkSize)
			continue
		}

		updated = true
		c.Data[ino.Name.String()] = off
		off = c.calFloor(bio.Offset(-1))
	}

	if updated {
		// write down anything which checkpoint is missing
		err = logex.Trace(c.Save(utils.NewWriter(r, r.Size())))
	}
	return
}
예제 #2
0
파일: lfs_test.go 프로젝트: allmad/madq
// simplest test for write and read a file
func TestSingleReadWrite(t *testing.T) {
	var err error
	defer utils.TDefer(t, &err)

	testData := genBlock(9 << 10)
	ins, err := newIns()
	if err != nil {
		return
	}
	defer ins.Pruge()

	f, err := ins.Open("lfsTestTopic")
	if err != nil {
		return
	}
	defer f.Close()

	w := &utils.Writer{f, 0}
	if err = safeWrite(w, testData); err != nil {
		return
	}

	testDataBuf := make([]byte, len(testData))
	r := utils.NewBufio(&utils.Reader{f, 0})
	if err = safeRead(r, testDataBuf); err != nil {
		return
	}

	return
}
예제 #3
0
파일: lfs.go 프로젝트: allmad/madq
// make a new one if not found
// TODO: there is two locks here
func (i *Ins) findIno(name string, blkBit uint) *Inode {
	ino, _ := NewInode(rpc.NewString(name), blkBit)
	off := i.cp.GetInoOffset(name)
	if off > 0 {
		err := ino.PRead(utils.NewBufio(utils.NewReader(i.rfd, off)))
		if err != nil {
			logex.Error(err)
		}
	}
	return ino
}
예제 #4
0
파일: topic.go 프로젝트: allmad/madq
func (t *Ins) get(arg *getArgs, mustReply bool) error {
	if arg.size > MaxGetBenchSize {
		return ErrBenchSizeTooLarge.Trace(arg.size)
	}

	msgs := make([]*message.Ins, arg.size)
	var (
		msg *message.Ins
		err error
	)

	var header message.Header

	// check offset
	r := utils.NewBufio(&utils.Reader{t.file, arg.offset})
	p := 0
	for i := 0; i < arg.size; i++ {
		msg, err = message.Read(&header, r, message.RF_RESEEK_ON_FAULT)
		err = logex.Trace(err, i, arg.offset)
		if logex.EqualAny(err, ErrNeedAddToWaiter) {
			// not finish, add to waiterList
			t.addToWaiterList(newWaiter(arg, r.Offset(-1), p))
			break
		}
		if err != nil {
			break
		}
		msgs[p] = msg
		p++
	}

	if mustReply || p > 0 {
		arg.reply <- rpc.NewReply(t.Name, msgs[:p])
	}
	if logex.Equal(err, io.EOF) {
		err = nil
	}
	return err
}