Version: 2023.2
LanguageEnglish
  • C#

IPropertyDatabaseView

interface in UnityEditor.Search

Suggest a change

Success!

Thank you for helping us improve the quality of Unity Documentation. Although we cannot accept all submissions, we do read each suggested change from our users and will make updates where applicable.

Close

Submission failed

For some reason your suggested change could not be submitted. Please <a>try again</a> in a few minutes. And thank you for taking the time to help us improve the quality of Unity Documentation.

Close

Cancel

Description

Interface of a PropertyDatabase view.

The idea of a PropertyDatabase view is similar to Windows' memory-mapped file views, although much simpler. Each PropertyDatabase view has its own filestream that can access the PropertyDatabase independently from other views. The views of a single PropertyDatabase are synchronized, so concurrent accesses are allowed. However, for concurrent accesses to work properly each thread must have its own instance of a view.

All operations available on the PropertyDatabase class are available on the view itself. When operating directly on the PropertyDatabase instance, an internal view is created to handle all the synchronization. Since we are dealing with files, opening a view has a non-negligible cost. Therefore, it is recommended to open a view once, and use it as long as possible before disposing it.

using System.Collections.Generic;
using NUnit.Framework;
using UnityEditor;
using UnityEditor.Search;
using UnityEngine;

static class Example_IPropertyDatabaseView
{
    // Where the property database will be written.
    const string propertyDatabaseFilePath = "Temp/test_ipropertydatabaseview_db";

    static PropertyDatabase propertyDatabase;

    static void InitializePropertyDatabase()
    {
        // Setup the property database. We configure it with automatic flushing so the file store
        // will be updated automatically after an update.
        propertyDatabase = new PropertyDatabase(propertyDatabaseFilePath, true);
    }

    static void ClearPropertyDatabase()
    {
        propertyDatabase.Clear();
        propertyDatabase.Dispose();
    }

    static PropertyDatabaseRecordKey GetPropertyKey(int id, IPropertyDatabaseView view)
    {
        return view.CreateRecordKey((ulong)id / 100, view.CreatePropertyHash((id % 100).ToString()));
    }

    static object LoadPropertyValue(int id, IPropertyDatabaseView view)
    {
        var recordKey = GetPropertyKey(id, view);
        if (view.TryLoad(recordKey, out object value))
            return value;

        // Fetch the value with the time consuming operation and store it for future
        // accesses.
        value = id.ToString();
        view.Store(recordKey, value);
        return value;
    }

    [MenuItem("Examples/IPropertyDatabaseView/Interface")]
    public static void RunExample()
    {
        InitializePropertyDatabase();
        if (!propertyDatabase.valid)
        {
            Debug.LogFormat(LogType.Error, LogOption.NoStacktrace, null, $"PropertyDatabase \"{propertyDatabase.filePath}\" failed to open properly.");
            return;
        }

        // Doing a change on the property database internally opens a view on the actual data,
        // which is non negligible. Therefore, it is advised to open a view once and use it as much as you
        // can.
        // Note: when doing concurrent accesses to the property database, each thread must have its own
        // view instance.
        var allValues = new Dictionary<int, object>();
        using (var view = propertyDatabase.GetView())
        {
            for (var i = 0; i < 1000; ++i)
            {
                var value = LoadPropertyValue(i, view);
                allValues.Add(i, value);
            }
        }

        // Validate everything is in the database
        using (var view = propertyDatabase.GetView())
        {
            for (var i = 0; i < 1000; ++i)
            {
                var key = GetPropertyKey(i, view);
                if (!view.TryLoad(key, out object value))
                    Assert.Fail("Record should be in the database.");
                Assert.AreEqual(i.ToString(), value);
            }
        }

        ClearPropertyDatabase();
    }
}

Additional resources: PropertyDatabase.GetView

Public Methods

ClearClears the entire content of the PropertyDatabase.
CreateDocumentKeyCreates a document key from a document identifier.
CreatePropertyHashCreates a property hash from a property path.
CreateRecordKeyCreates a record key from a document identifier and a property path.
EnumerateAllEnumerates all records stored in the PropertyDatabase
GetValueFromRecordDeserialize a record value into its proper type.
InvalidateInvalidates a single property record so it is no longer retrievable.
InvalidateMaskInvalidate all properties stored from multiple documents that match a document key mask.
IsPersistableTypeReturns a boolean indicating if a type can be persisted into the backing file.
StoreStores a document property.
SyncSynchronizes the views so they have access to the same content.
TryLoadLoads a single property, already deseriazed into an object.