示例#1
0
// WriteAt implements Filer.
func (f *MemFiler) WriteAt(b []byte, off int64) (n int, err error) {
	pgI := off >> pgBits
	pgO := int(off & pgMask)
	n = len(b)
	rem := n
	var nc int
	for rem != 0 {
		if pgO == 0 && rem >= pgSize && bytes.Equal(b[:pgSize], zeroPage[:]) {
			delete(f.m, pgI)
			nc = pgSize
		} else {
			pg := f.m[pgI]
			if pg == nil {
				pg = new([pgSize]byte)
				f.m[pgI] = pg
			}
			nc = copy((*pg)[pgO:], b)
		}
		pgI++
		pgO = 0
		rem -= nc
		b = b[nc:]
	}
	f.size = mathutil.MaxInt64(f.size, off+int64(n))
	return
}
示例#2
0
文件: file.go 项目: brgmnn/syncthing
func newFile(f *os.File, maxSize int64, pgBits uint) (*file, error) {
	if maxSize < 0 {
		panic("internal error")
	}

	pgSize := 1 << pgBits
	switch {
	case sysPage > pgSize:
		pgBits = uint(mathutil.Log2Uint64(uint64(sysPage)))
	default:
		pgBits = uint(mathutil.Log2Uint64(uint64(pgSize / sysPage * sysPage)))
	}
	pgSize = 1 << pgBits
	fi := &file{
		f: f,
		m: fileMap{},
		maxPages: int(mathutil.MinInt64(
			1024,
			mathutil.MaxInt64(maxSize/int64(pgSize), 1)),
		),
		pgBits: pgBits,
		pgMask: pgSize - 1,
		pgSize: pgSize,
	}
	info, err := f.Stat()
	if err != nil {
		return nil, err
	}

	if err = fi.Truncate(info.Size()); err != nil {
		return nil, err
	}

	return fi, nil
}
示例#3
0
文件: xact.go 项目: brgmnn/syncthing
func (f *bitFiler) WriteAt(b []byte, off int64) (n int, err error) {
	off0 := off
	pgI := off >> bfBits
	pgO := int(off & bfMask)
	n = len(b)
	rem := n
	var nc int
	for rem != 0 {
		pg := f.m[pgI]
		if pg == nil {
			pg = &bitPage{}
			pg.pdata = buffer.CGet(bfSize)
			pg.data = *pg.pdata
			if f.parent != nil {
				_, err = f.parent.ReadAt(pg.data, off&^bfMask)
				if err != nil && !fileutil.IsEOF(err) {
					return
				}

				err = nil
			}
			f.m[pgI] = pg
		}
		nc = copy(pg.data[pgO:], b)
		pgI++
		pg.dirty = true
		pgO = 0
		rem -= nc
		b = b[nc:]
		off += int64(nc)
	}
	f.size = mathutil.MaxInt64(f.size, off0+int64(n))
	return
}
示例#4
0
文件: xact.go 项目: sinfomicien/rkt
func (f *bitFiler) WriteAt(b []byte, off int64) (n int, err error) {
	off0 := off
	pgI := off >> bfBits
	pgO := int(off & bfMask)
	n = len(b)
	rem := n
	var nc int
	for rem != 0 {
		pg := f.m[pgI]
		if pg == nil {
			pg = &bitPage{}
			if f.parent != nil {
				_, err = f.parent.ReadAt(pg.data[:], off&^bfMask)
				if err != nil && !fileutil.IsEOF(err) {
					return
				}

				err = nil
			}
			f.m[pgI] = pg
		}
		nc = copy(pg.data[pgO:], b)
		pgI++
		pg.dirty = true
		for i := pgO; i < pgO+nc; i++ {
			pg.flags[i>>3] |= bitmask[i&7]
		}
		pgO = 0
		rem -= nc
		b = b[nc:]
		off += int64(nc)
	}
	f.size = mathutil.MaxInt64(f.size, off0+int64(n))
	return
}
示例#5
0
文件: filer.go 项目: sinfomicien/rkt
// Size implements Filer.
func (f *InnerFiler) Size() (int64, error) {
	sz, err := f.outer.Size()
	if err != nil {
		return 0, err
	}

	return mathutil.MaxInt64(sz-f.off, 0), nil
}
示例#6
0
func copyBlockData(blockData []byte, readStart int64, blockStart int64, readEnd int64, blockEnd int64, data []byte) {
	for j := mathutil.MaxInt64(readStart, blockStart); j < readEnd && j < blockEnd; j++ {
		outputItr := j - readStart
		inputItr := j - blockStart

		data[outputItr] = blockData[inputItr]
	}
}
示例#7
0
// WriteAt implements Filer.
func (f *SimpleFileFiler) WriteAt(b []byte, off int64) (n int, err error) {
	if f.size < 0 { // boot
		fi, err := os.Stat(f.file.Name())
		if err != nil {
			return 0, err
		}

		f.size = fi.Size()
	}
	f.size = mathutil.MaxInt64(f.size, int64(len(b))+off)
	return f.file.WriteAt(b, off)
}
示例#8
0
文件: file.go 项目: pmezard/exp
func (f *File) writeAt(b []byte, off int64, bits bool) (n int, err error) {
	var fsize int64
	a := (*Array)(f)
	if !bits {
		fsize, err = f.Size()
		if err != nil {
			return
		}
	}

	pgI := off >> pgBits
	pgO := int(off & pgMask)
	rem := len(b)
	var nc int
	for rem != 0 {
		if pgO == 0 && rem >= pgSize && bytes.Equal(b[:pgSize], zeroPage[:]) {
			if err = a.Delete(pgI); err != nil {
				return
			}

			nc = pgSize
			n += nc
		} else {
			v, err := a.Get(pgI)
			if err != nil {
				return n, err
			}

			pg, _ := v.([]byte)
			if len(pg) == 0 {
				pg = make([]byte, pgSize)
			}

			nc = copy(pg[pgO:], b)
			n += nc
			if err = a.Set(pg, pgI); err != nil {
				return n, err
			}

		}
		pgI++
		pgO = 0
		rem -= nc
		b = b[nc:]
	}
	if !bits {
		if newSize := mathutil.MaxInt64(fsize, off+int64(n)); newSize != fsize {
			return n, a.Set(newSize, fSize)
		}
	}

	return
}
示例#9
0
文件: file.go 项目: brgmnn/syncthing
func (f *mem) WriteAt(b []byte, off int64) (n int, err error) {
	pi := off >> f.pgBits
	po := int(off) & f.pgMask
	n = len(b)
	rem := n
	var nc int
	for rem != 0 {
		pg := f.m[pi]
		if pg == nil {
			pg = buffer.CGet(f.pgSize)
			f.m[pi] = pg
		}
		nc = copy((*pg)[po:], b)
		pi++
		po = 0
		rem -= nc
		b = b[nc:]
	}
	f.size = mathutil.MaxInt64(f.size, off+int64(n))
	return n, nil
}
示例#10
0
文件: file.go 项目: brgmnn/syncthing
func (f *file) WriteAt(b []byte, off int64) (n int, err error) {
	pi := off >> f.pgBits
	po := int(off) & f.pgMask
	n = len(b)
	rem := n
	var nc int
	for rem != 0 {
		pg := f.m[pi]
		if pg == nil {
			pg, err = f.page(pi)
			if err != nil {
				return n, err
			}
		}
		nc = copy(pg[po:], b)
		pi++
		po = 0
		rem -= nc
		b = b[nc:]
	}
	f.size = mathutil.MaxInt64(f.size, off+int64(n))
	return n, nil
}
示例#11
0
文件: 2pc.go 项目: sinfomicien/rkt
// NewACIDFiler0 returns a  newly created ACIDFiler0 with WAL in wal.
//
// If the WAL is zero sized then a previous clean shutdown of db is taken for
// granted and no recovery procedure is taken.
//
// If the WAL is of non zero size then it is checked for having a
// commited/fully finished transaction not yet been reflected in db. If such
// transaction exists it's committed to db. If the recovery process finishes
// successfully, the WAL is truncated to zero size and fsync'ed prior to return
// from NewACIDFiler0.
func NewACIDFiler(db Filer, wal *os.File) (r *ACIDFiler0, err error) {
	fi, err := wal.Stat()
	if err != nil {
		return
	}

	r = &ACIDFiler0{wal: wal}

	if fi.Size() != 0 {
		if err = r.recoverDb(db); err != nil {
			return
		}
	}

	acidWriter := (*acidWriter0)(r)

	if r.RollbackFiler, err = NewRollbackFiler(
		db,
		func(sz int64) (err error) {
			// Checkpoint
			if err = acidWriter.writePacket([]interface{}{wpt00Checkpoint, sz}); err != nil {
				return
			}

			if err = r.bwal.Flush(); err != nil {
				return
			}

			r.bwal = nil

			if err = r.wal.Sync(); err != nil {
				return
			}

			wfi, err := r.wal.Stat()
			switch err != nil {
			case true:
				// unexpected, but ignored
			case false:
				r.peakWal = mathutil.MaxInt64(wfi.Size(), r.peakWal)
			}

			// Phase 1 commit complete

			for _, v := range r.data {
				if _, err := db.WriteAt(v.b, v.off); err != nil {
					return err
				}
			}

			if err = db.Truncate(sz); err != nil {
				return
			}

			if err = db.Sync(); err != nil {
				return
			}

			// Phase 2 commit complete

			if !r.testHook {
				if err = r.wal.Truncate(0); err != nil {
					return
				}

				if _, err = r.wal.Seek(0, 0); err != nil {
					return
				}
			}

			r.testHook = false
			return r.wal.Sync()

		},
		acidWriter,
	); err != nil {
		return
	}

	return r, nil
}