func seekAndCopySyncKV(it *Iterator, p *proto.KeyValue) (uint8, uint16, bool) { p.CtrlFlag &^= 0xFF slotId, dbId, tableId, colSpace, rowKey, colKey := parseRawKey(it.Key()) switch colSpace { case proto.ColSpaceDefault: value, score := parseRawValue(it.Value()) p.SetValue(value) p.SetScore(score) case proto.ColSpaceScore1: it.Seek(getRawKey(dbId, tableId, colSpace+1, rowKey, nil)) if !it.Valid() { return dbId, slotId, false } return seekAndCopySyncKV(it, p) case proto.ColSpaceScore2: value, score := parseRawValue(it.Value()) p.SetValue(value) p.SetScore(score) } p.TableId = tableId p.SetColSpace(colSpace) p.RowKey = rowKey p.ColKey = colKey return dbId, slotId, true }
func getTestKV(tableId uint8, rowKey, colKey, value []byte, score int64, cas uint32) proto.KeyValue { var kv proto.KeyValue kv.TableId = tableId kv.RowKey = rowKey kv.ColKey = colKey kv.SetValue(value) kv.SetScore(score) kv.SetCas(cas) return kv }
func (tbl *Table) incrKV(wb *WriteBatch, zop bool, dbId uint8, kv *proto.KeyValue, wa *WriteAccess) error { kv.CtrlFlag &^= 0xFF // Clear all ctrl flags if len(kv.RowKey) == 0 { kv.SetErrCode(table.EcInvRowKey) return nil } if !wa.CheckKey(dbId, kv.TableId, kv.RowKey) { kv.SetErrCode(table.EcWriteSlave) return nil } var rawColSpace uint8 = proto.ColSpaceDefault if zop { rawColSpace = proto.ColSpaceScore2 } var rawKey = getRawKey(dbId, kv.TableId, rawColSpace, kv.RowKey, kv.ColKey) var lck = tbl.tl.GetLock(rawKey) lck.Lock() defer lck.Unlock() if !wa.replication && kv.Cas != 0 { var cas = lck.GetCas(rawKey) if cas != kv.Cas { kv.SetErrCode(table.EcCasNotMatch) return nil } } lck.ClearCas(rawKey) var err error var newScore = kv.Score var oldVal []byte var oldScore int64 if zop { if wb == nil { wb = tbl.db.NewWriteBatch() defer wb.Destroy() } oldVal, err = tbl.db.Get(nil, rawKey) if err != nil { kv.SetErrCode(table.EcReadFail) return err } else if oldVal != nil { oldVal, oldScore = parseRawValue(oldVal) newScore += oldScore if newScore != oldScore { var scoreKey = getRawKey(dbId, kv.TableId, proto.ColSpaceScore1, kv.RowKey, newScoreColKey(oldScore, kv.ColKey)) tbl.db.Del(scoreKey, wb) } else { // nothing changed kv.SetValue(oldVal) kv.SetScore(newScore) return nil } } tbl.db.Put(rawKey, getRawValue(oldVal, newScore), wb) var scoreKey = getRawKey(dbId, kv.TableId, proto.ColSpaceScore1, kv.RowKey, newScoreColKey(newScore, kv.ColKey)) tbl.db.Put(scoreKey, getRawValue(oldVal, 0), wb) kv.SetValue(oldVal) kv.SetScore(newScore) err = tbl.db.Commit(wb) if err != nil { kv.SetErrCode(table.EcWriteFail) return err } } else { oldVal, err = tbl.db.Get(nil, rawKey) if err != nil { kv.SetErrCode(table.EcReadFail) return err } else if oldVal != nil { oldVal, oldScore = parseRawValue(oldVal) newScore += oldScore if newScore == oldScore { // nothing changed kv.SetValue(oldVal) kv.SetScore(newScore) return nil } } kv.SetValue(oldVal) kv.SetScore(newScore) err = tbl.db.Put(rawKey, getRawValue(oldVal, newScore), nil) if err != nil { kv.SetErrCode(table.EcWriteFail) return err } } return nil }