Merge pull request #542 from pingcap/qiuyesuifeng/add-structure-hash-set-check

Add hash set check for not changed value.
This commit is contained in:
siddontang
2015-11-09 13:22:44 +08:00
3 changed files with 101 additions and 18 deletions

View File

@ -231,7 +231,7 @@ func (txn *dbTxn) Commit() error {
txn.close()
}()
return txn.doCommit()
return errors.Trace(txn.doCommit())
}
func (txn *dbTxn) CommittedVersion() (kv.Version, error) {

View File

@ -92,34 +92,40 @@ func (t *TxStructure) HGetInt64(key []byte, field []byte) (int64, error) {
}
func (t *TxStructure) updateHash(key []byte, field []byte, fn func(oldValue []byte) ([]byte, error)) error {
metaKey := t.encodeHashMetaKey(key)
meta, err := t.loadHashMeta(metaKey)
if err != nil {
return errors.Trace(err)
}
dataKey := t.encodeHashDataKey(key, field)
var oldValue []byte
oldValue, err = t.loadHashValue(dataKey)
oldValue, err := t.loadHashValue(dataKey)
if err != nil {
return errors.Trace(err)
}
if oldValue == nil {
meta.Length++
}
var newValue []byte
newValue, err = fn(oldValue)
newValue, err := fn(oldValue)
if err != nil {
return errors.Trace(err)
}
// Check if new value is equal to old value.
if bytes.Equal(oldValue, newValue) {
return nil
}
if err = t.txn.Set(dataKey, newValue); err != nil {
return errors.Trace(err)
}
return errors.Trace(t.txn.Set(metaKey, meta.Value()))
metaKey := t.encodeHashMetaKey(key)
meta, err := t.loadHashMeta(metaKey)
if err != nil {
return errors.Trace(err)
}
if oldValue == nil {
meta.Length++
if err = t.txn.Set(metaKey, meta.Value()); err != nil {
return errors.Trace(err)
}
}
return nil
}
// HLen gets the number of fields in a hash.

View File

@ -193,7 +193,7 @@ func (s *tesTxStructureSuite) TestHash(c *C) {
value, err = tx.HGet(key, []byte("fake"))
c.Assert(err, IsNil)
c.Assert(err, IsNil)
c.Assert(value, IsNil)
keys, err := tx.HKeys(key)
c.Assert(err, IsNil)
@ -224,13 +224,41 @@ func (s *tesTxStructureSuite) TestHash(c *C) {
c.Assert(err, IsNil)
c.Assert(l, Equals, int64(2))
// Test set new value which equals to old value.
value, err = tx.HGet(key, []byte("1"))
c.Assert(err, IsNil)
c.Assert(value, DeepEquals, []byte("1"))
err = tx.HSet(key, []byte("1"), []byte("1"))
c.Assert(err, IsNil)
value, err = tx.HGet(key, []byte("1"))
c.Assert(err, IsNil)
c.Assert(value, DeepEquals, []byte("1"))
l, err = tx.HLen(key)
c.Assert(err, IsNil)
c.Assert(l, Equals, int64(2))
n, err = tx.HInc(key, []byte("1"), 1)
c.Assert(err, IsNil)
c.Assert(n, Equals, int64(2))
l, err = tx.HLen(key)
c.Assert(err, IsNil)
c.Assert(l, Equals, int64(2))
n, err = tx.HInc(key, []byte("1"), 1)
c.Assert(err, IsNil)
c.Assert(n, Equals, int64(3))
l, err = tx.HLen(key)
c.Assert(err, IsNil)
c.Assert(l, Equals, int64(2))
n, err = tx.HGetInt64(key, []byte("1"))
c.Assert(err, IsNil)
c.Assert(n, Equals, int64(2))
c.Assert(n, Equals, int64(3))
l, err = tx.HLen(key)
c.Assert(err, IsNil)
@ -246,6 +274,55 @@ func (s *tesTxStructureSuite) TestHash(c *C) {
err = tx.HDel(key, []byte("fake_key"))
c.Assert(err, IsNil)
// Test set nil value.
value, err = tx.HGet(key, []byte("nil_key"))
c.Assert(err, IsNil)
c.Assert(value, IsNil)
l, err = tx.HLen(key)
c.Assert(err, IsNil)
c.Assert(l, Equals, int64(0))
err = tx.HSet(key, []byte("nil_key"), nil)
c.Assert(err, IsNil)
l, err = tx.HLen(key)
c.Assert(err, IsNil)
c.Assert(l, Equals, int64(0))
err = tx.HSet(key, []byte("nil_key"), []byte("1"))
c.Assert(err, IsNil)
l, err = tx.HLen(key)
c.Assert(err, IsNil)
c.Assert(l, Equals, int64(1))
value, err = tx.HGet(key, []byte("nil_key"))
c.Assert(err, IsNil)
c.Assert(value, DeepEquals, []byte("1"))
err = tx.HSet(key, []byte("nil_key"), nil)
c.Assert(err, NotNil)
l, err = tx.HLen(key)
c.Assert(err, IsNil)
c.Assert(l, Equals, int64(1))
value, err = tx.HGet(key, []byte("nil_key"))
c.Assert(err, IsNil)
c.Assert(value, DeepEquals, []byte("1"))
err = tx.HSet(key, []byte("nil_key"), []byte("2"))
c.Assert(err, IsNil)
l, err = tx.HLen(key)
c.Assert(err, IsNil)
c.Assert(l, Equals, int64(1))
value, err = tx.HGet(key, []byte("nil_key"))
c.Assert(err, IsNil)
c.Assert(value, DeepEquals, []byte("2"))
err = txn.Commit()
c.Assert(err, IsNil)