Iray SDK API nvidia_logo_transpbg.gif Up
Database Access

Provides access to the database using concepts like scopes and transactions. More...

Classes

class  mi::neuraylib::IDatabase
 This interface is used to interact with the distributed database. More...
 
class  mi::neuraylib::IScope
 A scope is the context which determines the visibility of database elements. More...
 
class  mi::neuraylib::IJob_execution_context
 Provides information about the context in which a job is executed. More...
 
class  mi::neuraylib::ITransaction
 A transaction provides a consistent view on the database. More...
 

Detailed Description

Provides access to the database using concepts like scopes and transactions.

Database limitations

The database does not support certain usage patterns. These patterns can not be rejected programmatically, but need to be ensured by the user for proper operation.

Note
This section mentions some DB internals, e.g. tags, which are not further explained here.

Identical names due to different scopes

See mi::neuraylib::IScope for general documentation about scopes.

Be careful when storing DB elements of the same name in different scopes. If the scopes are not in a parent-child relation, then the following limitation does not apply since no transaction will ever see both elements. But if the scopes are in a parent-child relation, then it is required that the store operation happens first in the parent scope and that this element is visible in the child scope before the store operation in that child scope occurs (in the same transaction, or with different transactions where the first one is committed before the second one is started). Otherwise, this results in different DB elements of the same name (and not just different versions of the same DB elements as it would happen when the correct order is observed).

Example (creation in wrong order):

neuray->get_api_component<mi::neuraylib::IDatabase>());
mi::base::Handle<mi::neuraylib::IScope> parent_scope( database->get_global_scope());
database->create_scope( parent_scope.get()));
// DB element with name "texture" is created first in the child scope ...
child_scope->create_transaction());
{
child_transaction->create<mi::neuraylib::ITexture>( "Texture"));
child_transaction->store( texture.get(), "texture");
}
child_transaction->commit();
parent_scope->create_transaction());
{
parent_transaction->create<mi::neuraylib::ITexture>( "Texture"));
// ... and is not visible here.
parent_transaction->store( texture.get(), "texture");
}
parent_transaction->commit();
// The name "texture" maps now to two different tags. Both tags are visible from the child scope via
// tag references (not part of this example), but only one of them via name.
Handle class template for interfaces, automatizing the lifetime control via reference counting.
Definition: handle.h:112
This interface is used to interact with the distributed database.
Definition: idatabase.h:211
Textures add image processing options to images.
Definition: itexture.h:65

While such a situation is not necessarily a problem for the database itself, it leads to unexpected behavior on the user side, as accesses might return different instances, depending on the details of the access method.

This limitation does not apply if there is already a DB element with that name accessible at the time of the store operation, i.e., the method does not create a new DB element, but essentially overwrites/edits an existing one.

Identical names due to parallel transactions

See mi::neuraylib::ITransaction for general documentation about transactions.

Be careful when storing DB elements of the same name in parallel transactions, unless the corresponding scopes are different and not in a parent-child relation to each other. Failure to observe this limitation results in different DB elements of the same name (and not just different versions of the same DB elements as it would happen with serialized transactions).

Example (wrong creation in parallel transactions):

neuray->get_api_component<mi::neuraylib::IDatabase>());
mi::base::Handle<mi::neuraylib::IScope> scope( database->get_global_scope());
scope->create_transaction());
scope->create_transaction());
{
transaction1->create<mi::neuraylib::ITexture>( "Texture"));
transaction1->store( texture.get(), "texture");
}
{
transaction2->create<mi::neuraylib::ITexture>( "Texture"));
transaction2->store( texture.get(), "texture");
}
transaction1->commit();
transaction2->commit();
// The name "texture" maps now to two different tags. Both tags are visible via tag references from
// the global scope (not part of this example), but only one of them via name.

While such a situation is not necessarily a problem for the database itself, it leads to unexpected behavior on the user side, as accesses might return different instances, depending on the details of the access method.

This limitation does not apply if there is already a DB element with that name accessible at the time of the store operations, i.e., the method does not create new DB elements, but essentially overwrites/edits an existing one.

Note that editing (as opposed to storing) the very same DB element in parallel transactions is supported by the database, but it is discouraged, since the semantics might not be as desired (see mi::neuraylib::ITransaction ).

References to elements in more private scopes

See mi::neuraylib::IScope for general documentation about scopes.

Be careful when creating references to DB elements that exist in a different scope than the referencing element. References to elements in parent scopes (or the the same scope) are perfectly fine. But you must not create references to DB elements that exist only in a more private scope. Typically, this happens when using mi::neuraylib::ITransaction::store() with an (explicit) wrong privacy level.

Example (invalid reference to element in more private scope):

neuray->get_api_component<mi::neuraylib::IDatabase>());
mi::base::Handle<mi::neuraylib::IScope> parent_scope( database->get_global_scope());
database->create_scope( parent_scope.get()));
child_scope->create_transaction());
{
child_transaction->create<mi::neuraylib::IImage>( "Image"));
check_success( 0 == child_transaction->store( image.get(), "image"));
child_transaction->create<mi::neuraylib::ITexture>( "Texture"));
check_success( 0 == texture->set_image( "image"));
// Triggers an error message since "texture" is to be stored in the parent scope (due to
// explicit privacy level 0), but references "image" in the child scope.
check_success( 0 == child_transaction->store( texture.get(), "texture", 0));
}
child_transaction->commit();
parent_scope->create_transaction());
{
parent_transaction->access<mi::neuraylib::ITexture>( "texture"));
// Triggers a fatal message about an invalid tag access.
const char name = texture->get_image();
}
parent_transaction->commit();
This interface represents a pixel image file.
Definition: iimage.h:65

A reference to an element in a more private scope triggers an error message when the referencing element is stored in the DB, but does not prevent the operation from being completed nor is it signaled via a return code. As soon as the incorrect reference is used, this triggers a fatal error message (and the process aborts if it returns from the logger callback). Even if the incorrect reference is never used, its existence hints at a conceptual error in the way the application uses scopes.