Skip to content

Conversation

@melekr
Copy link
Contributor

@melekr melekr commented Oct 22, 2025

WHY

  • Customers observed registry growth over time when the same scoped attribute key is added repeatedly.
  • Using a set and skipping redundant writes eliminates bloat and reduces I/O without changing public APIs.

What changed

  • Deduplication: Scoped attribute keys are now stored via an in-memory set and serialized back to a compact list preventing duplicate entries.
  • Avoid No-op writes: If a scoped attribute value hasn’t changed, no PlayerPrefs write occurs.
  • Safe cleanup & read: Safe JSON parsing in CleanScopedAttributes and GetScopedAttributes.
  • NO JSON format changes
  • Tests: Add Test coverage for scoped attribute persistence in Windows NativeClient

ref: BT-5953

…efs/registry.

Fix unbounded growth of scoped attributes stored in PlayerPrefs/registry on Windows.
- Maintain a HashSet of keys and serialize back to a compact List to prevent duplicates
- Skip PlayerPrefs writes when the new value matches the stored value
- Parse + cleanup in CleanScopedAttributes/GetScopedAttributes
@melekr melekr self-assigned this Oct 22, 2025
…lient

- Verifies duplicate keys are not added repeatedly
- Confirms PlayerPrefs writes are skipped when value unchanged
- Retains backward compatibility with legacy attribute reads

try
{
var attributes = JsonUtility.FromJson<ScopedAttributesContainer>(attributesJson);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

its our contract, and it should never break.

try
{
var attributes = JsonUtility.FromJson<ScopedAttributesContainer>(attributesJson);
if (attributes?.Keys != null)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the if statement is invalid, then the catch should capture this. Since this is our contract and we require the people to follow it, why we should check it?

{
try
{
var container = JsonUtility.FromJson<ScopedAttributesContainer>(attributesJson);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why you cannot deserialize array into hashset?

{
var container = new ScopedAttributesContainer
{
Keys = keys.OrderBy(k => k, StringComparer.Ordinal).ToList()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do you need it? also the same order needs to be applied to values.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants