diff --git a/index/delete.go b/index/delete.go index 49825ea..9c9b7ef 100644 --- a/index/delete.go +++ b/index/delete.go @@ -43,6 +43,11 @@ func (ri *redisIndex) spaceDelete(ctx context.Context, key Key, entry groupSpace return spaceId == key.SpaceId }) + // in case of isolated space - return limit to the group + if entry.space.Limit != 0 { + entry.group.Limit += entry.space.Limit + } + _, err = ri.cl.Pipelined(ctx, func(pipe redis.Pipeliner) error { entry.group.Save(ctx, pipe) pipe.Del(ctx, sk) diff --git a/index/delete_test.go b/index/delete_test.go index ce6a165..e047e38 100644 --- a/index/delete_test.go +++ b/index/delete_test.go @@ -45,6 +45,9 @@ func TestRedisIndex_SpaceDelete(t *testing.T) { assert.NotEmpty(t, groupInfo.BytesUsage) assert.Contains(t, groupInfo.SpaceIds, key.SpaceId) + require.NoError(t, fx.SetGroupLimit(ctx, key.GroupId, 5000)) + require.NoError(t, fx.SetSpaceLimit(ctx, key, 4000)) + ok, err = fx.SpaceDelete(ctx, key) require.NoError(t, err) assert.True(t, ok) @@ -53,6 +56,8 @@ func TestRedisIndex_SpaceDelete(t *testing.T) { require.NoError(t, err) assert.Empty(t, groupInfo.BytesUsage) assert.NotContains(t, groupInfo.SpaceIds, key.SpaceId) + assert.Equal(t, uint64(5000), groupInfo.AccountLimit) + assert.Equal(t, uint64(5000), groupInfo.Limit) // second call ok, err = fx.SpaceDelete(ctx, key) diff --git a/index/limit.go b/index/limit.go index eecc45e..ea55256 100644 --- a/index/limit.go +++ b/index/limit.go @@ -2,6 +2,7 @@ package index import ( "context" + "strconv" "strings" "github.com/anyproto/any-sync/commonfile/fileproto/fileprotoerr" @@ -153,20 +154,23 @@ func (op *spaceLimitOp) isolateSpace(ctx context.Context, entry groupSpaceEntry) sk := spaceKey(key) gk := groupKey(key) - keys, err := op.cl.HKeys(ctx, sk).Result() + keys, err := op.cl.HGetAll(ctx, sk).Result() if err != nil { return } var cids []cid.Cid + var cidRefs []int64 // collect all cids - for _, k := range keys { + for k, val := range keys { if strings.HasPrefix(k, "c:") { c, cErr := cid.Decode(k[2:]) if cErr != nil { log.WarnCtx(ctx, "can't decode cid", zap.String("cid", k[2:]), zap.Error(cErr)) } else { + ref, _ := strconv.ParseInt(val, 10, 64) cids = append(cids, c) + cidRefs = append(cidRefs, ref) } } } @@ -183,7 +187,7 @@ func (op *spaceLimitOp) isolateSpace(ctx context.Context, entry groupSpaceEntry) var groupDecrResults = make([]*redis.IntCmd, len(cids)) if _, err = op.cl.TxPipelined(ctx, func(pipe redis.Pipeliner) error { for i, c := range cids { - groupDecrResults[i] = pipe.HIncrBy(ctx, gk, cidKey(c), -1) + groupDecrResults[i] = pipe.HIncrBy(ctx, gk, cidKey(c), -cidRefs[i]) } return nil }); err != nil {