Browse Source

avoid writing the same file

pull/2/head
Chris Lu 12 years ago
parent
commit
4c1bc99366
  1. 8
      go/storage/needle_read_write.go
  2. 25
      go/storage/volume.go

8
go/storage/needle_read_write.go

@ -130,9 +130,11 @@ func (n *Needle) Read(r io.Reader, size uint32, version Version) (ret int, err e
n.readNeedleHeader(bytes) n.readNeedleHeader(bytes)
n.Data = bytes[NeedleHeaderSize : NeedleHeaderSize+size] n.Data = bytes[NeedleHeaderSize : NeedleHeaderSize+size]
checksum := util.BytesToUint32(bytes[NeedleHeaderSize+size : NeedleHeaderSize+size+NeedleChecksumSize]) checksum := util.BytesToUint32(bytes[NeedleHeaderSize+size : NeedleHeaderSize+size+NeedleChecksumSize])
if checksum != NewCRC(n.Data).Value() {
newChecksum := NewCRC(n.Data)
if checksum != newChecksum.Value() {
return 0, errors.New("CRC error! Data On Disk Corrupted!") return 0, errors.New("CRC error! Data On Disk Corrupted!")
} }
n.Checksum = newChecksum
return return
case Version2: case Version2:
if size == 0 { if size == 0 {
@ -151,9 +153,11 @@ func (n *Needle) Read(r io.Reader, size uint32, version Version) (ret int, err e
} }
n.readNeedleDataVersion2(bytes[NeedleHeaderSize : NeedleHeaderSize+int(n.Size)]) n.readNeedleDataVersion2(bytes[NeedleHeaderSize : NeedleHeaderSize+int(n.Size)])
checksum := util.BytesToUint32(bytes[NeedleHeaderSize+n.Size : NeedleHeaderSize+n.Size+NeedleChecksumSize]) checksum := util.BytesToUint32(bytes[NeedleHeaderSize+n.Size : NeedleHeaderSize+n.Size+NeedleChecksumSize])
if checksum != NewCRC(n.Data).Value() {
newChecksum := NewCRC(n.Data)
if checksum != newChecksum.Value() {
return 0, errors.New("CRC error! Data On Disk Corrupted!") return 0, errors.New("CRC error! Data On Disk Corrupted!")
} }
n.Checksum = newChecksum
return return
} }
return 0, fmt.Errorf("Unsupported Version! (%d)", version) return 0, fmt.Errorf("Unsupported Version! (%d)", version)

25
go/storage/volume.go

@ -158,6 +158,27 @@ func (v *Volume) NeedToReplicate() bool {
return v.ReplicaType.GetCopyCount() > 1 return v.ReplicaType.GetCopyCount() > 1
} }
func (v *Volume) isFileUnchanged(n *Needle) bool {
nv, ok := v.nm.Get(n.Id)
if ok && nv.Offset > 0 {
if _, err := v.dataFile.Seek(int64(nv.Offset)*NeedlePaddingSize, 0); err != nil {
return false
}
oldNeedle := new(Needle)
oldNeedle.Read(v.dataFile, nv.Size, v.Version())
if len(oldNeedle.Data) == len(n.Data) && oldNeedle.Checksum == n.Checksum {
length := len(n.Data)
for i := 0; i < length; i++ {
if n.Data[i] != oldNeedle.Data[i] {
return false
}
}
n.Size = oldNeedle.Size
return true
}
}
return false
}
func (v *Volume) write(n *Needle) (size uint32, err error) { func (v *Volume) write(n *Needle) (size uint32, err error) {
if v.readOnly { if v.readOnly {
err = fmt.Errorf("%s is read-only", v.dataFile) err = fmt.Errorf("%s is read-only", v.dataFile)
@ -165,6 +186,10 @@ func (v *Volume) write(n *Needle) (size uint32, err error) {
} }
v.accessLock.Lock() v.accessLock.Lock()
defer v.accessLock.Unlock() defer v.accessLock.Unlock()
if v.isFileUnchanged(n) {
size = n.Size
return
}
var offset int64 var offset int64
if offset, err = v.dataFile.Seek(0, 2); err != nil { if offset, err = v.dataFile.Seek(0, 2); err != nil {
return return

Loading…
Cancel
Save