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:
@ -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) {
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user