### 여러 키를 읽어 하나에 쓰는 연산 일곱의 서명 Set difference( Collection> keys, AdvancedOperationPermit permit, MultiKeyPermit multiKeyPermit, OperationBudget budget); Set intersection( Collection> keys, AdvancedOperationPermit permit, MultiKeyPermit multiKeyPermit, OperationBudget budget); Set union( Collection> keys, AdvancedOperationPermit permit, MultiKeyPermit multiKeyPermit, OperationBudget budget); long bitOperation( BitmapOperation operation, BitmapKey destination, Collection sources, MultiKeyPermit permit, OperationBudget budget); long searchStore( GeoKey source, GeoKey destination, GeoSearchRequest request, MultiKeyPermit permit, OperationBudget budget); long count(Collection> keys, MultiKeyPermit permit); void merge( HyperLogLogKey destination, Collection> sources, MultiKeyPermit permit); ### 정책 카탈로그의 위험 등급 SDIFF: risk: R2 support: ADVANCED_TYPED read-only: true key-spec: "1 -1 1" required-policy: set-algebra SINTER: risk: R2 support: ADVANCED_TYPED read-only: true key-spec: "1 -1 1" required-policy: set-algebra SUNION: risk: R2 support: ADVANCED_TYPED read-only: true key-spec: "1 -1 1" required-policy: set-algebra BITOP: risk: R2 support: ADVANCED_TYPED key-spec: "2 -1 1" required-policy: multi-key-write PFCOUNT: risk: R2 support: ADVANCED_TYPED read-only: true key-spec: "1 -1 1" required-policy: multi-key-read PFMERGE: risk: R2 support: ADVANCED_TYPED key-spec: "1 -1 1" required-policy: multi-key-write GEOSEARCHSTORE: risk: R2 support: ADVANCED_TYPED key-spec: "1 2 1" required-policy: multi-key-write ### R2 요청에 budget이 비어 있으면 } if (request.budget().isEmpty()) { throw new RedisCommandRejectedException( "R2 command requires permit and budget", metadata(policy, OptionalInt.empty())); } ### 그래서 HyperLogLog 요청은 budget을 스스로 만든다 69: Optional.of(context.collectionBudget(rendered.qualified().size(), rendered.requestBytes())), 93: Optional.of(context.collectionBudget(qualified.size(), size)), long replyCeiling = (long) elements * limits.maxReplyBytesPerElement(); return new OperationBudget( elements, Math.max(1L, requestBytes), replyCeiling, limits.collectionTimeout()); ### 같은 식을 쓰는 다른 두 메서드 313: elements, Math.max(1L, requestBytes), replyCeiling, limits.collectionTimeout()); 336: Math.max(1L, requestBytes), 349: 1, Math.max(1L, requestBytes), limits.maxReplyBytesPerElement(), limits.scriptTimeout()); ### 그 설계를 적어 둔 곳 /** * The ceilings the typed operations apply when the public signature does not carry a budget. * *

Design section 10 gives some R2 methods a caller-supplied {@code OperationBudget} and others a * caller-supplied permit, but {@code CommandPolicyGuard} requires both for every R2 command. These * limits are what the SDK fills in for the half the signature omits, so an R2 command is never * admitted with an unbounded cost. The caller-supplied half always wins; this only supplies what * the caller had no way to pass. * ### 같은 패키지에서 반대로 적어 둔 곳 /** * Explicit bound a caller accepts for one advanced operation. * *

Every R2 API requires a budget. The budget is never optional and never defaulted, because the * whole point is that the caller states the cost it is prepared to pay before Redis is asked. */