Skip to main content

Introduction

One of the central features of Caché is its multidimensional storage engine. This feature lets applications store data in compact, efficient, multidimensional sparse arrays. These arrays are referred to as globals.

This document describes:

Features

Globals provide an easy-to-use way to store data in persistent, multidimensional arrays.

For example, you can associate the value “Red” with the key “Color” using a global named Settings:

   SET ^Settings("Color")="Red"
   WRITE !,^Settings("Color")

You can take advantage of the multidimensional nature of globals to define a more complex structure:

^Settings("Auto1","Properties","Color") = "Red"
^Settings("Auto1","Properties","Model") = "SUV"
^Settings("Auto2","Owner") = "Mo"
^Settings("Auto2","Properties","Color") = "Green"

Globals have the following features:

  • Simple to use — Globals are as easy to use as other programming language variables. A comprehensive set of commands in both the ObjectScript language and the Caché Basic scripting language make it extremely easy to use globals within applications.

  • Multidimensional — You can specify the address of a node within a global using any number of subscripts. For example, in ^Settings("Auto2","Properties","Color"), the subscript Color is a third-level node within the Settings global. Subscripts can be integer, numeric, or string values, and need not be contiguous.

  • Sparse — The subscripts used to address global nodes are highly compacted and need not have contiguous values.

  • Efficient — The operations on globals — inserting, updating, deleting, traversing, and retrieving — are all highly optimized for maximum performance and concurrency. There are additional commands for specialized operations (such as bulk inserts of data). There is a special set of globals designed for temporary data structures (such as for sorting records).

  • Reliable — The Caché database provides a number of mechanisms to ensure the reliability of data stored within globals, including both logical-level and physical-level journaling. Data stored within globals is backed up when a database backup operation is performed.

  • Distributed — Caché provides a number of ways to control the physical location of data stored within globals. You can define a physical database used to store a global, or distribute portions of a global across several databases. Using the distributed database features of Caché, you can share globals across a network of database and application server systems. In addition, by means of data shadowing technology, data stored within globals on one system can be automatically replicated on another system.

  • Concurrent — Globals support concurrent access among multiple processes. Setting and retrieving values within individual nodes (array elements) is always atomic: no locking is required to guarantee reliable concurrent access. In addition, Caché supports a powerful set of locking operations that can be used to provide concurrency for more complex cases involving multiple nodes. When using Object or SQL access, this concurrency is handled automatically.

  • Transactional — Caché provides commands that define transaction boundaries; you can start, commit, or rollback a transaction. In the event of a rollback, all modifications made to globals within the transaction are undone; the contents of the database are restored to their pre-transaction state. By using the various Caché locking operations in conjunction with transactions, you can perform traditional ACID transactions using globals. (An ACID transaction provides Atomicity, Consistency, Isolation, and Durability.) When using object or SQL access, transactions are handled automatically.

Note:

The globals described in this document should not be confused with another type of Caché array variable: process-private globals. Process-private globals are not persistent; they persist only for the duration of the process that created them. Process-private globals are also not concurrent; they can only be accessed by the process that created them. A process-private global can be easily distinguished from a global by its multi-character name prefix: either ^|| or ^|"^"|.

Examples

A simple example can demonstrate the ease and performance of globals. The following program example creates a 10,000–node array (deleting it first if present) and stores it in the database. You can try this to get a sense of the performance of globals:

—Creating a Persistent Array—
Creating a Persistent Array
 Set start = $ZH  // get current time

 Kill ^Test.Global
 For i = 1:1:10000 {
     Set ^Test.Global(i) = i
 }

 Set elap = $ZH - start  // get elapsed time
 Write "Time (seconds): ",elap

We can also see how long it takes to iterate over and read the values in the array (make sure to run the above example first to build the array):

—Reading a Persistent Array—
Reading a Persistent Array
 Set start = $ZH  // get current time
 Set total = 0
 Set count = 0

 // get key and value for first node
 Set i = $Order(^Test.Global(""),1,data)

 While (i '= "") {
     Set count = count + 1
     Set total = total + data

    // get key and value for next node
    Set i = $Order(^Test.Global(i),1,data)
 }

 Set elap = $ZH - start  // get elapsed time

 Write "Nodes:          ",count,!
 Write "Total:          ",total,!
 Write "Time (seconds): ",elap,!

Use in Applications

Within Caché applications, globals are used in many ways, including:

  • As the underlying storage mechanism shared by the object and SQL engines.

  • As the mechanism used to provide a variety of indices, including bitmap indices, for object and SQL data.

  • As a work space for performing certain operations that may not fit within process memory. For example, the SQL engine uses temporary globals for sorting data when there is no preexisting index available for this purpose.

  • For performing specialized operations on persistent objects or SQL tables that are difficult or inefficient to express in terms of object or SQL access. For example, you can define a method (or stored procedure or web method) to perform specialized analysis on data held in a table. By using methods, such an operation is completely encapsulated; the caller simply invokes the method.

  • To implement application-specific, customized storage structures. Many applications have the need to store data that is difficult to express relationally. Using globals you can define custom structures and make them available to outside clients via object methods.

  • For a variety of special purpose data structures used by the Caché system, such as configuration data, class definitions, error messages, and executable code.

Globals are not constrained by the confines of the relational model. They provide the freedom to develop customized structures optimized for specific applications. For many applications, judicious use of globals can be a secret weapon delivering performance that relational application developers can only dream about.

Whether your application makes direct use of globals or not, it is useful to understand their operation. Understanding globals and their capabilities will help you to design more efficient applications as well as provide help with determining the optimal deployment configuration for your applications.

FeedbackOpens in a new tab