Beispiel #1
0
// SliceAt implements the fs.SlicerAt interface
func (s *Store) SliceAt(sz, off int64) (p []byte, err error) {
	fn := func(i, start, end int64) (stop bool, err error) {
		s.segmx.RLock()
		if i >= int64(len(s.segs)) {
			s.segmx.RUnlock()
			return false, io.EOF
		}
		s.segmx.RUnlock()

		seg := s.segs[i]
		p = seg.Data[start:end]

		// mark that the mmap may have changed (sliced data can be changed)
		// TODO We're setting this as changed but the change is going to
		// happen later (if it happens at all). Try to fix this problem.
		atomic.StoreUint32(&seg.dirty, 1)

		return true, nil
	}

	if err := segments.Bounds(s.size, off, off+sz, fn); err != nil {
		return nil, err
	}

	return p, nil
}
Beispiel #2
0
// WriteAt implements the io.WriterAt interface
func (s *Store) WriteAt(p []byte, off int64) (n int, err error) {
	sz := int64(len(p))
	towrite := p[:]
	var toalloc int64

	fn := func(i, start, end int64) (stop bool, err error) {
		if err := s.ensure(i); err != nil {
			return false, err
		}

		seg := s.segs[i]
		c := copy(seg.Data[start:end], towrite)

		// mark the segment as changed
		atomic.StoreUint32(&seg.dirty, 1)

		n += c
		towrite = towrite[c:]
		toalloc = i + 1

		return false, nil
	}

	if err := segments.Bounds(s.size, off, off+sz, fn); err != nil {
		return n, err
	}

	return n, nil
}
Beispiel #3
0
// ReadAt implements the io.ReaderAt interface
func (s *Store) ReadAt(p []byte, off int64) (n int, err error) {
	sz := int64(len(p))
	toread := p[:]

	fn := func(i, start, end int64) (stop bool, err error) {
		s.segmx.RLock()
		if i >= int64(len(s.segs)) {
			s.segmx.RUnlock()
			return false, io.EOF
		}
		s.segmx.RUnlock()

		var done int64
		req := end - start
		seg := s.segs[i]

		for done < req {
			c, err := seg.ReadAt(toread[:req-done], start+done)
			if err != nil {
				return false, err
			}

			n += c
			done += int64(c)
			toread = toread[c:]
		}

		return false, nil
	}

	err = segments.Bounds(s.size, off, off+sz, fn)
	return n, err
}
Beispiel #4
0
// ReadAt implements the io.ReaderAt interface
func (s *Store) ReadAt(p []byte, off int64) (n int, err error) {
	sz := int64(len(p))
	toread := p[:]

	fn := func(i, start, end int64) (stop bool, err error) {
		s.segmx.RLock()
		if i >= int64(len(s.segs)) {
			s.segmx.RUnlock()
			return false, io.EOF
		}
		s.segmx.RUnlock()

		seg := s.segs[i]
		c := copy(toread, seg.Data[start:end])

		n += c
		toread = toread[c:]

		return false, nil
	}

	err = segments.Bounds(s.size, off, off+sz, fn)
	return n, err
}
Beispiel #5
0
// WriteAt implements the io.WriterAt interface
func (s *Store) WriteAt(p []byte, off int64) (n int, err error) {
	sz := int64(len(p))
	towrite := p[:]

	fn := func(i, start, end int64) (stop bool, err error) {
		if err := s.ensure(i); err != nil {
			return false, err
		}

		var done int64
		req := end - start
		seg := s.segs[i]

		for done < req {
			c, err := seg.WriteAt(towrite[:req-done], start+done)
			if err != nil {
				return false, err
			}

			n += c
			done += int64(c)
			towrite = towrite[c:]
		}

		// mark the segment as changed
		atomic.StoreUint32(&seg.dirty, 1)

		return false, nil
	}

	if err := segments.Bounds(s.size, off, off+sz, fn); err != nil {
		return n, err
	}

	return n, nil
}