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 }
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 }
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 }