예제 #1
0
func (c *CacheMap) create_get_submsg(msg *message.Message,
	address uint64, logblock uint32,
	buffer []byte) *message.Message {

	m := message.NewMsgGet()
	msg.Add(m)

	// Set IoPkt
	mio := m.IoPkt()
	mio.Address = address
	mio.Buffer = buffer
	mio.LogBlock = logblock

	return m
}
예제 #2
0
func (c *CacheMap) Put(msg *message.Message) error {

	err := msg.Check()
	if err != nil {
		return err
	}

	c.lock.Lock()
	defer c.lock.Unlock()

	io := msg.IoPkt()
	if io.Blocks > 1 {
		// Have parent message wait for its children
		defer msg.Done()

		//
		// It does not matter that we send small blocks to the Log, since
		// it will buffer them before sending them out to the cache device
		//
		// We do need to send each one sperately now so that the cache
		// policy hopefully aligns them one after the other.
		//
		for block := uint32(0); block < io.Blocks; block++ {
			child := message.NewMsgPut()
			msg.Add(child)

			child_io := child.IoPkt()
			child_io.Address = io.Address + uint64(block)
			child_io.Buffer = SubBlockBuffer(io.Buffer, c.blocksize, block, 1)
			child_io.LogBlock = c.put(child_io.Address)
			child_io.Blocks = 1

			// Send to next one in line
			c.pipeline <- child
		}
	} else {
		io.LogBlock = c.put(io.Address)
		c.pipeline <- msg
	}

	return nil
}
예제 #3
0
파일: log.go 프로젝트: chenweicai/pblcache
func (c *Log) get(msg *message.Message) error {

	var n int
	var err error

	defer msg.Done()
	iopkt := msg.IoPkt()

	var readmsg *message.Message
	var readmsg_block uint32
	for block := uint32(0); block < iopkt.Blocks; block++ {
		ramhit := false
		index := iopkt.LogBlock + block
		offset := c.offset(index)

		// Check if the data is in RAM.  Go through each buffered segment
		for i := 0; i < c.segmentbuffers; i++ {

			c.segments[i].lock.RLock()
			if c.inRange(index, &c.segments[i]) {

				ramhit = true
				n, err = c.segments[i].data.ReadAt(SubBlockBuffer(iopkt.Buffer, c.blocksize, block, 1),
					offset-c.segments[i].offset)

				godbc.Check(err == nil, err, block, offset, i)
				godbc.Check(uint32(n) == c.blocksize)
				c.stats.RamHit()
			}
			c.segments[i].lock.RUnlock()
		}

		// We did not find it in ram, let's start making a message
		if !ramhit {
			if readmsg == nil {
				readmsg = message.NewMsgGet()
				msg.Add(readmsg)
				io := readmsg.IoPkt()
				io.LogBlock = index
				io.Blocks = 1
				readmsg_block = block
			} else {
				readmsg.IoPkt().Blocks++
			}

			io := readmsg.IoPkt()
			io.Buffer = SubBlockBuffer(iopkt.Buffer,
				c.blocksize,
				readmsg_block,
				io.Blocks)

		} else if readmsg != nil {
			// We have a pending message, but the
			// buffer block was not contiguous.
			c.logreaders <- readmsg
			readmsg = nil
		}
	}

	// Send pending read
	if readmsg != nil {
		c.logreaders <- readmsg
	}

	return nil
}