c++ collections guide and referencemedia.progress.com/realtime/techsupport/...contents 4 4 c++...

302
C++ Collections Guide and Reference Release 6.3

Upload: others

Post on 17-Jun-2020

22 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

C++ Collections Guide and Reference

Release 6.3

Page 2: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Copyright

C++ Collections Guide and Reference

ObjectStore Release 6.3 for all platforms, October 2005

© 2005 Progress Software Corporation. All rights reserved.

Progress® software products are copyrighted and all rights are reserved by Progress Software Corporation. This manual is also copyrighted and all rights are reserved. This manual may not, in whole or in part, be copied, photocopied, translated, or reduced to any electronic medium or machine-readable form without prior consent, in writing, from Progress Software Corporation.

The information in this manual is subject to change without notice, and Progress Software Corporation assumes no responsibility for any errors that may appear in this document.

The references in this manual to specific platforms supported are subject to change.

A (and design), Allegrix, Allegrix (and design), Apama, Business Empowerment, DataDirect (and design), DataDirect Connect, DataDirect Connect OLE DB, DirectAlert, EasyAsk, EdgeXtend, Empowerment Center, eXcelon, Fathom,, IntelliStream, O (and design), ObjectStore, OpenEdge, PeerDirect, P.I.P., POSSENET, Powered by Progress, Progress, Progress Dynamics, Progress Empowerment Center, Progress Empowerment Program, Progress Fast Track, Progress OpenEdge, Partners in Progress, Partners en Progress, Persistence, Persistence (and design), ProCare, Progress en Partners, Progress in Progress, Progress Profiles, Progress Results, Progress Software Developers Network, ProtoSpeed, ProVision, SequeLink, SmartBeans, SpeedScript, Stylus Studio, Technical Empowerment, WebSpeed, and Your Software, Our Technology-Experience the Connection are registered trademarks of Progress Software Corporation or one of its subsidiaries or affiliates in the U.S. and/or other countries. AccelEvent, A Data Center of Your Very Own, AppsAlive, AppServer, ASPen, ASP-in-a-Box, BusinessEdge, Cache-Forward, DataDirect, DataDirect Connect64, DataDirect Technologies, DataDirect XQuery, DataXtend, Future Proof, ObjectCache, ObjectStore Event Engine, ObjectStore Inspector, ObjectStore Performance Expert, POSSE, ProDataSet, Progress Business Empowerment, Progress DataXtend, Progress for Partners, Progress ObjectStore, PSE Pro, PS Select, SectorAlliance, SmartBrowser, SmartComponent, SmartDataBrowser, SmartDataObjects, SmartDataView, SmartDialog, SmartFolder, SmartFrame, SmartObjects, SmartPanel, SmartQuery, SmartViewer, SmartWindow, WebClient, and Who Makes Progress are trademarks or service marks of Progress Software Corporation or one of its subsidiaries or affiliates in the U.S. and other countries. Java and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. Any other trademarks or trade names contained herein are the property of their respective owners.

ObjectStore includes software developed by the Apache Software Foundation (http://www.apache.org/). Copyright 2000-2003 The Apache Software Foundation. All rights reserved. The names "Ant," "Xerces," and "Apache Software Foundation" must not be used to endorse or promote products derived from the Products without prior written permission. Any product derived from the Products may not be called "Apache", nor may "Apache" appear in their name, without prior written permission. For written permission, please contact [email protected].

September 2005

Page 3: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Contents

Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .15

Chapter 1 Introducing Collections . . . . . . . . . . . . . . . . . . . . . . . .19Overview of Collections, Queries, and Indexes . . . . . . . . . . . . . . . 19

Collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

Query Processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

Data Access . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

Query Optimizer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

Indexes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

Collections Class Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20Collections Query and Manipulation Features. . . . . . . . . . . . . . . . . 21Requirements for Collections Applications . . . . . . . . . . . . . . . . . . . 21

Including Collections Header Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

Initializing the Collections Facility . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

Generating the Application Schema. . . . . . . . . . . . . . . . . . . . . . . . . . . 22

Linking with ObjectStore Libraries. . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

Introductory Collections Example. . . . . . . . . . . . . . . . . . . . . . . . . 22Choosing a Collection Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

os_Set and os_set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

os_Bag and os_bag. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

os_List and os_list . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

os_Array and os_array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

os_Dictionary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

Using a Decision Tree to Select a Collection Type . . . . . . . . . . . . . . . . . 26

Collection Characteristics and Behaviors . . . . . . . . . . . . . . . . . . . . 26Collections Store Pointers to Objects . . . . . . . . . . . . . . . . . . . . . . . . . . 26

Collections Can Be Transient or Persistent . . . . . . . . . . . . . . . . . . . . . . 26

Parameterized and Nonparameterized Collections . . . . . . . . . . . . . . . . . 27

Class Hierarchy Diagram . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

Collection Behaviors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

Expected Collection Size . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

Performing pick() on an Empty Collection . . . . . . . . . . . . . . . . . . . . . . 28

Release 6.3 3

Page 4: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Contents

4

Templated and Nontemplated Collections. . . . . . . . . . . . . . . . . . . .29Using Collections with the Element Type Parameter . . . . . . . . . . . . . . . .29

Using Collections Without Parameterization . . . . . . . . . . . . . . . . . . . . . .30

Chapter 2 Performing Basic Collections Functions . . . . . . . . . . . . .33Creating Collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .33

General Guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .33

Deleting Collections. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .34Inserting Collection Elements . . . . . . . . . . . . . . . . . . . . . . . . . . . .34

Inserting Dictionary Elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .34

Duplicate Insertions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .34

Null Insertions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .35

Ordered Collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .35

Duplicate Keys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .35

Removing Collection Elements with remove(). . . . . . . . . . . . . . . . .35Ordered Collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .35

Removing Dictionary Elements. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .36

Testing Collection Membership with contains() . . . . . . . . . . . . . . . .36Finding the Count of an Element with count(). . . . . . . . . . . . . . . . .37Finding the Size of a Collection with cardinality() . . . . . . . . . . . . . .37Copying, Combining, and Comparing Collections. . . . . . . . . . . . . . .37

Dual Purpose of the Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .38

Ordered Collections and Collections with Duplicates . . . . . . . . . . . . . . . .38

Compiling for Collections Optimization. . . . . . . . . . . . . . . . . . . . . .39

Chapter 3 Using Cursors to Navigate Collections. . . . . . . . . . . . . .41Description of a Cursor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .41Creating Default Cursors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .42Traversing Collections with Default Cursors . . . . . . . . . . . . . . . . . .43

Positioning the Cursor at the Collection’s First Element . . . . . . . . . . . . . .44

Moving the Cursor to the Collection’s Next Element . . . . . . . . . . . . . . . .44

Is the Cursor at a Nonnull Element? . . . . . . . . . . . . . . . . . . . . . . . . . . .44

Rebinding Cursors to Another Collection . . . . . . . . . . . . . . . . . . . .45Accessing Collection Elements with a Cursor or Ordinal Value. . . . . .45Manipulating First and Last Elements in a Collection . . . . . . . . . . . .46Using os_address_space_marker Cursors . . . . . . . . . . . . . . . . . . .47

Chapter 4 Using Dictionaries . . . . . . . . . . . . . . . . . . . . . . . . . . .49Creating Dictionaries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .49Marking Persistent Dictionaries. . . . . . . . . . . . . . . . . . . . . . . . . . .51Marking Transient Dictionaries . . . . . . . . . . . . . . . . . . . . . . . . . . .51

4 C++ Collections Guide and Reference

Page 5: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Contents

Dictionary Behavior . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52Visiting the Elements with Specified Keys . . . . . . . . . . . . . . . . . . . 52

Picking the Element with a Specified Key . . . . . . . . . . . . . . . . . . . . . . . 52

Writing Destructors for Dictionaries . . . . . . . . . . . . . . . . . . . . . . . 54Example of Using Dictionaries . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

Chapter 5 Performing Advanced Collections Operations . . . . . . . . .61Using Paths in Navigation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62Creating Paths. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62

Simple Paths . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62

Multiple Member Paths . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

Rank and Hash Functions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64

Paths and Member Functions. . . . . . . . . . . . . . . . . . . . . . . . . . . . 64Restrictions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64

Prerequisites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64

os_query_function() Macro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65

os_query_function_returning_ref() Macro . . . . . . . . . . . . . . . . . . . . . . 65

os_query_function_body() Macro . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66

OS_MARK_QUERY_FUNCTION() Macro . . . . . . . . . . . . . . . . . . . . . . . . 66

os_query_function_body_returning_ref() Macro . . . . . . . . . . . . . . . . . . 66

Path String Syntax Extension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67

Index Maintenance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68

Controlling Traversal Order . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68Default Traversal Order . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68

Address Order Traversal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68

Rank-Function-Based Traversal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69

Path-Based Traversal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69

Using Ranges in Navigation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70Ranges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70

Specifying Collection Ranges . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71Ranges with Only One Bound . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71

Ranges with Both an Upper and Lower Bound . . . . . . . . . . . . . . . . . . . 72

Restricting the Elements Visited in a Traversal . . . . . . . . . . . . . . . 73Dictionaries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73

Duplicates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74

Performing Collection Updates During Traversal . . . . . . . . . . . . . . 74Retrieving Uniquely Specified Collection Elements . . . . . . . . . . . . . 74

Ordered Collections. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75

Selecting Individual Collection Elements with pick() . . . . . . . . . . . . 75Dictionaries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76

Picking an Arbitrary Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77

Release 6.3 5

Page 6: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Contents

6

Consolidating Duplicates with operator =() . . . . . . . . . . . . . . . . . .77Supplying Rank and Hash Functions . . . . . . . . . . . . . . . . . . . . . . .78

os_index_key() Macro. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .78

Rank Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .78

Hash Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .79

Example Use of Rank and Hash Functions . . . . . . . . . . . . . . . . . . . . . . .79

Specifying Expected Size . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .80

Chapter 6 Querying Collections. . . . . . . . . . . . . . . . . . . . . . . . . .81Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .81Performing Queries with query(). . . . . . . . . . . . . . . . . . . . . . . . . .82

Example Query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .82

Query Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .82

C++ Control Expressions in Query Strings. . . . . . . . . . . . . . . . . . . . . . .84

Matching Patterns in Query Strings. . . . . . . . . . . . . . . . . . . . . . . . . . . .84

Calling Functions in Query Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . .86

Nested Queries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .87

Queries Compared to Collection Traversals . . . . . . . . . . . . . . . . . . . . . .88

Single-Element Queries with query_pick() . . . . . . . . . . . . . . . . . . .88Example query_pick() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .89

Existential Queries with exists() . . . . . . . . . . . . . . . . . . . . . . . . . .89Example exists() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .89

Query Functions and Nested Queries. . . . . . . . . . . . . . . . . . . . . . .90Nested Query Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .90

Nested Existential Queries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .91Example of a Nested Existential Query . . . . . . . . . . . . . . . . . . . . . . . . .91

Preanalyzed Queries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .92Creating Query Objects with the os_coll_query Class . . . . . . . . . . . . . . .92

Destroying Query Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .93

Function Calls in Query Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .93

Creating Bound Queries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .93

Executing Bound Queries. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .94

Chapter 7 Using Indexes to Optimize Performance . . . . . . . . . . . .95Indexes and Query Optimization. . . . . . . . . . . . . . . . . . . . . . . . . .95

Adding an Index to a Collection with add_index(). . . . . . . . . . . . . . . . . .96

Index Maintenance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .96

Pointer-Valued Members and char* Keys. . . . . . . . . . . . . . . . . . . . . . . .96

Floating-point Keys. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .96

Indexes and Performance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .97

Dropping Indexes from a Collection with drop_index() . . . . . . . . . . . . . .97

6 C++ Collections Guide and Reference

Page 7: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Contents

Testing for the Presence of an Index with has_index() . . . . . . . . . . . . . 98

Indexes and Complex Paths . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99

Monitoring Index Use During Queries . . . . . . . . . . . . . . . . . . . . . . . . . 99

Debugging Index Problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .100

Index Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101os_index_path::ordered Enumerator. . . . . . . . . . . . . . . . . . . . . . . . . .101

Index Option Enumerators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .101

Performing or Enabling Index Maintenance . . . . . . . . . . . . . . . . . 103Paths as Indexes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .103

Declaring an os_backptr Member. . . . . . . . . . . . . . . . . . . . . . . . 104Inheritance of the os_backptr. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .105

Enabling Automatic Index Maintenance . . . . . . . . . . . . . . . . . . . 105os_indexable_member() Macro . . . . . . . . . . . . . . . . . . . . . . . . . . . . .107

os_indexable_body() Macro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .107

os_index() Macro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .107

Avoid White Space in Macro Arguments. . . . . . . . . . . . . . . . . . . . . . . .107

The Actual Value/Apparent Value Distinction . . . . . . . . . . . . . . . . . . . .108

char* and char() Members. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .108

Restriction on Updates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .109

User-Controlled Index Maintenance with an os_backptr . . . . . . . . 109Making and Breaking Links on Indexable Data Members . . . . . . . . . . . .109

Making and Breaking Links to Indexed Member Functions . . . . . . . . . . .111

User-Controlled Index Maintenance Without an os_backptr. . . . . . 112Rank and Hash Function Requirements. . . . . . . . . . . . . . . . . . . . 112Example: Member Function Calls in Query and Path Strings . . . . . 112

Rectangle Header File — rectangle.hh . . . . . . . . . . . . . . . . . . . . . . . . .113

Schema Source File — schema.cc . . . . . . . . . . . . . . . . . . . . . . . . . . . .114

Main Program File — rectangle.cc . . . . . . . . . . . . . . . . . . . . . . . . . . . .115

Chapter 8 Class Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122os_Array. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122

os_Array::operator =() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .127

os_Array::operator |=() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .127

os_Array::operator &=() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .128

os_Array::operator –=() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .128

os_Array::os_Array() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .128

os_Array::set_cardinality() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .129

os_array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129os_array::operator =() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .133

os_array::operator |=() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .134

Release 6.3 7

Page 8: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Contents

8

os_array::operator &=() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134

os_array::operator –=() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134

os_array::os_array() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134

os_array::set_cardinality() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135

os_backptr. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135os_backptr::break_link(). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136

os_backptr::make_link(). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137

os_Bag . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138os_Bag::operator =() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143

os_Bag::operator |=() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143

os_Bag::operator &=() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143

os_Bag::operator –=() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144

os_Bag::os_Bag() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144

os_bag . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144os_bag::operator =() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148

os_bag::operator |=() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148

os_bag::operator &=() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148

os_bag::operator –=() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148

os_bag::os_bag(). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149

os_bound_query. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149os_bound_query::os_bound_query() . . . . . . . . . . . . . . . . . . . . . . . . . 149

os_Collection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149os_Collection::contains() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154

os_Collection::count() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154

os_Collection::exists() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154

os_Collection::insert() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155

os_Collection::insert_after() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155

os_Collection::insert_before() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155

os_Collection::insert_first() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156

os_Collection::insert_last() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156

os_Collection::only() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157

os_Collection::operator os_Array(). . . . . . . . . . . . . . . . . . . . . . . . . . . 157

os_Collection::operator const os_Array() . . . . . . . . . . . . . . . . . . . . . . 157

os_Collection::operator os_Bag() . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157

os_Collection::operator const os_Bag() . . . . . . . . . . . . . . . . . . . . . . . 157

os_Collection::operator os_List() . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157

os_Collection::operator const os_List() . . . . . . . . . . . . . . . . . . . . . . . . 158

os_Collection::operator os_Set() . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158

os_Collection::operator const os_Set() . . . . . . . . . . . . . . . . . . . . . . . . 158

os_Collection::operator ==(). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158

os_Collection::operator !=() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158

8 C++ Collections Guide and Reference

Page 9: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Contents

os_Collection::operator <() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .158

os_Collection::operator <=() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .159

os_Collection::operator >() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .159

os_Collection::operator >=() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .159

os_Collection::operator =() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .159

os_Collection::operator |=() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .160

os_Collection::operator |() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .160

os_Collection::operator &=() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .160

os_Collection::operator &() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .160

os_Collection::operator –=() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .160

os_Collection::operator –() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .161

os_Collection::pick() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .161

os_Collection::query(). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .161

os_Collection::query_pick() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .162

os_Collection::remove() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .163

os_Collection::remove_first(). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .163

os_Collection::remove_last() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .164

os_Collection::replace_at() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .164

os_Collection::retrieve() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .164

os_Collection::retrieve_first() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .165

os_Collection::retrieve_last() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .165

os_collection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166os_collection::add_index(). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .171

os_collection::allow_duplicates . . . . . . . . . . . . . . . . . . . . . . . . . . . . .173

os_collection::allow_nulls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .173

os_collection::cardinality() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .173

os_collection::cardinality_estimate(). . . . . . . . . . . . . . . . . . . . . . . . . .174

os_collection::cardinality_is_maintained() . . . . . . . . . . . . . . . . . . . . . .174

os_collection::clear() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .174

os_collection::contains() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .174

os_collection::count() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .174

os_collection::drop_index() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .174

os_collection::empty() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .174

os_collection::EQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .175

os_collection::exists() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .175

os_collection::GE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .176

os_collection::GT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .176

os_collection::get_behavior(). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .176

os_collection::get_indexes() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .176

os_collection::has_index(). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .176

os_collection::initialize() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .177

Release 6.3 9

Page 10: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Contents

10

os_collection::insert(). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177

os_collection::insert_after() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177

os_collection::insert_before() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178

os_collection::insert_first() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178

os_collection::insert_last() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179

os_collection::LE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179

os_collection::LT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179

os_collection::maintain_order . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179

os_collection::multi_trans_add_index() . . . . . . . . . . . . . . . . . . . . . . . 179

os_collection::multi_trans_drop_index() . . . . . . . . . . . . . . . . . . . . . . . 180

os_collection::NE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180

os_collection::only(). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180

os_collection::operator os_array&() . . . . . . . . . . . . . . . . . . . . . . . . . . 181

os_collection::operator const os_array&() . . . . . . . . . . . . . . . . . . . . . . 181

os_collection::operator os_bag&() . . . . . . . . . . . . . . . . . . . . . . . . . . . 181

os_collection::operator const os_bag&() . . . . . . . . . . . . . . . . . . . . . . . 181

os_collection::operator os_int32() . . . . . . . . . . . . . . . . . . . . . . . . . . . 181

os_collection::operator os_list&(). . . . . . . . . . . . . . . . . . . . . . . . . . . . 181

os_collection::operator const os_list&() . . . . . . . . . . . . . . . . . . . . . . . 181

os_collection::operator os_set&(). . . . . . . . . . . . . . . . . . . . . . . . . . . . 182

os_collection::operator const os_set&() . . . . . . . . . . . . . . . . . . . . . . . 182

os_collection::operator ==() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182

os_collection::operator !=() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182

os_collection::operator <() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182

os_collection::operator <=() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182

os_collection::operator >() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183

os_collection::operator >=() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183

os_collection::operator =() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183

os_collection::operator |=() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183

os_collection::operator |() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184

os_collection::operator &=() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184

os_collection::operator &() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184

os_collection::operator –=() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184

os_collection::operator -() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185

os_collection::optimized_list . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185

os_collection::pick() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185

os_collection::query(). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185

os_collection::query_pick() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187

os_collection::remove() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188

os_collection::remove_at() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188

10 C++ Collections Guide and Reference

Page 11: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Contents

os_collection::remove_first() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .188

os_collection::remove_last() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .189

os_collection::replace_at() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .189

os_collection::retrieve() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .189

os_collection::retrieve_first() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .190

os_collection::retrieve_last() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .190

os_collection::set_query_memory_mode() . . . . . . . . . . . . . . . . . . . . .190

os_collection::trace_index_usage() . . . . . . . . . . . . . . . . . . . . . . . . . .191

os_collection::update_cardinality() . . . . . . . . . . . . . . . . . . . . . . . . . . .191

os_coll_query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192os_coll_query::create() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .192

os_coll_query::create_exists() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .195

os_coll_query::create_pick() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .197

os_coll_query::destroy() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .198

os_coll_query::get_element_type() . . . . . . . . . . . . . . . . . . . . . . . . . .198

os_coll_query::get_query_string() . . . . . . . . . . . . . . . . . . . . . . . . . . .198

os_coll_query::get_file_name() . . . . . . . . . . . . . . . . . . . . . . . . . . . . .199

os_coll_query::get_line_number() . . . . . . . . . . . . . . . . . . . . . . . . . . .199

os_coll_range . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199os_coll_range::os_coll_range() . . . . . . . . . . . . . . . . . . . . . . . . . . . . .199

os_Cursor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203os_Cursor::first() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .204

os_Cursor::insert_after(). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .204

os_Cursor::insert_before() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .204

os_Cursor::last() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .205

os_Cursor::more() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .205

os_Cursor::next(). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .205

os_Cursor::null() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .205

os_Cursor::os_Cursor(). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .205

os_Cursor::owner() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .207

os_Cursor::previous() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .207

os_Cursor::rebind() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .208

os_Cursor::remove_at() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .208

os_Cursor::resolve_all() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .208

os_Cursor::retrieve() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .208

os_Cursor::valid() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .209

os_Cursor::~os_Cursor() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .209

os_cursor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209os_cursor::first() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .210

os_cursor::insert_after() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .210

os_cursor::insert_before(). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .210

Release 6.3 11

Page 12: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Contents

12

os_cursor::last() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210

os_cursor::more() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211

os_cursor::next(). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211

os_cursor::null() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211

os_cursor::order_by_address . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211

os_cursor::order_by_DSCO. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212

os_cursor::os_cursor() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212

os_cursor::owner() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214

os_cursor::previous() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214

os_cursor::rebind() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214

os_cursor::remove_at() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214

os_cursor::resolve_all() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215

os_cursor::retrieve() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215

os_cursor::update_insensitive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215

os_cursor::valid() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215

os_cursor::~os_cursor() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215

os_Dictionary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215os_Dictionary::contains() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220

os_Dictionary::count_values() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220

os_Dictionary::insert() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220

os_Dictionary::os_Dictionary() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220

os_Dictionary::pick() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222

os_Dictionary::remove() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222

os_Dictionary::remove_value() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223

os_Dictionary::retrieve(). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223

os_Dictionary::retrieve_key() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223

os_dynamic_extent. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224os_dynamic_extent::insert() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224

os_dynamic_extent::os_dynamic_extent() . . . . . . . . . . . . . . . . . . . . . 224

os_dynamic_extent::remove(). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225

os_index_name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225os_index_name::get_options() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225

os_index_name::get_path_name() . . . . . . . . . . . . . . . . . . . . . . . . . . 225

os_index_path . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226os_index_path::allow_duplicates . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226

os_index_path::copy_key . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226

os_index_path::create() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226

os_index_path::no_duplicates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228

os_index_path::ordered . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228

os_index_path::point_to_key . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228

os_index_path::signal_duplicates. . . . . . . . . . . . . . . . . . . . . . . . . . . . 229

12 C++ Collections Guide and Reference

Page 13: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Contents

os_index_path::unordered. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .229

os_Ixonly and os_ixonly . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229os_Ixonly::os_Ixonly() and os_ixonly::os_ixonly() . . . . . . . . . . . . . . . .230

os_keyword_arg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231os_keyword_arg::operator ,() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .231

os_keyword_arg::os_keyword_arg(). . . . . . . . . . . . . . . . . . . . . . . . . .231

os_keyword_arg_list . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233os_keyword_arg_list::destroy_list() . . . . . . . . . . . . . . . . . . . . . . . . . .233

os_keyword_arg_list::operator ,() . . . . . . . . . . . . . . . . . . . . . . . . . . .233

os_keyword_arg_list::os_keyword_arg_list() . . . . . . . . . . . . . . . . . . . .234

os_List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234os_List::operator =() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .239

os_List::operator |=(). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .239

os_List::operator &=() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .240

os_List::operator –=() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .240

os_List::os_List() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .240

os_list . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241os_list::operator =() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .244

os_list::operator |=() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .245

os_list::operator &=(). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .245

os_list::operator –=() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .245

os_list::os_list() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .245

os_nList and os_nlist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246os_Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247

os_Set::default_behavior() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .251

os_Set::operator =() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .251

os_Set::operator |=() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .251

os_Set::operator &=() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .252

os_Set::operator –=() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .252

os_Set::os_Set() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .253

os_set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254os_set::operator =(). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .257

os_set::operator |=() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .257

os_set::operator &=(). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .257

os_set::operator –=() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .258

os_set::optimized_set. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .258

os_set::os_set(). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .258

Chapter 9 Macros and User-Defined Functions Reference. . . . . . . 259OS_MARK_DICTIONARY(). . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260OS_MARK_NLIST() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260

Release 6.3 13

Page 14: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Contents

14

OS_MARK_NLIST_PT() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261OS_MARK_QUERY_FUNCTION() . . . . . . . . . . . . . . . . . . . . . . . . . 261OS_MARK_QUERY_FUNCTION_WITH_NAMESPACE() . . . . . . . . . . . 262OS_TRANSIENT_DICTIONARY() . . . . . . . . . . . . . . . . . . . . . . . . . 262OS_TRANSIENT_DICTIONARY_NOKEY() . . . . . . . . . . . . . . . . . . . 263OS_TRANSIENT_NLIST() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263OS_TRANSIENT_NLIST_NO_BLOCK() . . . . . . . . . . . . . . . . . . . . . 264os_assign_function(). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265os_assign_function_body() . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265os_index() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265os_index_key() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266os_index_key_hash_function() . . . . . . . . . . . . . . . . . . . . . . . . . . 266os_index_key_rank_function() . . . . . . . . . . . . . . . . . . . . . . . . . . 267os_indexable_body(). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267OS_INDEXABLE_LINKAGE() . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268os_indexable_member() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268os_query_function() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269os_query_function_body() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270os_query_function_body_returning_ref(). . . . . . . . . . . . . . . . . . . 270os_query_function_body_with_namespace() . . . . . . . . . . . . . . . . 270os_query_function_returning_ref() . . . . . . . . . . . . . . . . . . . . . . . 271os_rel_1_1_body() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271os_rel_1_m_body(). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272os_rel_m_1_body(). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273os_rel_m_m_body() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274os_rel_1_1_body_options() . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275os_rel_1_m_body_options(). . . . . . . . . . . . . . . . . . . . . . . . . . . . 276os_rel_m_1_body_options(). . . . . . . . . . . . . . . . . . . . . . . . . . . . 277os_rel_m_m_body_options() . . . . . . . . . . . . . . . . . . . . . . . . . . . 278os_relationship_1_1() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280os_relationship_1_m() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281OS_RELATIONSHIP_LINKAGE() . . . . . . . . . . . . . . . . . . . . . . . . . 282os_relationship_m_1() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282os_relationship_m_m() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283

Chapter 10 Predefined TIX Exceptions. . . . . . . . . . . . . . . . . . . . .285Parent Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286Predefined Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287

Collection Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287

Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .291

14 C++ Collections Guide and Reference

Page 15: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Preface

Purpose The C++ Collections Guide and Reference describes how to use the C++ programming interface to ObjectStore to allocate, populate, query, and manipulate collections.

Audience This book assumes you are experienced with C++.

Scope Information in this book assumes that ObjectStore is installed and configured.

How This Book Is OrganizedChapter 1, Introducing Collections, on page 19, introduces collections, describes the different types of collections, and provides a simple example.

Chapter 2, Performing Basic Collections Functions, on page 33, discusses how to create, destroy, populate, and obtain information about collections.

Chapter 3, Using Cursors to Navigate Collections, on page 41, describes how to use a cursor to iterate over the elements in a collection.

Chapter 4, Using Dictionaries, on page 49, provides information about collections that use keys to keep track of elements.

Chapter 5, Performing Advanced Collections Operations, on page 61, discusses the use of paths to navigate to collection elements, the techniques for controlling collection traversal, supplying rank and hash functions, and specifying expected collection size.

Chapter 6, Querying Collections, on page 81, includes information about how to query collections.

Chapter 7, Using Indexes to Optimize Performance, on page 95, shows you how to build indexes on types in collections so that ObjectStore can process queries faster.

Chapter 8, Class Reference, on page 121, provides complete information about each class in the collections facility. Information is presented in alphabetical order by class name.

Chapter 9, Macros and User-Defined Functions Reference, on page 259, presents information in alphabetical order about each collections macro and user-defined function.

Chapter 10, Predefined TIX Exceptions, on page 285, provides information about exceptions that collections operations can signal.

Release 6.3 15

Page 16: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Preface

Notation ConventionsThis document uses the following conventions:

Progress Software Real Time Division on the World Wide WebThe Progress Software Real Time Division Web site (www.progress.com/realtime) provides a variety of useful information about products, news and events, special programs, support, and training opportunities.

Technical Support

To obtain information about purchasing technical support, contact your local sales office listed at www.progress.com/realtime/techsupport/contact, or in North America call 1-781-280-4833. When you purchase technical support, the following services are available to you:

• You can send questions to [email protected]. Remember to include your serial number in the subject of the electronic mail message.

• You can call the Technical Support organization to get help resolving problems. If you are in North America, call 1-781-280-4005. If you are outside North America, refer to the Technical Support Web site at www.progress.com/realtime/techsupport/contact.

• You can file a report or question with Technical Support by going to www.progress.com/realtime/techsupport/techsupport_direct.

• You can access the Technical Support Web site, which includes

- A template for submitting a support request. This helps you provide the necessary details, which speeds response time.

- Solution Knowledge Base that you can browse and query.

Convention Meaning

Courier Courier font indicates code, syntax, file names, API names, system output, and the like.

Bold Courier Bold Courier font is used to emphasize particular code, such as user input.

Italic Courier Italic Courier font indicates the name of an argument or variable for which you must supply a value.

Sans serif Sans serif typeface indicates the names of user interface elements such as dialog boxes, buttons, and fields.

Italic serif In text, italic serif typeface indicates the first use of an important term.

[ ] Brackets enclose optional arguments.

{ a | b | c } Braces enclose two or more items. You can specify only one of the enclosed items. Vertical bars represent OR separators. For example, you can specify a or b or c.

... Three consecutive periods indicate that you can repeat the immediately previous item. In examples, they also indicate omissions.

16

Page 17: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Preface

- Online documentation for all products.

- White papers and short articles about using Real Time Division products.

- Sample code and examples.

- The latest versions of products, service packs, and publicly available patches that you can download.

- Access to a support matrix that lists platform configurations supported by this release.

- Support policies.

- Local phone numbers and hours when support personnel can be reached.

Education Services

To learn about standard course offerings and custom workshops, use the Real Time Division education services site (www.progress.com/realtime/services).

If you are in North America, you can call 1-800-477-6473 x4452 to register for classes. If you are outside North America, refer to the Technical Support Web site. For information on current course offerings or pricing, send e-mail to [email protected].

Searchable Documents

In addition to the online documentation that is included with your software distribution, the full set of product documentation is available on the Technical Support Web site at www.progress.com/realtime/techsupport/documentation. The site provides documentation for the most recent release and the previous supported release. Service Pack README files are also included to provide historical context for specific issues. Be sure to check this site for new information or documentation clarifications posted between releases.

Your CommentsReal Time Division product development welcomes your comments about its documentation. Send any product feedback to [email protected]. To expedite your documentation feedback, begin the subject with Doc:. For example:

Subject: Doc: Incorrect message on page 76 of reference manual

Release 6.3 17

Page 18: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Preface

18

Page 19: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 1Introducing Collections

A collection is an object whose purpose is to group together other objects. It provides a convenient means of storing and manipulating groups of objects by supporting operations for inserting, removing, and retrieving elements.

This chapter discusses the following topics:

Overview of Collections, Queries, and Indexes 19

Collections Class Library 20

Collections Query and Manipulation Features 21

Requirements for Collections Applications 21

Introductory Collections Example 22

Choosing a Collection Type 24

Collection Characteristics and Behaviors 26

Templated and Nontemplated Collections 29

Overview of Collections, Queries, and Indexes

The ObjectStore collections facility provides

• A library of collection classes

• Facilities that allow traversal, manipulation, and retrieval of the elements within collections

The collections facility is rich and varied. Consequently, it adds overhead to your code and database. If your application does not require collections, a simple linked list you write yourself might be a more suitable choice.

Collections Queries involve collections, which are objects such as sets, bags, or lists that serve to group together other objects. ObjectStore provides a library of collection classes. These classes provide the data structures for representing such collections, encapsulated by member functions that support various forms of collection manipulation, such as element insertion and removal. Retrieval of a given

Release 6.3 19

Page 20: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Collections Class Library

collection’s elements for examination or processing one at a time is supported through the use of a cursor class.

Query ProcessingThe query processing database service provides support for associative data retrieval, such as look-up by name or ID number.

Data AccessMany application types require two forms of data access: navigational access and associative access. Navigation accesses data by following pointers contained in data structure fields. In C++, the data member access syntax supports navigational data access. Associative access, on the other hand, is the look-up of those data structures whose field values satisfy a certain condition (for example, look-up of an object by name or ID number). ObjectStore supports associative access, or query, through member functions in the ObjectStore class library.

Query Optimizer Queries return a collection containing those elements of a given collection that satisfy a specified condition. They can be executed with an optimized search strategy, formulated by the ObjectStore query optimizer. The query optimizer maintains indexes into collections based on user-specified keys, that is, data members, or data members of data members, and so on.

Indexes By using these indexes, implemented as B-trees or hash tables, the programmer can minimize the number of objects examined in response to a query. Formulation of optimization strategies is performed automatically by the system. Index maintenance can also be automatic — the programmer need only specify the desired index keys.

Collections Class LibraryThe classes in the ObjectStore collections class library provide the data structures for representing several types of collections. The categories of classes and their different behaviors are as follows:

• Sets do not maintain order, do not allow nulls, and ignore duplicates.

• Bags do not maintain order and do not allow nulls, but they do allow duplicates.

• Lists maintain order and do not allow nulls, but they do allow duplicates.

• Arrays maintain order and allow nulls and duplicates.

• Dictionaries associate a key with each element or group of elements. They can be ordered or unordered, do not allow nulls, and ignore duplicates.

20 C++ Collections Guide and Reference

Page 21: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 1: Introducing Collections

• Index-only collections support O(1) element look-up. The index can be ordered or unordered, supports null insertions, and ignores duplicate insertions.

An object can be contained in many different collections, and collections can be used in transient or persistent memory, depending on the needs of your application.

Collections Query and Manipulation FeaturesCollections form the basis of the ObjectStore query facility, which allows you to select those elements of a collection that satisfy a specified condition. Queries with simple conditions are discussed in this chapter. Queries with complex conditions are described in Chapter 6, Querying Collections, on page 81.

Each class defines member functions that allow you to insert, remove, and count the elements in the collection. With the ObjectStore cursor class, you can create a cursor to iterate over the elements in a collection and to retrieve elements for examination or processing one at a timeAlso, you can query collections for elements meeting simple or sophisticated sorting criteria.

Collections are commonly used to model many-valued attributes, and they can also be used as class extents (which hold all instances of a particular class). Collections of one type — dictionaries — associate a key with each element or group of elements, and so can be used to model binary associations or mappings. ObjectStore dictionaries are described in detail in Chapter 4, Using Dictionaries, on page 49.

Requirements for Collections Applications The following sections describe the requirements for applications that use collections:

• Including Collections Header Files

• Initializing the Collections Facility

• Generating the Application Schema

• Linking with ObjectStore Libraries

Including Collections Header FilesAfter including the standard ObjectStore header file <ostore/ostore.hh>, programs that use ObjectStore collections must include the header file <ostore/coll.hh>.

If your application uses ObjectStore dictionaries, your program must include <ostore/coll/dict_pt.hh> and must also include <ostore/coll/dict_pt.cc> in any source file that instantiates an os_Dictionary, following the other header files. See ObjectStore Header Files in Chapter 2 of Building ObjectStore C++ Applications.

Release 6.3 21

Page 22: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Introductory Collections Example

Initializing the Collections FacilityTo use the collections facility, after an application calls the objectstore::initialize() function, it must call the static member function os_collection::initialize(). For example:

objectstore::initialize();os_collection::initialize();

Generating the Application SchemaAs with any ObjectStore application, applications that use the collections facility must generate an application schema. Create a schema source file that marks the classes you want to store in the database.

If you use parameterized persistent collections, you must mark those collection types in your schema source file.

If you use persistent dictionaries, you must call the macro OS_MARK_DICTIONARY() in the schema source file for each key-type/element-type pair that you use. Calls to this macro have the form

OS_MARK_DICTIONARY(key-type, element-type)

Specific information about marking dictionaries can be found in Marking Persistent Dictionaries on page 51. See also OS_MARK_DICTIONARY() on page 260.

Linking with ObjectStore LibrariesPrograms that use ObjectStore collections must also link with the appropriate ObjectStore collections libraries. Collections library names are platform specific:

Introductory Collections ExampleHere is a simple example to illustrate how to use collections. ObjectStore collections provide some alternatives to linked lists, C++ arrays, and other aggregation data structures. In cases where your application uses queries and ranges, collections are easier to use and more powerful. This example is based on the linked-list example in Example of a Lexical Transaction in Chapter 5 of the ObjectStore C++ A P I User Guide, replacing the linked list with a collection.

Header file: note.hh

#include <iostream>#include <string.h>#include <ostore/ostore.hh>#include <ostore/coll.hh>

UNIX Platforms Windows and OS/2 Platforms

Collections -loscol liboscol.so

ostore.lib

Indexes and queries -losqry libosqry.so

None

22 C++ Collections Guide and Reference

Page 23: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 1: Introducing Collections

/* A simple class that records a note entered by the user. */

class note {

public:

/* Public Member functions */ note(const char*, int); ~note(); void display(ostream& = cout); static os_typespec* get_os_typespec();

/* Public Data members */ char* user_text; int priority;};

Main program: main.cc

/* ++ Note Program - main file */

#include "note.hh"extern "C" void exit(int);extern "C" int atoi(char*);

/* Head of linked-list of notes */os_list *notes = 0;const int note_text_size = 100;

main(int argc, char** argv) {

if(argc!=2) { cout << "Usage: note <database>" << endl; exit(1); } /* end if */

objectstore::initialize(); os_collection::initialize(); char buff[note_text_size]; char buff2[note_text_size]; int note_priority;

os_database *db = os_database::open(argv[1], 0, 0644);

OS_BEGIN_TXN(t1,0,os_transaction::update) {

os_database_root *root_head = db->find_root("notes"); if(!root_head) root_head = db->create_root("notes"); notes = (os_list *)root_head->get_value();

if(!notes) { notes = new(db, os_list::get_os_typespec()) os_list; root_head->set_value(notes); } /* end if */

os_cursor c(*notes); /* Display existing notes */ for(note* n=(note *)c.first(); n; n=(note *)c.next()) n->display();

/* Prompt user for a new note */ cout << "Enter a new note: "<< flush; cin.getline(buff, sizeof(buff));

/* Prompt user for a note priority */ cout << "Enter a note priority: "<< flush; cin.getline(buff2, sizeof(buff2)); note_priority = atoi(buff2);

Release 6.3 23

Page 24: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Choosing a Collection Type

notes->insert(new(db, note::get_os_typespec()) note(buff, note_priority) ); } OS_END_TXN(t1)

db->close();}

Choosing a Collection TypeThis section contains a brief description of each type of ObjectStore collection, followed by a simple decision tree you can use to choose a collection type to suit your program’s particular behavioral requirements.

All collection types described below (with the exception of os_Dictionary) have both a templated (parameterized) and a nontemplated (nonparameterized) version. For ease of differentiation, the templated versions use uppercase letters (for example, os_Set), whereas the nontemplated versions use lowercase (os_set). Nontemplated classes are always typed as void* pointers.

• For information about the differences between templated (parameterized) and nontemplated (nonparameterized) collection classes, see Templated and Nontemplated Collections.

• For information about the characteristics of ObjectStore collection classes, see Collection Characteristics and Behaviors.

• For a description of hierarchical representation of the relationships between the ObjectStore collection types, see the Class Hierarchy Diagram.

• For information about how to create collection classes, see Creating Collections on page 33.

os_Set and os_setSets, as with familiar data structures such as linked lists and arrays, have elements. Elements are objects that the set groups together. But, in contrast to the elements of lists and arrays, the elements of a set are unordered. Use sets to group objects together when you do not need to record any particular order for the objects.

Besides lacking order, sets do not allow multiple occurrences of the same element. This means that inserting a value that is already an element of a set leaves the set unchanged.

os_Bag and os_bagBags are collections that keep track of what their elements are and also of the number of occurrences of each element. In other words, bags allow duplicate elements. Bags provide all the operations available for sets, as well as an operation, count(), that returns the number of occurrences of a given element in a given collection.

24 C++ Collections Guide and Reference

Page 25: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 1: Introducing Collections

os_List and os_listIn addition to sets and bags, the ObjectStore collections facility supports lists. A list is a collection that associates a numerical position with each element based on insertion order. Lists allow duplicates. In addition to simple insert (insert into the beginning or end of the collection) and simple remove (removal of the first occurrence of a specified element), you can insert, remove, and retrieve elements based on a specified numerical position, or based on a specified cursor position (see Accessing Collection Elements with a Cursor or Ordinal Value on page 45).

os_nList and os_nlist are derived from parameterized os_List and os_list, respectively. They allow the user to customize the internal representation of ObjectStore lists.

os_Array and os_arrayObjectStore arrays are like ObjectStore lists, except that they always provide access to collection elements in constant time. That is, the time complexity of operations such

as retrieval of the nth element is order 1 in the array’s size. Arrays also always allow null elements, and they provide the ability to automatically establish a specified number of new null elements.

os_DictionaryLike bags, ObjectStore dictionaries are unordered collections that allow duplicates. Unlike bags, however, dictionaries associate a key with each element. The key can be a value of any C++ fundamental type, a user-defined type, or a pointer type. When you insert an element into a dictionary, you specify the key along with the element. You can retrieve an element with a given key, or retrieve those elements whose keys fall within a given range.

Dictionaries are somewhat different from other ObjectStore collection classes in their use of keys. See Chapter 4, Using Dictionaries, on page 49, for additional information on how dictionaries differ from other kinds of ObjectStore collections.

Release 6.3 25

Page 26: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Collection Characteristics and Behaviors

Using a Decision Tree to Select a Collection TypeHere is a simple decision tree to help you choose a collection type to suit particular behavioral requirements.

Collection Characteristics and BehaviorsTo use collections, it is important to understand the characteristics and behavior of each type of collection. The topics discussed in this section are

• Collections Store Pointers to Objects

• Collections Can Be Transient or Persistent

• Parameterized and Nonparameterized Collections

• Class Hierarchy Diagram

• Collection Behaviors

• Expected Collection Size

• Performing pick() on an Empty Collection

Collections Store Pointers to ObjectsObjectStore collection classes store pointers to objects, not the objects themselves. Thus, elements exist independently from membership in a collection. A single element can be a member of many collections.

Collections Can Be Transient or PersistentLike all types in ObjectStore, collections can be used in transient memory (program memory) or persistent memory. Transient collections are used to represent transient, changeable groupings; the current list of cars in the parking garage, for example. Persistent collections contain more permanent associations, such as the list of people on a board of directors or the founding states of the European community.

os_Array os_List os_Dictionary

Maintain insertion order?

yes no

os_Bag os_Set

Associate a key with each element?

Automatic addition of a specified number of null elements?

yes no yes no

Allow duplicates?

yes no

26 C++ Collections Guide and Reference

Page 27: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 1: Introducing Collections

Parameterized and Nonparameterized CollectionsEvery ObjectStore collection class (except os_Dictionary) is provided in both a templated (parameterized) and a nontemplated (nonparameterized) form. See Templated and Nontemplated Collections on page 29.

Templated classes use an uppercase letter in their class names (os_Set), whereas nontemplated classes use lowercase letters in their class names (os_set).

Class Hierarchy DiagramThe following diagram shows the hierarchical relationship among most (os_Dictionary, os_nlist, and os_nList are not included) of the public ObjectStore collection classes. Note that E is actually a pointer value: the element type parameter used by the templated collection classes to specify the types of values allowable as elements. See Using Collections with the Element Type Parameter on page 29 for more information.

os_set

os_bag

os_list

os_array

os_Bag<E>

os_Collection<E>

os_collection

os_List<E>

os_Array<E>

os_Set<E>

os_nListos_nlist

Release 6.3 27

Page 28: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Collection Characteristics and Behaviors

Collection BehaviorsThe ObjectStore collection classes vary according to what behaviors and characteristics are permitted and prohibited. The following table lists the classes and their default behaviors. You can change the default size of a collection; see Chapter 5, Performing Advanced Collections Operations, on page 61, for more information on customizing your ObjectStore collections.

The os_Dictionary class differs substantially from other collection classes in its behaviors. Dictionary behaviors are related to the key of an element rather than to an element itself. See Chapter 4, Using Dictionaries, on page 49, for information on how ObjectStore dictionaries differ from other ObjectStore collection classes.

The behavior of os_nList and os_nlist is the same as that of os_List. See os_nList and os_nlist on page 246.

Expected Collection SizeBy default, all collection classes are presized with a representation suitable for a size of less than 20. The expected_size argument for the collection constructors lets you supply a different default size. For more information, see Specifying Expected Size on page 80.

Performing pick() on an Empty Collection For all collection classes, performing pick() on an empty collection or on an empty result of a query results in a null return value.

Collection Class

Maintain Element Order

Allow Duplicates

Allow Nulls

os_Set No No No

os_Bag No Yes No

os_List Yes Yes No

os_Array Yes Yes Yes

28 C++ Collections Guide and Reference

Page 29: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 1: Introducing Collections

Templated and Nontemplated CollectionsObjectStore collection classes are provided in both templated (parameterized) and nontemplated (nonparameterized) versions.

Using Collections with the Element Type ParameterThe parameterized ObjectStore collection classes — os_Set, os_Bag, os_List, os_Collection, os_Dictionary, os_Ixonly, and os_Array — are class templates. Each class has a parameter, the element type parameter, that specifies the type of value allowable as elements. This type must be a pointer type. For example:

os_Set<part*> &a_part_set = *new(db1, os_Set<part*>::get_os_typespec()) os_Set<part*>;

This fragment defines a variable whose value is a reference to a set of pointers to part objects. The element type, part*, appears in angle brackets when the collection type is mentioned. (Note that the element type parameter is represented as <E> in function signatures.)

os_nList and os_nlist are also parameterized ObjectStore collections classes. The parameters for these classes are used to customize the internal representation of the list. See os_nList and os_nlist on page 246.

Example: os_Set

The following example uses an instance of os_Set, one of the classes supplied by the collections facility. This class defines a part that includes the part number and the responsible engineer.

#include <ostore/ostore.hh>#include <ostore/coll.hh>

class part {

public:

int part_number; os_Set<part*> &children; employee *responsible_engineer;

part (int n) : children(*new( db1, os_Set<part*>::get_os_typespec()) os_Set<part*> { part_number = n; responsible_engineer = 0; }

};

Release 6.3 29

Page 30: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Templated and Nontemplated Collections

Using Collections Without ParameterizationYou can choose to use the following nonparameterized collection classes:

Notice that the names of the parameterized classes have an uppercase letter following the os_ , while the nonparameterized classes have a lowercase letter following the os_ . Notice, as well, that there is no nonparameterized version of os_Dictionary.

os_collection

os_listos_bag os_arrayos_set os_ixonly

30 C++ Collections Guide and Reference

Page 31: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 1: Introducing Collections

Difference Between Parameterized and Nonparame-terized InterfacesThe difference between the parameterized and nonparameterized interfaces is that with the parameterized interface, you can inform the compiler of the type of element a collection is to have, allowing the compiler to provide an extra measure of type safety. With the nonparameterized interface, elements are always typed as void* pointers.

Most of the examples in this manual use the parameterized interface, but if you are not using parameterization, just drop any construct of the form

<element-type-name>

and use the nonparameterized collection type names (beginning with os_ followed by a lowercase letter). If you use os_set instead of os_Set, class definition example used earlier in Using Collections with the Element Type Parameter on page 29 would then look like the following:

Example: os_set()

class employee ;extern os_database *db1 ;

class part {

public:

int part_number ; os_set &children ; employee *responsible_engineer ;

part (int n) : children(*new(db1, os_set::get_os_typespec()) os_set { part_number = n; responsible_engineer = 0 ; }

};

In this example, os_Set, and os_Set is changed to os_set and the element type parameter <part*> is left out.

Nonparameterized collections are typed void*When you use nonparameterized collections, elements are typed void*. This means you must cast the result of retrieving a collection element, for example, when using pick()or traversing a collection by using a cursor.

Release 6.3 31

Page 32: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Templated and Nontemplated Collections

32 C++ Collections Guide and Reference

Page 33: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 2Performing Basic Collections Functions

A collection is an object whose purpose is to group together other objects. It provides a convenient means of storing and manipulating groups of objects by supporting operations for inserting, removing, and retrieving elements.

This chapter discusses the following topics:

Creating Collections 33

Deleting Collections 34

Inserting Collection Elements 34

Removing Collection Elements with remove() 35

Testing Collection Membership with contains() 36

Finding the Count of an Element with count() 37

Finding the Size of a Collection with cardinality() 37

Copying, Combining, and Comparing Collections 37

Compiling for Collections Optimization 39

Creating CollectionsThis section presents information on creating collections. The os_Array, os_Bag, os_Collection, os_List, and os_Set classes are discussed together in the first subsection. os_Dictionary is discussed separately in Chapter 4, Using Dictionaries, on page 49. For information about os_Ixonly, see os_Ixonly and os_ixonly on page 229.

General GuidelinesYou create collections for each collection class with the following constructor functions:

Collection Type Constructor Function

Array os_Array::os_Array()

Bag os_Bag::os_Bag()

Release 6.3 33

Page 34: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Deleting Collections

Constructor functions

The overloadings of constructor functions are listed in Chapter 8, Class Reference, on page 121. For each constructor, there is at least one overloading that creates an empty set and another that lets you specify the expected collection size. There are also two copy constructors that create a collection with the same membership as another specified collection.

Deleting CollectionsTo delete a collection, use the C++ delete() function. For example:

os_list *list = new(db, os_list::get_os_typespec()) os_list;delete list;

You must explicitly delete each collection that you allocate. If you do not, your application has memory leaks. For information about deleting objects, see ::operator delete() in Chapter 3 of C++ A P I Reference.

Inserting Collection ElementsYou update collections by inserting and removing elements or by using the assignment operators (see Copying, Combining, and Comparing Collections on page 37). The insert operations for os_Collection and its subtypes are declared in the following way:

void insert(const E) ;

Inserting Dictionary ElementsFor dictionaries, you specify an entry, that is, a key, along with the element to be inserted. So os_Dictionary::insert() is declared in the following way:

void insert(const K &key, const E element) ;

void insert(const K *key_ptr, const E element) ;

These two overloadings are provided for convenience so that you can pass either the key or a pointer to the key.

Caution For dictionaries with signal_dup_keys behavior, if an attempt is made to insert something with a key that already exists, err_am_dup_key is signaled.

Duplicate InsertionsFor collections that do not support duplicates, inserting something that is already an element of the collection leaves the collection unchanged. For example:

List os_List::os_List()

Set os_Set::os_Set()

Collection Type Constructor Function

34 C++ Collections Guide and Reference

Page 35: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 2: Performing Basic Collections Functions

os_database *db1 ;message *a_msg ;os_Set<message*> &temp_set = *new(db1, os_Set<message*>::get_os_typespec()) os_Set<message*>; . . .temp_set.insert(a_msg) ;temp_set.insert(a_msg) ; /* set is unchanged */

For collections that support duplicates, each insertion increases the collection’s size by 1 and increases by 1 the count (or number of occurrences) of the inserted element in the collection. You can retrieve the count of a given element with count(). Iteration with an unrestricted cursor visits each occurrence of each element.

Null InsertionsIf you insert a null pointer (0) into a collection that does not support nulls, the collection remains unchanged and err_coll_nulls is signaled.

Ordered CollectionsInserting an element into an ordered collection adds the element to the end of the collection. See also Accessing Collection Elements with a Cursor or Ordinal Value on page 45.

Duplicate KeysFor dictionaries with signal_dup_keys behavior, if an attempt is made to insert an element with a key that already exists, err_am_dup_key is signaled.

Removing Collection Elements with remove()The remove operations for os_Collection and its subtypes are declared in the following way:

os_int32 remove(E) ;

If you remove an element from a collection, the cardinality decreases by 1, and the count of the element in the collection decreases by 1. If you remove something that is not an element, the collection is unchanged. For example:

os_database *db1 ;message *a_msg; . . .os_Set<message*> &temp_set = *new(db1, os_Set<message*>::get_os_typespec()) os_Set<message*>;. . .temp_set.remove(a_msg) ;temp_set.remove(a_msg) ; /* set is unchanged */

Ordered CollectionsFor collections that maintain order, remove() removes the specified element from the end of the collection. There are also overloadings of remove() that allow you to

Release 6.3 35

Page 36: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Testing Collection Membership with contains()

remove at a numerical index value in the collection or remove at the position of the cursor.

Removing Dictionary ElementsFor dictionaries, you can also remove the entry with a specified key and element with remove_value(). This function is faster than remove(), so if you can specify the key, use remove_value() instead of remove(). There are two overloadings that differ only in that you pass a pointer to the key in one overloading and you pass a reference to the key in the other overloading.

void remove(const K &key, const E element) ;

void remove(const K *key_ptr, const E element) ;

If there is no entry with the specified key and element, the collection is unchanged. As with remove(), if you remove an entry from a dictionary, the cardinality decreases by 1, and the count of the element in the collection decreases by 1.

With dictionaries, you can also remove a specified number of entries with a specified key, using the following functions:

E remove_value(const K &key, os_unsigned_int32 n = 1) ;

E remove_value(const K *key_ptr, os_unsigned_int32 n = 1) ;

If there are fewer than n entries with the specified key, all entries in the dictionary with that key are removed. If there is no such entry, the dictionary remains unchanged.

Testing Collection Membership with contains()

To see if a given pointer is an element of a collection, use

os_int32 contains(E) const ;

This function returns nonzero if the specified E is an element of the specified collection, and 0 otherwise.

For dictionaries, you can determine if there is an entry with a given key and element.

os_boolean contains( const K const &key_ref, const E element) const ;

os_boolean contains( const K *key_ptr, const E element) const ;

With the first function, you pass a reference to the key; with the second, you pass a pointer to the key. Other than that, these two functions are equivalent. If there is no entry with the specified key and element, 0 (false) is returned.

36 C++ Collections Guide and Reference

Page 37: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 2: Performing Basic Collections Functions

Finding the Count of an Element with count()To find the count of a given element in a collection that allows duplicates, use

os_int32 count(E) ;

If the specified E is not an element of the collection, 0 is returned.

For dictionaries, you can determine the number of entries with a specified key with one of these functions:

os_unsigned_int32 count_values(const K const &key_ref) const ;

os_unsigned_int32 count_values(const K *key_ptr) const ;

With the first function, you pass a reference to the key; with the second, you pass a pointer to the key. Other than that, these two functions are equivalent.

Finding the Size of a Collection with cardinality()

You can determine the number of elements in a collection with the member function os_collection::cardinality().

os_unsigned_int32 cardinality() const ;

The cardinality of a collection that does not allow duplicates is the number of elements it contains. The cardinality of a collection that does allow duplicates is the sum of the number of occurrences of each of its elements.

You can test to see if a collection is empty with the member function empty().

os_int32 empty() ;

This function returns true (a nonzero 32-bit integer) if it is empty, and false (0) otherwise.

Copying, Combining, and Comparing Collections

The class os_Collection defines several operators for assignment and comparison. Some of the assignment operators are related to the familiar set-theory operators union, intersection, and difference. In addition, some of the comparison operators are analogous to set-theory comparisons such as subset and superset. The collection operators are listed below. (LHS, below, stands for the operand on the left-hand side, and RHS stands for the right-hand-side operand.)

Release 6.3 37

Page 38: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Copying, Combining, and Comparing Collections

Collection operators

• operator =() replaces the contents of LHS with the contents of RHS.

• operator |=() adds the contents of RHS to LHS.

• operator -=() removes the contents of RHS from LHS.

• operator &=() replaces the contents of LHS with the intersection of LHS and RHS.

• operator <() (like proper subset).

• operator >() (like proper superset).

• operator <=() (like subset).

• operator >=() (like superset).

• operator ==() (checks if elements are the same).

• operator !=() (checks if any elements are different).

Dual Purpose of the OperatorsAll these operators have a dual purpose. They can be used on two collections, or they can be used on a collection (as left-hand operand) and an instance of that collection’s element type (as right-hand operand). For example, they can be used on a set of parts and a part. In that case, the instance of the collection’s element type is treated as a collection whose one and only element is that instance. Performance varies by representation.

So, for example, you can use the union equals operator (|=) as a convenient way of performing inserts:

os_Set<message*> &a_set = *new(db1, os_Set<message*>::get_os_typespec()) os_Set<message*>;message *a_msg ;. . . a_set |= a_msg ;

And you can use -= to remove elements:

a_set -= a_msg ;

Ordered Collections and Collections with DuplicatesWhen you use update operators, such as |=, on ordered collections or collections that allow duplicates, the result can be understood in terms of performing an iteration on one or more of the operands. So, for example:

big_list |= little_list ;

is equivalent to iterating through little_list in the default order, performing an insert into big_list for each occurrence of each element of little_list. Assignment of one collection to another as in

the_copy = the_original;

is equivalent to first removing all the_copy’s elements and then iterating through the_original in default order, performing an insert into the_copy for each occurrence of each element of the_original.

38 C++ Collections Guide and Reference

Page 39: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 2: Performing Basic Collections Functions

In general, the update operators (=, |=, -=, &=) bundle together a sequence of inserts or removes of elements of one or more operands in the order in which those elements appear in the operands, the default iteration order for the operands. This describes only the behavior of the operators. The implementations might be different.

For example, to add all of a part’s children to a given list, you might use this code:

os_database *db1 ;. . . os_List<part*> &a_list = *new(db1, os_List<part*>::get_os_typespec()) os_List<part*>; part *a_part ;. . . a_list |= a_part->children ;

This is behaviorally equivalent to

part *p ;os_Cursor<part*> c(a_part->children) ;for ( p = c.first() ; p ; p = c.next() ) a_list.insert(p) ;

Compiling for Collections Optimization If your application uses a transient os_list, os_List<>, or os_set that contains pointers to persistent objects, you can optimize the default construction of the class instance to use hard pointers instead of soft pointers, thus improving the performance of the constructed instance. To optimize transient sets and lists globally, set the following defines either in the application source code or on the compile line, following the -D option:

• _OS_COLL_SET_OPTIMIZE

• _OS_COLL_LIST_OPTIMIZE

The _OS_COLL_SET_OPTIMIZE macro sets the os_set::optimized_set flag for any default transient os_set and os_Set<> objects, and the _OS_COLL_LIST_OPTIMIZE macro sets the os_collection::optimized_list flag for any default transient os_list and os_List<> objects.

The macros set the optimization flags only for the default constructors. If your application uses a nondefault constructor, you must explicitly specify the optimization flag as an argument. For more information about the optimization flags, see the following:

• os_collection::optimized_list

• os_set::optimized_set

Note that transient cursors are optimized to use hard pointers by default.

Release 6.3 39

Page 40: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Compiling for Collections Optimization

40 C++ Collections Guide and Reference

Page 41: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 3Using Cursors to Navigate Collections

The ObjectStore collections facility provides a number of classes that help you navigate within a collection. The os_Cursor class, the os_index_path class, and the os_coll_range class all help you insert and remove elements, as well as retrieve particular elements or sequences of elements.

• The os_index_path class is described in Using Paths in Navigation on page 62. See also os_index_path on page 226.

• The os_coll_range class is described in Using Ranges in Navigation on page 70. See also os_coll_range on page 199.

This chapter discusses the following topics:

Description of a Cursor 41

Creating Default Cursors 42

Traversing Collections with Default Cursors 43

Rebinding Cursors to Another Collection 45

Accessing Collection Elements with a Cursor or Ordinal Value 45

Manipulating First and Last Elements in a Collection 46

Using os_address_space_marker Cursors 47

Description of a CursorA cursor, an instance of os_Cursor, is used to designate a position within a collection. You can use cursors to traverse collections as well as to retrieve, insert, remove, and replace elements.

When you create a default cursor, you specify its associated collection, and the cursor is positioned at the collection’s first element. With member functions of os_Cursor, you can reposition the cursor as well as retrieve the element at which the cursor is currently positioned. See Traversing Collections with Default Cursors on page 43. Some members of the collection classes take cursor arguments. These functions support insertion, removal, and replacement of elements.

Release 6.3 41

Page 42: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Creating Default Cursors

Creating Default CursorsThe class os_Cursor is a parameterized class supplied by the ObjectStore class library.

os_Cursor(const os_Collection<E> &) ;

Its constructor takes an os_Collection& (people in the example in the next section) as the argument. This is the collection to be traversed. The traversal proceeds in an arbitrary order for unordered collections and, for ordered collections, in the order in which the elements were inserted. See also Controlling Traversal Order on page 68, Performing Collection Updates During Traversal on page 74, and Restricting the Elements Visited in a Traversal on page 73.

Note that traversal of a collection with duplicates visits each element once for each time it occurs in the collection. For example, an element that occurs three times in a collection is visited three times during a traversal of the collection.

os_Cursor’s parameter (person* in the example) indicates the type of elements in the collection being traversed. The cursor’s parameter must be the element type (see Using Collections with the Element Type Parameter on page 29) of the collection passed as the constructor argument.

42 C++ Collections Guide and Reference

Page 43: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 3: Using Cursors to Navigate Collections

Traversing Collections with Default CursorsThe ObjectStore collections facility allows you to program loops that process the elements of a collection one at a time. When you use it, you do not need to know how many elements are in the collection; each time through the loop, you can test whether more elements remain to be visited. Consequently, you need not worry about loop bounds.

To traverse a collection, you create a cursor associated with the collection you want to traverse. The cursor records the state of an iteration by pointing to the element currently being visited. Each time through the loop, you advance the cursor to the next element and retrieve that element. Following is an example:

os_database *db1 ;. . .os_Set<person*> &people = *new(db1, os_Set<person*>::get_os_typespec()) os_Set<person*>; . . . /* insertions into people */

os_Set<person*> &teenagers = *new(db1, os_Set<person*>::get_os_typespec()) os_Set<person*>;

person* p;

os_Cursor<person*> c(people);

for (p = c.first(); c.more() ; p = c.next()) { if (p–>age >=13 && p–>age <= 19) teenagers.insert(p);}

The for loop in this example retrieves each element of the collection people and adds those between the ages of 13 and 19 to the collection teenagers.

The next sections provide information about positioning and moving cursors in the collection.

Release 6.3 43

Page 44: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Traversing Collections with Default Cursors

Positioning the Cursor at the Collection’s First ElementIn the example code, the traversal is performed with a for loop. The initialization part of the loop header is an assignment involving a call to the member function os_Cursor::first():

p = c.first()

This positions the cursor at the collection’s first element and returns that element. If there is no first element because the collection is empty, first() makes the cursor null and returns 0.

Moving the Cursor to the Collection’s Next ElementIn the example, the increment part of the for loop header is an assignment involving a call to the member function os_Cursor::next():

p = c.next()

This positions the cursor at the collection’s next element and returns that element. If there is no next element, next() makes the cursor null and returns 0.

Is the Cursor at a Nonnull Element?In the example, the loop’s condition is a call to the member function os_Cursor::more():

c.more()

This function returns a nonzero 32-bit integer (true) when the cursor is still positioned at some element of the collection. The function returns 0 (false) when the cursor is not pointing at any element.

After next() is applied to the collection’s last element, the cursor becomes null and more() then returns false, terminating the loop.

Alternative to using more()

For collections that do not allow null elements, you can take advantage of the fact that first() and next() return null pointers when there is no first or next element. This means you can use the values returned by these functions (in this case p) as the loop condition as long as the collection contains no null pointers. For example:

os_database *db1 ;. . .os_Set<person*> &people = *new(db1, os_Set<person*>::get_os_typespec()) os_Set<person*>;

. . . /* inserts to people */

os_Set<person*> &teenagers = *new(db1, os_Set<person*>::get_os_typespec()) os_Set<person*>;

person* p ;os_Cursor<person*> c(people) ;

for ( p = c.first() ; p ; p = c.next() ) if ( p–>age >=13 && p–>age <= 19 ) teenagers.insert(p) ;

44 C++ Collections Guide and Reference

Page 45: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 3: Using Cursors to Navigate Collections

Rebinding Cursors to Another CollectionYou can change a cursor’s associated collection with the following members of os_Cursor:

void rebind(const os_Collection<E>&) ;

void rebind(const os_Collection<E>&, _Rank_fcn) ;

This last overloading is for rebinding cursors whose order is specified by a rank function. See Path-Based Traversal on page 69. Once rebound, the cursor is positioned at the specified collection’s first element.

Accessing Collection Elements with a Cursor or Ordinal Value

You can gain access to a specific place in a collection by means of an ordinal value or a cursor as arguments to the following functions:

void os_Collection::insert_after(const E, const os_Cursor<E>&)

void os_Collection::insert_after(const E, os_unsigned_int32)

void os_Collection::insert_before(const E, const os_Cursor<E>&)

void os_Collection::insert_before(const E, os_unsigned_int32)

void os_Collection::remove_at(const os_Cursor<E>&)

void os_Collection::remove_at(os_unsigned_int32)

E os_Collection::replace_at(const E, const os_Cursor<E>&)

E os_Collection::replace_at(const E, os_unsigned_int32)

E os_Collection::retrieve(const os_Cursor<E>&) const

E os_Collection::retrieve(os_unsigned_int32) const

The cursor-based overloadings must use a default cursor. The cursor-based overloadings of remove_at(), replace_at(), and retrieve() can also be used for unordered collections. (See Traversing Collections with Default Cursors on page 43.)

Release 6.3 45

Page 46: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Manipulating First and Last Elements in a Collection

Manipulating First and Last Elements in a Collection

There are also functions for inserting, removing, and retrieving elements from the beginning and the end of an ordered collection. These are declared as follows:

void os_Collection::insert_first(const E)

void os_Collection::insert_last(const E)

os_int32 os_Collection::remove_first(const E&)

E os_Collection::remove_first()

os_int32 os_Collection::remove_last(const E&)

E os_Collection::remove_last()

The integer-valued remove() and retrieve() functions return 0 if the collection had no elements to remove or retrieve (that is, was empty). Otherwise, they return a nonzero integer and modify their arguments to indicate the removed or retrieved element.

If you perform any of these functions on an unordered collection created with the supertype’s interface, the exception err_coll_not_supported is signaled. These operations cause a compile-time error if they are performed on an unordered collection created with the subtype’s interface. (Compile-time detection is possible because the unordered subtypes define the ordered operations as private.)

46 C++ Collections Guide and Reference

Page 47: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 3: Using Cursors to Navigate Collections

Using os_address_space_marker CursorsThe ObjectStore collections facility allows you to program loops that process the elements of a collection one at a time. During this process, address_space_full exceptions can occur when retrieving element pointers from the collection. For managing address space while iterating over a large collection, the following set of cursor functions are available:

void * os_cursor::first(os_address_space_marker &);void * os_cursor::last(os_address_space_marker &);void * os_cursor::next(os_address_space_marker &);void * os_cursor::previous(os_address_space_marker &);void * os_cursor::retrieve(os_address_space_marker &);

E os_Cursor<E>::first(os_address_space_marker &);E os_Cursor<E>::last(os_address_space_marker &);E os_Cursor<E>::next(os_address_space_marker &);E os_Cursor<E>::previous(os_address_space_marker &);E os_Cursor<E>::retrieve(os_address_space_marker &);

The following example demonstrates the use of an os_address_space_marker cursor for managing address_space_full conditions:

os_database * db = os_database::open("MyDatabase");

os_Collection<MyClass*> * p_coll = (os_Collection<MyClass*> *) db->find_root("MyClass_root")->get_value();

os_Cursor<MyClass*> cu(*p_coll);

os_address_space_marker asmarker;

for (MyClass * p = cu.first(asmarker); cu.more(); p = cu.next(asmarker)) { /* Process p */}

asmarker.release();

In the above example, the cursor function calls handle any address_space_full exceptions by using the os_address_space_marker to release address space that has been acquired since the marker was established. At the end of the above example, a final release of address space is done. This cleans up address space for the next step of the application.

When the element pointer is returned and processed there is the possibility of receiving another address_space_full exception. To protect against this, you can use the same os_address_space_marker to manage address space as in the following example:

os_database * db = os_database::open("MyDatabase");

os_Set<MyClass*> * p_coll = (os_Set<MyClass*> *) db->find_root("MyClass_that_root")->get_value();

os_Cursor<MyClass*> cu(*p_coll);

os_address_space_marker asmarker;

Release 6.3 47

Page 48: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Using os_address_space_marker Cursors

for (MyClass * p = cu.first(asmarker); cu.more(); p = cu.next(asmarker)) { TIX_HANDLE(err_address_space_full) { p->add_widget(); } TIX_EXCEPTION { os_soft_pointer<MyClass> sp = p; asmarker.release(); p = sp; p->add_widget(); } TIX_END_HANDLE}

asmarker.release();

In the above example, suppose another address_space_full exception happens while processing the element pointer. In the exception handler, the program can release the address space and retry processing of the element pointer. If address space still becomes full then the application fails. Some type of address space maintenance is needed, such as increasing the size the value of the OS_AS_SIZE environment variable or moving elements into multiple clusters.

Within the above exception handler, after releasing the address space, the program can call os_Cursor<E>::retrieve() to refresh the element pointer. This is instead of saving the pointer in an os_soft_pointer. However, using the os_soft_pointer approach has less overhead.

When iterating with os_address_space_marker cursors, be careful to ensure that you do not hold persistent pointers across iterations. Doing this can result in database corruption because the pointer is not valid after the address space is released. If pointers need to be saved across cursor iterations, you should save them as os_soft_pointers.

Using os_address_space_marker cursors is slightly more expensive than using the set of default interfaces. ObjectStore saves the cursor contents on each iteration and restores them when an address_space_full exception is reached. Consequently, you should use os_address_space_marker cursors only when necessary.

48 C++ Collections Guide and Reference

Page 49: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 4Using Dictionaries

Dictionaries are unordered collections that allow duplicates. Unlike other collections, dictionaries associate a key with each element. The key can be a value of any C++ fundamental type, user-defined type, or pointer type. When you insert an element into a dictionary, you specify the key along with the element. You can retrieve an element with a given key or retrieve those elements whose keys fall within a given range.

Required include files

To use ObjectStore’s dictionary facility, you must include the files <ostore/ostore.hh>, <ostore/coll.hh>, and either ostore/coll/dict_pt.hh or <ostore/coll/dict_pt.cc>, in this order. You must include dict_pt.cc when instantiating the template because it contains the bodies of the functions declared in ostore/coll/dict_pt.hh. However, users of the template can just include dict_pt.hh.

This chapter discusses the following topics:

Creating Dictionaries 49

Marking Persistent Dictionaries 51

Marking Transient Dictionaries 51

Dictionary Behavior 52

Visiting the Elements with Specified Keys 52

Writing Destructors for Dictionaries 54

Example of Using Dictionaries 55

Creating DictionariesYou can create dictionaries with an os_Dictionary constructor. For example:

os_Dictionary<char*, char*> *dict = new ( db, os_Dictionary<char*, char*>::get_os_typespec()) os_Dictionary<char*, char*>;

See the reference information for os_Dictionary::os_Dictionary() on page 220.

Dictionaries can have different types of keys as the key type parameters.

Integer keys For integer keys, specify one of the following as key type:

• os_int32 (a signed 32-bit integer)

Release 6.3 49

Page 50: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Creating Dictionaries

• os_unsigned_int32 (an unsigned 32-bit integer)

• os_int16 (a signed 16-bit integer)

• os_unsigned_int16 (an unsigned 16-bit integer)

Class keys For class keys, the class must have a destructor that zeroes any pointers it contains, a default (no arguments) constructor, and operator=.

Class keys with soft pointers

For ordered dictionaries and when the key is a class that contains a soft pointer you need to register its assignment operator using the os_assign_function() and os_assign_function_body() macros. See os_assign_function() on page 265 and os_assign_function_body() on page 265.

void* keys Use the type void* for pointer keys other than char* keys.

char* keys For char[] keys, use the parameterized type os_char_array<S>, where the actual parameter is an integer literal indicating the size of the array in bytes.

If a dictionary’s key type is char*, the dictionary makes its own copies of the character array upon insert. If the dictionary does not allow duplicate keys, you can significantly improve performance by using the type os_char_star_nocopy as the key type. With this key type, the dictionary copies the pointer to the array and not the array itself. You can freely pass chars to this type.

Note that you should not use os_char_star_nocopy with dictionaries that allow duplicate keys.

char[], char*, and os_char_star_nocopy all use strcmp() for comparison.

Floating-point keys

Because the collections library has no defined ordering for IEEE floating-point NaN values, if you are using floating-point keys and expect to generate NaN values, there are a number of possible problems. The collections library will not order floating-point keys with NaN value in any definitive way. All NaN values cannot be expected to be equal. Some may be greater than all the other keys, some may be less than all the other keys. Furthermore cross platform database compatibility is not ensured when using floating-point keys with NaN values; a NaN value generated on one platform cannot be counted on to be equal with a NaN value generated on another platform. This cross-platform problem could result in “lost keys,” meaning operations that traverse a dictionary or index might not reach all the keys.

The workaround for this problem is to wrap your floating-point key in a user-defined class and supply your own rank and hash function for that class using the os_index_key macro. In this way you can designate the way you want NaN values to be treated and you can address the issue of cross-database compatibility. Keep in mind that these rank and hash functions will be greatly used, so if performance is a priority for your application, you should keep any platform checks and computations to a minimum. See Supplying Rank and Hash Functions on page 78 and os_assign_function() on page 265 for more information.

50 C++ Collections Guide and Reference

Page 51: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 4: Using Dictionaries

Marking Persistent DictionariesIf you use persistent dictionaries, you must call the macro OS_MARK_DICTIONARY() for each key-type/element-type pair that you use. Calls to this macro have the form

OS_MARK_DICTIONARY(key-type, element-type)

Put these calls in the schema source file. For example:

/* schema.cc */

#include <ostore/ostore.hh>#include <ostore/coll.hh>#include <ostore/coll/dict_pt.hh>#include <ostore/manschem.hh>#include "dnary.hh"

OS_MARK_DICTIONARY(void*,Course*) ;OS_MARK_DICTIONARY(int,Employee**) ;OS_MARK_DICTIONARY(int,Course*) ;OS_MARK_SCHEMA_TYPE(Course) ;OS_MARK_SCHEMA_TYPE(Employee) ;OS_MARK_SCHEMA_TYPE(Department) ;

For pointer keys, use void* as the key-type.

See the reference information for OS_MARK_DICTIONARY() on page 260.

Marking Transient DictionariesIf you use only transient dictionaries, you must call the macro OS_TRANSIENT_DICTIONARY() for each key-type / element-type pair that you use. If you use a particular instantiation of an os_Dictionary template both transiently and persistently, you should use the OS_MARK_DICTIONARY() macro only. The arguments for OS_TRANSIENT_DICTIONARY() are the same as for OS_MARK_DICTIONARY(), but you call OS_TRANSIENT_DICTIONARY() at file scope in an application source file, rather than in a schema source file.

However, using OS_TRANSIENT_DICTIONARY() more than once with the same key type results in a compilation error. For example, the following does not compile correctly:

OS_TRANSIENT_DICTIONARY(int,void*);OS_TRANSIENT_DICTIONARY(int,foo*);

The problem is that both invocations of OS_TRANSIENT_DICTIONARY() cause a stub routine to be defined for the key type int. Instead, you should only invoke OS_TRANSIENT_DICTIONARY() once for each key type and use the macro OS_TRANSIENT_DICTIONARY_NOKEY() for each consecutive dictionary with the same key type. The correct use, given the example above, would be

OS_TRANSIENT_DICTIONARY(int,void*);OS _TRANSIENT_DICTIONARY_NOKEY(int,foo*);

Release 6.3 51

Page 52: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Dictionary Behavior

For related information on these macros, see OS_MARK_DICTIONARY() on page 260, OS_TRANSIENT_DICTIONARY() on page 262, and OS_TRANSIENT_DICTIONARY_NOKEY() on page 263.

Dictionary BehaviorEvery dictionary has the following properties:

• Duplicate elements are allowed.

• Null pointers cannot be inserted.

• No guarantees are made concerning whether an element inserted or removed during a traversal of its elements will be visited later in that same traversal.

By default, a new dictionary also has the following properties:

• Its entries have no intrinsic order.

• Duplicate keys are allowed; that is, two or more elements can have the same key.

• Range look-ups are not supported; that is, key order is not maintained.

You can customize the behavior of new dictionaries with regard to these last properties. For large dictionaries that maintain key order, there is also an option for reducing contention.

Visiting the Elements with Specified KeysFor dictionaries, you can specify a restriction that is satisfied by elements whose key satisfies a specified range.

os_Cursor<E> ( const os_dictionary &coll, const os_coll_range &range, os_int32 options = 0 ) ;

An element satisfies this cursor’s restriction if its key satisfies range. If the dictionary’s key type is a class, you must supply rank and hash functions for the class. To do this, the dictionary must be created with the behavior maintain_key_order. See os_Dictionary on page 215.

Picking the Element with a Specified KeyFor dictionaries, you can retrieve an element with the specified key with one of the following two functions:

E pick(const K const &key_ref) const ;

E pick(const K *key_ptr) const ;

These differ only in that with one you supply a reference to the key, and with the other you supply a pointer to the key. Again, if there is more than one element with

52 C++ Collections Guide and Reference

Page 53: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 4: Using Dictionaries

the key, an arbitrary one is picked and returned. If there is no such element, the function returns null.

Retrieving Ranges of ElementsFor dictionaries, you can also retrieve an element whose key satisfies a specified collection range with

E pick(const os_coll_range&) const ;

For example:

a_dictionary.pick( os_coll_range(GE, 100) )

returns an element of a_dictionary whose key is greater than or equal to 100. The dictionary must have the behavior os_dictionary::maintain_key_order for a pick() using an os_coll_range.

As with the other pick() overloadings, if there is more than one such element, an arbitrary one is picked and returned. If there is no such element, 0 is returned.

Retrieving Elements When the Key Type is a ClassIf the dictionary’s key type is a class, you must supply rank and hash functions for the class. See Supplying Rank and Hash Functions on page 78.

The key types char*, char[ ], and os_char_star_nocopy are each treated as a class whose rank and hash functions are defined in terms of strcmp(). For example, for char*:

a_dictionary.pick("Smith")

returns an element of a_dictionary whose key is the string “Smith” (that is, whose key, k, is such that strcmp(k, "Smith") is 0).

Release 6.3 53

Page 54: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Writing Destructors for Dictionaries

Writing Destructors for DictionariesThere are circumstances in which a slot in an ObjectStore dictionary can be reused. A slot is used for the first time when the first item is hashed to that slot during an insert. A removal of that item causes the slot to be emptied and marked as previously occupied. A subsequent insert of a key that hashes to that slot can result in the reuse of that slot to hold this new key.

When a key is removed, the destructor for the object of type K is run. Because the slot can then be reused, it is necessary for the destructor for the object of type K to null any pointers to memory that are freed in the destructor.

Example Following is an example where type K is class myString:

class myString{ private: char* theString; int len;}RMString::RMString(char* theChars){ if (theChars == 0) len = 0; else len = strlen(theChars); theString = new(os_segment::of(this), os_typespec::get_char(),len + 1) char[len+1]; if (theChars == 0) theString[0] = ‘\0’; else strcpy(theString, theChars);}RMString::~RMString(){ delete[] theString;/****************************************************** The following line solves the multiple delete problem********************************************************/ theString = 0;

}

Failure to include the line theString = 0; results in the following error if a slot is reused:

Invalid argument to operator delete

<err-0025-0608>Delete failed. Cannot locate a persistent object at address 0x5780114 (err_invalid_deletion)

54 C++ Collections Guide and Reference

Page 55: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 4: Using Dictionaries

Example of Using DictionariesA ternary relationship is a relationship among three objects, such as “student x got grade y in course z.” Dictionaries are often useful in representing ternary relationships. This section contains an example involving the classes Student, Grade, and Course, which allow you to store and retrieve information about who got what grade in what course.

Each Student object contains two dictionaries that serve to associate a course with the grade the student got in the course. One dictionary supports look-up of the grade given the course, and the other supports look-up of the courses with a given grade.

Note that the dnary.cc example includes <ostore/coll/dict_pt.cc> instead of dict_pt.hh; dict_pt.cc is needed because it contains the bodies of the functions declared in dict_pt.hh. You need not also include dict_pt.hh because it is included in dict_pt.cc. The example also includes schema.cc, which is the application’s schema source file.

Following is the file dnary.hh, which contains the class definitions. After that is the file dnary.cc, which contains the member function implementations.

Header file: dnary.hh

/* dnary.hh */

#include <ostore/ostore.hh>#include <ostore/coll.hh>#include <ostore/coll/dict_pt.hh>#include <iostream>#include <stdlib.h>

class Student ;class Grade ;class Course ;

class Student {

public: int get_id() const ; const os_Set<Course*> &get_courses() const ; int add_course( Course*, Grade* = 0 ) ; void remove_course(Course*) ; Grade *get_grade_for_course(const Course*) const ; void set_grade_for_course(Course*, Grade*) ; os_Set<Course*> &get_courses_with_grade( const Grade* ) const ; float get_gpa() const ; static os_typespec *get_os_typespec() ; Student(int id, os_segment*); ~Student() ;

private: int id ; os_Set<Course*> & courses ; os_Dictionary<void*, Grade*> & course_grade; os_Dictionary<void*, Course*> & grade_course;

} ;

class Grade {

public:

Release 6.3 55

Page 56: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Example of Using Dictionaries

const char *get_name() const ; float get_value() const ; static os_typespec *get_os_typespec() ; Grade(const char *name, float value, os_segment*) ; ~Grade() ;

private: char *name ; float value ;

} ;

class Course {

public: Course(char* name, int num); `Course(); const char* name() const { return_name; } const int number() const { return _num; } static os_typespec* get_os_typespec() ; private: char * _name; int _num;

} ;

Main program: dnary.cc

/* dnary.cc */

#include <ostore/ostore.hh>#include <ostore/coll.hh>#include <ostore/coll/dict_pt.cc> #include "dnary.hh"

typedef os_Dictionary<void*,Course*> grade_course_dnary ;typedef os_Dictionary<void*,Grade*> course_grade_dnary ;

/* Student member function implementations */

int Student::get_id() const { return id ;}

const os_Set<Course*> &Student::get_courses() const { return courses ;}

int Student::add_course( Course *c, Grade *g ) { if ( courses.contains(c) ) return 0 ; courses.insert(c) ;

if (g) { grade_course.insert(g, c) ; course_grade.insert(c, g) ; } /* end if */ return 1 ;}

void Student::remove_course(Course *c) { courses.remove(c) ; grade_course.remove( course_grade.pick(c), c ) ; course_grade.remove_value(c) ;}

Grade *Student::get_grade_for_course(const Course * c) const { return course_grade.pick((Course*)c) ;

56 C++ Collections Guide and Reference

Page 57: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 4: Using Dictionaries

}

void Student::set_grade_for_course(Course *c, Grade *g) { grade_course.remove(course_grade.pick(c), c) ; course_grade.remove_value(c) ; grade_course.insert(g, c) ; course_grade.insert(c, g) ;}

os_Set<Course*> & Student::get_courses_with_grade(const Grade *g) const { os_Set<Course*> &the_courses = *new(os_database::get_transient_database(), os_Set<Course*>::get_os_typespec()) os_Set<Course*> ; os_cursor cur(grade_course, os_coll_range( os_collection::EQ, g)) ;

for ( Course *c = (Course*) cur.first() ; c ; c = (Course*) cur.next() ) the_courses.insert(c) ; return the_courses ;}

float Student::get_gpa() const { float sum = 0.0 ; os_cursor c(course_grade) ; for ( Grade *g = (Grade*) c.first(); g; g = (Grade*) c.next() ) sum = sum + g->get_value() ; return sum / course_grade.cardinality(); }

Student::Student(int i, os_segment *seg) : courses(*new(seg, os_Set<Course*>::get_os_typespec()) os_Set<Course*>), course_grade(*new(seg, os_Dictionary<void*, Grade*>::get_os_typespec()) os_Dictionary<void*, Grade*>(10)), grade_course(*new(seg, os_Dictionary<void*, Course*>::get_os_typespec()) os_Dictionary<void*, Course*> ) { id = i;}

Student::~Student() { os_Collection<Course*> *courses_ptr = &courses ; os_Dictionary<void*, Grade*> *course_grade_ptr = &course_grade ; os_Dictionary<void*, Course*> *grade_course_ptr = &grade_course ; delete courses_ptr ; delete course_grade_ptr ; delete grade_course_ptr ;}

/* Grade member function implementations */

const char *Grade::get_name() const { return name ;}

float Grade::get_value() const { return value ;

Release 6.3 57

Page 58: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Example of Using Dictionaries

}

Grade::Grade(const char *n, float v, os_segment *seg) { name = new( seg, os_typespec::get_char(), strlen(n)+1 ) char[strlen(n)+1] ; ::strcpy(name, n) ; value = v ;}

Grade::~Grade() { delete name ;}

/* Course member function implementations */

Course::Course(char* name, int num) : _num(num){ int len = ::strlen(name) +1; _name = new (os_segment::of(this), os_typespec::get_char(), len) char[len]; ::strcpy(_name, name);}

Course::~Course(){ delete [] _name;}

#if (defined(_MSC_VER) && (_MSC_VER >= 1300))#pragma warning( disable : 4717 )#endif

void force_vfts(void *) { force_vfts(new os_Dictionary<char *, Grade *>); force_vfts(new os_Dictionary<os_char_star_nocopy, Course *>); force_vfts(new os_Dictionary<void *, Course *>); force_vfts(new os_Dictionary<void *, Grade *>); force_vfts(new os_List<Student *>); force_vfts(new os_List<Course *>); force_vfts(new os_Set<Student *>); force_vfts(new os_Set<Course *>); force_vfts(new os_Array<Course *>); force_vfts(new os_Array<Student *>); force_vfts(new os_Bag<Student *>); force_vfts(new os_Bag<Course *>); force_vfts(new os_Collection<Student *>);}

Schema file: schema.cc

/* schema.cc */

#include <ostore/ostore.hh>#include <ostore/coll.hh>#include <ostore/coll/dict_pt.hh>#include <ostore/manschem.hh>

#include "dnary.hh"

OS_MARK_DICTIONARY(void*,Course*); OS_MARK_DICTIONARY(void*,Grade*); OS_MARK_SCHEMA_TYPE(Course); OS_MARK_SCHEMA_TYPE(Student); OS_MARK_SCHEMA_TYPE(Grade);

58 C++ Collections Guide and Reference

Page 59: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 4: Using Dictionaries

Example description

The data member Student::courses contains a reference to a set of pointers to the courses the student has taken.

The data member Student::course_grade contains a reference to a dictionary that maps each course to the grade the student got for that course. This dictionary supports look-up of the grade given the course.

The data member Student::grade_course contains a reference to a dictionary that maps each grade to the courses for which the student got that grade. This dictionary supports look-up of the courses given the grade.

The function Student::add_course() first checks to see if the specified course has already been added. If it has, 0 (indicating failure) is returned. If it has not, the function inserts the specified course into the set referred to by Student::courses. Then, if a grade is specified, entries are inserted into the dictionaries referred to by Student::course_grade and Student::grade_course. Finally, 1 (indicating success) is returned.

The function Student::remove_course() removes the specified course from Student::courses. If the course is not an element of courses, the call to remove() has no effect.

Then, using pick() on course_grade, remove_course() determines the grade for the given course. The grade and the course are then passed to os_Dictionary::remove() to remove from Student::grade_course the entry whose value is the given course. The function add_course() ensures that there is at most one.

If the course is not an element of the dictionary, pick() returns 0 and the call to remove() has no effect.

Finally, using os_Dictionary::remove_value(), remove_course() removes from Student::Course_grade the entry whose key is the given course. Again, add_course() ensures there is at most one. If the dictionary has no entry whose key is that course, the call to remove_value() has no effect.

Student::get_grade_for_course() uses os_Dictionary::pick() to retrieve from Student::course_grade the element whose key is the given course.

Student::set_grade_for_course() first takes precautions in case the specified course already has been assigned a grade. It removes from Student::course_grade and Student::grade_course any entries with the given course. It does this as follows.

First, the function performs remove() on grade_course, passing in the grade for the given course (determined by performing pick() on course_grade) and also passing in the given course itself. If no grade has been set for the course, pick() returns 0 and the call to remove() has no effect. Then the function uses remove_value() to remove from course_grade the entry, if there is one, whose key is the given course.

Next, Student::set_grade_for_course() inserts into grade_course an entry whose key is the specified grade and whose value is the specified course. Finally, it

Release 6.3 59

Page 60: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Example of Using Dictionaries

inserts into course_grade an entry whose key is the specified course and whose value is the specified grade.

The function Student::get_courses_with_grade() returns a reference to a collection of the courses for which the student got the specified grade. It creates a collection on the transient heap and then uses a restricted cursor to visit each element of grade_course whose key is the specified grade. As each qualifying element is visited, it is inserted into the newly created collection. Finally, a reference to the collection is returned.

The function Student::get_gpa() returns the student’s grade point average. It visits each element of the dictionary course_grade, summing the result of performing get_value() on each element along the way. When the traversal is complete, the sum is divided by the dictionary’s size to get the average, which is returned.

The Student constructor allocates an os_Set and two instances of os_Dictionary in the specified segment.

60 C++ Collections Guide and Reference

Page 61: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 5Performing Advanced Collections Operations

After you are familiar with the basic use of collections, you can use the information in this chapter to perform more advanced operations with collections. This chapter discusses the following topics:

Using Paths in Navigation 62

Creating Paths 62

Paths and Member Functions 64

Controlling Traversal Order 68

Using Ranges in Navigation 70

Specifying Collection Ranges 71

Restricting the Elements Visited in a Traversal 73

Performing Collection Updates During Traversal 74

Retrieving Uniquely Specified Collection Elements 74

Selecting Individual Collection Elements with pick() 75

Consolidating Duplicates with operator =() 77

Supplying Rank and Hash Functions 78

Specifying Expected Size 80

Release 6.3 61

Page 62: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Using Paths in Navigation

Using Paths in NavigationThe ObjectStore collections facility provides a number of classes that help you navigate within a collection. The os_Cursor class, the os_index_path class, and the os_coll_range class all help you insert and remove elements as well as retrieve particular elements or sequences of elements.

• The os_Cursor class is discussed in Chapter 3, Using Cursors to Navigate Collections, on page 41. See also os_Cursor on page 203.

• The os_coll_range class is described in Using Ranges in Navigation on page 70. See also os_coll_range on page 199.

The os_index_path class is discussed here and in the immediately following sections of this chapter. See also os_index_path on page 226.

A path, an instance of os_index_path, represents a navigational path starting from the elements of a collection. Paths are used to specify index keys and to specify a cursor’s associated order. See Creating Paths on page 62; also see Paths and Member Functions on page 64.

Paths are also used in conjunction with ranges to specify a restriction on the elements that a cursor visits. See Using Ranges in Navigation on page 70 for information on ranges.

Creating PathsPaths are used to specify traversal order (see Controlling Traversal Order on page 68) and index keys.

Simple PathsUsing the simplest kind of path, you can base an index key or iteration order on the value of some data member or simple member function. For example, you can iterate through a set of parts in order of the parts’ part numbers (parts with lower numbers precede parts with higher numbers). The member is specified with an instance of the class os_index_path, which designates a member access path.

To iterate in order of part numbers, first create a path with os_index_path::create(), which returns an os_index_path&:

os_index_path::create("part*", "part_number", db1)

The object created designates the path from part pointers to their part numbers. Here, part* is the path’s type string, which names the element type of collections whose elements can serve as path starting points. part_number is a path string indicating the data member itself. The argument db1 is a database whose schema contains the definition of the class part.

Both type strings and path strings can contain white space around tokens.

62 C++ Collections Guide and Reference

Page 63: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 5: Performing Advanced Collections Operations

The instance of os_index_path generated by the call to create() is heap allocated. When you no longer need it, you should delete it. For information about deleting objects, see ::operator delete() in Chapter 3 of C++ A P I Reference.

Multiple Member PathsSometimes path expressions specify not just a single member but a navigational path involving multiple member accesses. For example, to base iteration order on the emp_id of a part’s responsible_engineer, you create the following path:

os_index_path::create( "part*", "responsible_engineer->emp_id", db1) ;

Examples of Eath expressionsA path applied to a pointer to an employee, returning the employee’s name, is specified by the path expression

os_index_path::create("employee*", "name", db1)

A path applied to a pointer to an employee, returning the employee’s manager, is specified by

os_index_path::create( "employee*", "department–>manager", db1)

A path applied to a pointer to an employee, returning the name of each of the employee’s supervisees, is specified by

os_index_path::create( "employee*", "supervisees[ ]–>name", db1)

Brackets ([ ]) in a path indicate that the path goes through each element of the indicated collection. The path mapping follows the remainder of the specified path for each element. Thus, application of a path mapping can result in many values.

In this last example, the path maps a single employee* to many names, the names of the employee’s supervisees. If you use such a path to specify a key for an index, the index would handle look-up of an employee by the name of any one of the employee’s supervisees.

But paths with brackets cannot be used to specify iteration order. Iteration in order of names of supervisees is not well defined because there is more than one supervisee. In contrast, iterating by name of supervisor, for example, is well defined if each employee has exactly one supervisor.

Another important point is that if an index path contains a path through a collection, this collection either has to be parameterized or you must cast it to the appropriate type of parameterized collection in the index path string. This is necessary so that the index path parser can determine whether, for example, name is a valid data member of the type of element in the supervisees collection. For example:

Release 6.3 63

Page 64: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Paths and Member Functions

(os_Collection<employee*>&)supervisees[]->name

Rank and Hash FunctionsPaths that end in a class or that end in a floating numerical type must have associated rank and/or hash functions. You must register these functions by calling os_index_key(). See os_index_key() Macro on page 78.

Paths and Member FunctionsMember functions called in path strings are subject to certain restrictions and prerequisites, as described in this section.

RestrictionsMember functions called in query or path strings are subject to certain restrictions:

• The return type can be any type, but if it is a user-defined type, the rank/hash functions for the type must be defined.

• The function must take no arguments.

For example, consider the following class:

class person { private: unsigned int age; person* sibling;

public: unsigned int get_age();

person* get_sibling(); unsigned int get_age_n_years_ago(unsigned int n);}

The functions get_age() and get_sibling() can be referenced in a query or path string. get_age_n_years_ago() violates the second of the preceding restrictions.

To perform a query, ObjectStore sometimes (depending on what indexes are present) issues calls to member functions used in paths and queries. If such a member function allocates memory that it does not free (for example if it returns a pointer to newly allocated memory), memory leaks can result; ObjectStore does not free the space that the function allocates. So member functions used in paths or queries should not allocate persistent memory or memory in the transient heap.

PrerequisitesApplications that use a member function in a query or path string must do four things:

1 Define an os_backptr-valued data member in the class that defines the member function. This data member must appear before any query functions in the class definitions.

64 C++ Collections Guide and Reference

Page 65: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 5: Performing Advanced Collections Operations

2 Call the macro os_query_function().

3 Call the macro os_query_function_body().

4 Call the macro OS_MARK_QUE RY_FUNCTION().

You can name the os_backptr member anything you want. In addition, you can use the same os_backptr member for indexable data members and member functions; a class never needs to define more than one os_backptr-valued member.

os_query_function() MacroA call to os_query_function() has the form

os_query_function(class,func,return_type)

where

• class is the name of the class defining the member function.

• func is the name of the member function itself.

• return_type names the type of value returned by the member function.

The os_query_function() macro should be invoked at module level in a header file (for example, the file containing the definition of the class that declares the member function). No white space should appear in the argument list.

os_query_function_returning_ref() MacroIf an application uses a member function in a query and the function returns a reference, the application must call os_query_function_returning_ref().

A call to os_query_function_returning_ref() has the form

os_query_function_returning_ref(class,func,return_type)

where

• class is the name of the class defining the member function.

• func is the name of the member function itself.

• return_type names the type of value returned by the member function. The way to use this is to pass just return_type, not return_type&, to the macro return_type arguments.

In query and index path strings, functions returning references should be treated as if they returned pointers. For example, queries over the function

Name& get_name();

should be written as if the function signature were

Name* get_name();

That is,

*get_name() == *(Name*) Freevar

An index path to support this query would be

*get_name()

Release 6.3 65

Page 66: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Paths and Member Functions

os_query_function_body() MacroA call to os_query_function_body() has the form

os_query_function_body(class,func,return_type,bpname)

where

• class is the name of the class that defines the member function.

• func is the name of the member function itself.

• return_type names the type of value returned by the member function.

• bpname is the name of the os_backptr-valued member of class.

The os_query_function_body() macro should be invoked at module level in a source file (for example, the file containing the definition of the member function). No white space should appear in the argument list.

OS_MARK_QUERY_FUNCTION() MacroA call to OS_MARK_QUERY_FUNCTION() has the form

OS_MARK_QUERY_FUNCTION(class,func)

where

• class is the name of the class that defines the member function.

• func is the name of the member function itself.

The OS_MARK_QUERY_FUNCTION() macro should be invoked along with the OS_MARK_SCHEMA_TYPE() macros for an application’s schema, that is, in the schema source file, inside the dummy function containing the calls to OS_MARK_SCHEMA_TYPE(). No white space should appear in the argument list of OS_MARK_QUERY_FUNCTION().

For information about the OS_MARK_QUERY_FUNCTION() macro, see OS_MARK_QUERY_FUNCTION() on page 261. For information about the OS_MARK_SCHEMA_TYPE() macro, see OS_MARK_SCHEMA_TYPE() in Chapter 4 of the C++ A P I Reference.

os_query_function_body_returning_ref() MacroThis macro enables users to register a query function that returns a reference. The application that uses this member function in a query must call os_query_function_body_returning_ref(). A call to this macro has the form

os_query_function_body_returning_ref( class,func,return_type,bpname

)where

• class is the name of the class defining the member function.

• func is the name of the member function itself.

66 C++ Collections Guide and Reference

Page 67: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 5: Performing Advanced Collections Operations

• return_type names the type of value returned by the member function. The way to use this is to pass just return_type, not return_type&, to the return_type arguments of the macro.

• bpname is the name of the os_backptr-valued member of class.

Use of Functions Returning References in Query StringsIn query and index path strings, functions returning references should be treated as if they returned pointers. For example, queries over the function

Name& get_name();

should be written as if the function signature were

Name* get_name()

That is,

*get_name() == *(Name*)Freevar

An index path to support this query would be

*get_name()

Path String Syntax ExtensionGiven a path string that specifies a path ending in pointers to objects:

path-string

If the last component of the path string is a member function name, you can construct a path string to specify a path ending in those objects themselves, using * (asterisk) as follows:

* (path-string)

The parentheses are not necessary if the original path string specifies a single-step path.

Consider, for example, the path

os_index_path::create( "rectangle*", "get_location()", db) ;

If the function rectangle::get_location() returns a pointer to a coord object, this path ends in pointers to coord objects. So you can also construct a path that ends in coord objects themselves, rather than pointers:

os_index_path::create( "rectangle*", "*get_location()", db) ;

Release 6.3 67

Page 68: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Controlling Traversal Order

Index MaintenanceTo maintain indexes keyed by paths containing member function calls, use os_backptr::make_link() and os_backptr::break_link(). See User-Controlled Index Maintenance with an os_backptr on page 109.

Controlling Traversal OrderTo control traversal order, use one of the constructors for os_Cursor. The various overloadings allow you to specify a traversal order based on

• Default traversal order

• The order in persistent memory of the objects pointed to by collection elements

• The rank function registered for the collection’s element type

• A specified rank function

• A specified path

The following sections discuss traversals.

Default Traversal Order os_Cursor( const os_Collection&, os_int32 options );

Every cursor has an associated ordering for the elements of its associated collection. By default, this ordering is the order in which each element appears in the collection (for ordered collections) or an arbitrary ordering (for unordered collections).

Address Order TraversalThere are two options that allow the cursor to iterate in object address order:

• If you supply os_cursor::order_by_address as the options argument, the cursor iterates in address order. This is the order in which the objects pointed to by collection elements are arranged in persistent memory.

• If you supply os_cursor::order_by_DSCO as the options argument, the cursor iterates the collection element pointers in database/segment/cluster/offset order.

The difference between the two options is that order_by_DSCO handles address_space_full exceptions when creating the cursor. The ordering for order_by_DSCO is in address space order unless an address_space_full exception is hit at which time the pointers are saved as os_soft_pointers and the sorting is done in DSCO order.

Both options are useful if you dereference each collection element as you retrieve it because the order can dramatically reduce paging overhead resulting in improved performance. An order_by_DSCO cursor should only be used for this purpose.

Both order_by_address and order_by_DSCO cursors are update insensitive.

68 C++ Collections Guide and Reference

Page 69: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 5: Performing Advanced Collections Operations

Rank-Function-Based Traversalos_Cursor( const os_Collection&, const char* typename, ) ;

If you create a cursor with this constructor, iteration follows the order determined by the rank function of the element type specified by typename. See Supplying Rank and Hash Functions on page 78.

os_Cursor( const os_Collection&, _Rank_fcn) ;

_Rank_fcn is a pointer to a rank function for the element type. Iteration using a cursor created with this constructor follows the order determined by this function.

Rank-function-based cursors are update insensitive. See Performing Collection Updates During Traversal on page 74.

Path-Based Traversal os_Cursor( const os_Collection&, const os_index_path&) ;

If you create a cursor with this constructor, iteration follows the order determined by os_index_path. See Creating Paths on page 62.

Multiple member paths

In the case of multiple member paths (see Multiple Member Paths on page 63), the traversal first visits all elements that have a complete path and then visits the other elements in order of decreasing path length. That is, given the path boss->boss->boss->name, the cursor first visits those collection elements that actually have a boss->boss->boss in name order before visiting any that do not.

Reuse of an os_index_path

Note that after you have created an os_index_path, you can reuse it (for example, to specify the same order for another iteration or to specify the key of an index). There is no need to create a separate index path each time you specify an iteration order or index.

char* paths Paths whose values are char* are treated specially by the iteration facility. An ordered iteration based on a char*-valued member does not iterate in order of addresses (the values, strictly speaking, of the data member), but proceeds in the order of the strings pointed to. The order is determined by the function strcmp().

Example Following is a code fragment demonstrating iteration by responsible_engineer’s emp_id:

os_index_path &a_path = os_index_path::create( "part*", "responsible_engineer–>emp_id", db1) ;

os_Cursor<part*> c(a_set, a_path) ;

Release 6.3 69

Page 70: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Using Ranges in Navigation

part *p = 0 ;for (p = c.first(); p; p = c.next()) printf("%d", e–>emp_id) ;

If an index on the path is present, it is used to make the traversal more efficient.

If an index on the iteration path is not present, the cursor constructor copies the collection elements into a separate structure, applies the path to each element, copies the terminal key into that structure, then sorts it according to the key rank. Care is taken to sort the structure by address whenever the path interpretation calls for dereferencing a pointer, in order to improve paging behavior. Cursor creation time depends on the length of the path, the size of the collection, and the complexity of the rank function.

When you are performing path-based traversal over some collection, if you update a data member on which the ordering is based, you are effectively removing and then reinserting the element you changed. In other words, when you update such a data member for an element of a collection, you also update the collection itself.

Using Ranges in NavigationThe ObjectStore collections facility provides a number of classes that help you navigate within a collection. The os_Cursor class, the os_index_path class, and the os_coll_range class all help you insert and remove elements as well as retrieve particular elements or sequences of elements.

• The os_Cursor class is discussed in Chapter 3, Using Cursors to Navigate Collections, on page 41; see also os_Cursor on page 203.

• The os_index_path class is described in Using Paths in Navigation on page 62. See also os_index_path on page 226.

The os_coll_range class is discussed here and in the immediately following sections of this chapter. See also os_coll_range on page 199.

RangesA range, an instance of os_coll_range, represents a range of values. A range can be used in conjunction with a path to restrict the elements visited by a cursor. See Specifying Collection Ranges on page 71 and Restricting the Elements Visited in a Traversal on page 73.

You can also use an os_coll_range to retrieve from a dictionary the elements whose key falls within a specified range. See Chapter 4, Using Dictionaries, on page 49.

Both these uses of ranges provide a way of performing inexpensive, simple queries without some of the overhead associated with using query(), query_pick(), or exists(). See Chapter 6, Querying Collections, on page 81, for more detailed information about performing queries.

70 C++ Collections Guide and Reference

Page 71: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 5: Performing Advanced Collections Operations

Specifying Collection RangesYou can create an object that represents a range of values with the class os_coll_range. An instance of this class can be used as argument to the os_Cursor constructor to create a restricted cursor or as argument to os_Dictionary::pick().

The constructor for os_coll_range has several overloadings. Each overloading falls into one of the following two groups:

• Overloadings that specify both a lower and upper bound on a range of values (as in “all values greater than 4 and less than or equal to 7”)

• Overloadings that specify just a lower bound or just an upper bound (as in “all values less than or equal to 7”)

In each of these two groups, there is one overloading for each C++ fundamental type of value and one for the type void*. To specify a range for any type of pointer value, use a void* overloading.

Ranges with Only One BoundFollowing are the overloadings for os_coll_range() that specify only an upper or lower bound:

os_coll_range(int rel_op, int value) ;

os_coll_range(int rel_op, unsigned int value) ;

os_coll_range(int rel_op, short value) ;

os_coll_range(int rel_op, unsigned short value) ;

os_coll_range(int rel_op, char value) ;

os_coll_range(int rel_op, unsigned char value) ;

os_coll_range(int rel_op, long value) ;

os_coll_range(int rel_op, unsigned long value) ;

os_coll_range(int rel_op, float value) ;

os_coll_range(int rel_op, double value) ;

os_coll_range(int rel_op, const void* value) ;

The argument rel_op should be one of the following enumerators:

• os_collection::EQ (equal to)

• os_collection::NE (not equal to)

• os_collection::LT (less than)

• os_collection::LE (less than or equal to)

• os_collection::GT (greater than)

• os_collection::GE (greater than or equal to)

A collection range created with one of these functions is satisfied by all values that bear the relation rel_op to value. When the value type is char*, these operators are defined in terms of strcmp().

Release 6.3 71

Page 72: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Specifying Collection Ranges

So, for example,

os_coll_range( os_collection::LE, 7)

is satisfied by all values less than or equal to 7, and

os_coll_range( os_collection::EQ, 7)

is satisfied only by the value 7.

os_coll_range( os_collection::LE, "foo")

is satisfied by any char* value, s, such that strcmp(s,"foo") is less than or equal to 0.

os_coll_range( os_collection::EQ, "foo")

is satisfied by any char* value, s, such that strcmp(s, "foo") is 0.

Ranges with Both an Upper and Lower BoundFollowing are the overloadings for os_coll_range() that specify both an upper and lower bound.

os_coll_range(int rel_op1, int value1, int rel_op2, int value2) ;

os_coll_range(int rel_op1, unsigned int value1, int rel_op2, unsigned int value2) ;

os_coll_range(int rel_op1, short value1, int rel_op2, short value2) ;

os_coll_range(int rel_op1, char value1, int rel_op2, char value2) ;

os_coll_range(int rel_op1, unsigned char value1, int rel_op2, unsigned char value2) ;

os_coll_range(int rel_op1, long value1, int rel_op2, long value2) ;

os_coll_range(int rel_op1, unsigned long value1, int rel_op2, unsigned long value2) ;

os_coll_range(int rel_op1, float value1, int rel_op2, float value2) ;

os_coll_range(int rel_op1, double value1, int rel_op2, double value2) ;

os_coll_range(int rel_op1, const void *value1, int rel_op2, const void *value2) ;

Constructs an os_coll_range satisfied by all values that both bear the relation rel_op1 to value1 and bear the relation rel_op2 to value2. The arguments rel_op and rel_op2 should be one of the following enumerators:

• os_collection::EQ (equal to)

• os_collection::NE (not equal to)

• os_collection::LT (less than)

• os_collection::LE (less than or equal to)

72 C++ Collections Guide and Reference

Page 73: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 5: Performing Advanced Collections Operations

• os_collection::GT (greater than)

• os_collection::GE (greater than or equal to)

When the value type is char*, these relations are defined in terms of strcmp(). So, for example:

os_coll_range( os_collection::GT, 4, os_collection::LE, 7)

is satisfied by all ints greater than 4 and less than or equal to 7.

Do not specify the null range, for example:

os_coll_range( os_collection::LT, 4, os_collection::GT, 7 )

Do not specify a discontinuous range, for example:

os_coll_range( os_collection::GT, 4, os_collection::NE, 7)

If you do, the exception err_am is signaled and the following message is issued to stdout:

No handler for exception:<maint-0023-0001>invalid restriction on unordered index (err_am)

Restricting the Elements Visited in a TraversalA special overloading of the os_Cursor constructor allows you to create a cursor for including in traversals only those collection elements that satisfy a specified restriction. Using such a cursor allows you to perform simple queries that are less expensive than queries performed with os_collection::query().

os_Cursor<E> ( const os_Collection<E> & coll, const os_index_path &path, const os_coll_range &range, os_int32 options ) ;

An element satisfies the cursor’s restriction if the result of applying path to the element satisfies range (see Specifying Collection Ranges on page 71). The order of iteration is arbitrary.

See also Chapter 3, Using Cursors to Navigate Collections, on page 41.

DictionariesFor dictionaries, you can specify a restriction that is satisfied by elements whose key satisfies a specified range.

os_Cursor<E> ( const os_dictionary & coll, const os_coll_range &range, os_int32 options );

Release 6.3 73

Page 74: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Performing Collection Updates During Traversal

An element satisfies this cursor’s restriction if its key satisfies range. If the dictionary’s key type is a class, you must supply rank and hash functions for the class. See Supplying Rank and Hash Functions on page 78.

DuplicatesWith a restricted cursor, a traversal visits only one occurrence of each qualified element.

Performing Collection Updates During Traversal

If you want to be able to update a collection while traversing it, you must use an update-insensitive cursor.

With an update-insensitive cursor, the traversal is based on a snapshot of the collection elements at the time the cursor was bound to the collection. None of the inserts and removes performed on the collection is reflected in the traversal.

If you update a collection while traversing it without using an update-insensitive cursor, the results of the traversal are undefined.

You can create an update-insensitive cursor with the following cursor constructor:

os_Cursor(const os_Collection&, os_int32 options) ;

Supply os_collection::update_insensitive as the options argument.

In addition, the following kinds of cursors are always update insensitive:

• Rank-function-based cursors. See Rank-Function-Based Traversal on page 69.

• order_by_address cursors. See Address Order Traversal on page 68.

Retrieving Uniquely Specified Collection Elements

You can retrieve the collection element at which a specified cursor is positioned with the following function:

E retrieve(const os_Cursor<E>&) const ;

If the cursor is null, err_coll_null_cursor is signaled. If the cursor is nonnull but not positioned at an element, err_coll_illegal_cursor is signaled.

You can retrieve the only element of a collection with the following function:

E only() const ;

74 C++ Collections Guide and Reference

Page 75: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 5: Performing Advanced Collections Operations

If the collection has more than one element, err_coll_not_singleton is signaled. If the collection is empty, 0 is returned.

Ordered CollectionsFor ordered collections, you can retrieve the element with a specified numerical position with the following function:

E retrieve(os_unsigned_int32 index) const ;

The index is zero based. If the index is not less than the collection’s size, err_coll_out_of_range is signaled. If the collection does not have maintain_order behavior, err_coll_not_supported is signaled.

retrieve_first() function

You can retrieve a collection’s first element with the following function:

E retrieve_first() const ;

This function returns the collection’s first element, or 0 if the collection is empty. If the collection is not ordered, err_coll_not_supported is signaled.

For collections with allow_nulls behavior, you can use the following function instead:

os_int32 retrieve_first(const E&) const ;

This function modifies the argument to refer to the collection’s first element. It returns 0 if the specified collection is empty, and nonzero otherwise. If the collection is not ordered, err_coll_not_supported is signaled.

retrieve_last() function

To retrieve a collection’s last element, use

E retrieve_last() const ;

This function returns the collection’s last element, or 0 if the collection is empty. If the collection is not ordered, err_coll_not_supported is signaled.

For collections with allow_nulls behavior, you can use the following function instead:

os_int32 retrieve_last(const E&) const ;

This function modifies the argument to refer to the collection’s last element. It returns 0 if the specified collection is empty, and nonzero otherwise. If the collection is not ordered, err_coll_not_supported is signaled.

Selecting Individual Collection Elements with pick()

The function os_collection::pick() can be used to perform simple queries. It provides a relatively inexpensive alternative to os_collection::query_pick() and os_collection::exists(). With the following overloading, you can retrieve a collection element such that the result of applying path (see Creating Paths on

Release 6.3 75

Page 76: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Selecting Individual Collection Elements with pick()

page 62) to the element is a value that satisfies range (see Specifying Collection Ranges on page 71):

void* pick( const os_index_path &path, const os_coll_range &range) const;

For example:

const os_index_path &id_path = os_index_path::create("employee*", "id", db1) ;os_coll_range range_eq_1138(EQ, 1138) ;. . . employee *e = a_coll.pick(id_path, range_eq_1138) ;

assigns to e an employee in a_coll whose id equals 1138.

If there is more than one such element, an arbitrary one is picked and returned. If there is no such element, 0 is returned.

DictionariesFor dictionaries, you can retrieve an element with the specified key, with one of the following two functions:

E pick(const K const &key_ref) const ;

E pick(const K *key_ptr) const ;

These two differ only in that with one you supply a reference to the key, and with the other you supply a pointer to the key. Again, if there is more than one element with the key, an arbitrary one is picked and returned. If there is no such element, 0 is returned.

For dictionaries, you can also retrieve an element whose key satisfies a specified collection range (see Specifying Collection Ranges on page 71) with

E pick(const os_coll_range&) const ;

For example:

a_dictionary.pick( os_coll_range(GE, 100) )

returns an element of a_dictionary whose key is greater than or equal to 100.

As with the other pick() overloadings, if there is more than one such element, an arbitrary one is picked and returned. If there is no such element, 0 is returned.

If the dictionary’s key type is a class, you must supply rank and hash functions for the class (see Supplying Rank and Hash Functions on page 78).

The key types char*, char[ ], and os_char_star_nocopy are each treated as a class whose rank and hash functions are defined in terms of strcmp(). For example, for char*:

a_dictionary.pick("Smith")

returns an element of a_dictionary whose key is the string Smith (that is, whose key, k, is such that strcmp(k, "Smith") is 0).

76 C++ Collections Guide and Reference

Page 77: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 5: Performing Advanced Collections Operations

Picking an Arbitrary ElementYou can retrieve an arbitrary collection element with

E pick() const;

If the collection is empty, 0 is returned.

This is sometimes useful when all the elements of a collection have the same value for a data member and the easiest way to retrieve this value is through one of the elements.

For example, suppose the class bus defines a member for the set of pins connected to it but no member for the cell in which it resides, while pin defines a member pointing to its attached cell, which in turn has a member pointing to its containing cell. The best way to find the cell on which a given bus resides is to find the pins connected to it and then find the cell on which one of the pins resides:

a_cell = a_bus–>pins.pick()–>cell->container;

Consolidating Duplicates with operator =()You can use the assignment operator os_Collection::operator =() (see Copying, Combining, and Comparing Collections on page 37) to consolidate duplicates in a bag or other collection. Do this by assigning the collection with duplicates to an empty collection that does not allow duplicates. For example:

os_database *db1 ;part *a_part, *p ;employee *e ;. . . os_Bag<employee*> &emp_bag = *new(db1, os_Bag<employee*>::get_os_typespec()) os_Bag<employee* >;

os_Set<employee*> &emp_set = = *new(db1, os_Set<employee* >::get_os_typespec()) os_Set<employee* >;

os_Cursor<part*> c(a_part->children) ; for ( p = c.first() ; p ; p = c.next() ) emp_bag.insert(p–>responsible_engineer) ;

emp_set = emp_bag ; // consolidate duplicates

os_Cursor<employee*> c(emp_set) ;

for (e = c.first() ; e ; e = c.next() ) cout << e–>name << "\t" << emp_bag.count(e) << "\n" ;

If two of a_part’s children have the same responsible_engineer, that engineer appears twice as an element of emp_bag. You can consolidate duplicates in emp_set so you can iterate over it, retrieving each engineer only once in the loop and then use count() to see how many times the engineer occurs in emp_bag. This is the number of parts for which the engineer is responsible.

Release 6.3 77

Page 78: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Supplying Rank and Hash Functions

Supplying Rank and Hash FunctionsIn all these examples, iteration order is based on integer-valued data members (part_number, emp_id, or salary); that is, the paths end in integer values. The integers have a system-supplied order, defined by the comparison operators <, >, and so forth. The same is true for pointers. For char* pointers, which are treated differently from other pointers, the order is defined by performing strcmp() on the string pointed to. But what if a path ends in some other type of value; that is, what if it ends in the instances of some class or floating-point numerical type?

If you want to use such a path to control iteration order, you must make known to ObjectStore a utility specific to the class, a rank function that defines an ordering on the type’s instances.

You must also supply a rank function if you use such a path to specify a key for an ordered index (see Index Options on page 101). For unordered indexes keyed by such paths, you must supply both a rank and a hash function (the rank function is used to resolve hashing collisions). ObjectStore uses these utilities to maintain proper information on index paths that end in the class.

Registering To register a rank or hash function, you must call os_index_key() from within a session. This function registers a rank or hash function for the entire process. Calling os_index_key() outside any session has no effect.

For more information about sessions, see Chapter 3, Multithread and Multisession Applications, in ObjectStore Advanced C++ A P I User Guide.

Floating-point keys

If you are using floating-point keys and expect to generate NaN values, you should wrap your floating-point key in a user-defined class and supply your own rank and hash function for that class using the os_index_key macro. See Floating-point Keys on page 96 for more information.

os_index_key() MacroYou make these utilities known to ObjectStore by calling the macro os_index_key(). Calls to os_index_key() have the following form:

os_index_key(type,rank-function,hash-function);

For example:

os_index_key(date,date_rank,date_hash);

The type is the type that is at the end of the path.

For information about the os_index_key() macro, see os_assign_function() on page 265.

Rank FunctionsThe rank-function is a user-defined global function that, for any pair of instances of class, provides an ordering indicator for the instances, much as strcmp() does for strings. The rank function should return one of os_collection::LT, os_collection::GT, or os_collection::EQ.

78 C++ Collections Guide and Reference

Page 79: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 5: Performing Advanced Collections Operations

Rank functions for floating-point numerical types (float, double, and long double) should follow these guidelines:

• NaN and inf must be handled specially. For example, the representation of NaN is not unique. In the rank function, test for these values before doing anything else. You might want NaN to rank below any other value.

• For the purpose of ranking, comparisons should be precise. For example, the rank function should consider x and y to be equal if x == y but not if abs(x – y) < e (for some small value of e) as long as > and < also check for equality using e. Using imprecise comparisons can lead to corrupt indexes and incorrect query results.

Hash FunctionsThe hash-function is a user-defined global function that, for each instance of class, returns a value, an os_unsigned_int32, that can be used as a key in a hash table. It takes a const void* argument. If you are not supplying a hash function for the class, this argument should be 0.

Example Use of Rank and Hash FunctionsSuppose that you have a collection of pointers to messages, instances of a class that you have defined. Further suppose that you want to iterate through the messages in order of their dates to display each message. If a message has an indexable data member whose value is its date, you can code such an iteration in the following way:

os_collection &messages = . . . ;message *a_msg;

os_index_path &date_path = os_index_path::create("message", "date_received", msg_db);

os_cursor c(messages, date_path); for (a_msg=(message*)c.first(); a_msg; a_msg = (message*)c.next()) a_msg->display();

This assumes that dates have an order that is known to ObjectStore. This is true if dates are instances of an integer or pointer type such as int. But suppose that dates are instances of a user-defined class:

class date{public: int month; int day; int year;};

In this case, you must define the rank function and make it known to ObjectStore. You might define it as follows:

int date_rank(const void* arg1, const void *arg2) { const date *date1 = (const date *) arg1; const date *date2 = (const date *) arg2;

if (date1->year < date2->year) return os_collection::LT; else if (date1->year > date2->year) return os_collection::GT;

Release 6.3 79

Page 80: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Specifying Expected Size

else if (date1->month < date2->month) return os_collection::LT; else if (date1->month > date2->month) return os_collection::GT; else if (date1->day < date2->day) return os_collection::LT; else if (date1->day > date2->day) return os_collection::GT; return os_collection::EQ;}

If you also use unordered indexes keyed by date, you must supply a hash function, which might be defined in the following way:

os_unsigned_int32 date_hash(const void* x) { const date* d = (const date*) x; return ((os_unsigned_int32) (d->year) << 16) ^ (d->month << 8) ^ d->day;}

Finally, you must call os_index_key() before your application performs any iteration or query employing an index path ending on a data member of type date.

main() { . . . os_index_key(date,date_rank,date_hash); . . . }

If unordered indexes are never created, the hash function is not needed and the registration could be done as follows:

os_index_key(date,date_rank,0);

Specifying Expected SizeFrequently, a collection has a loading phase in which it is loaded with elements before being the subject of other kinds of manipulation such as queries and traversal. In these cases, it is desirable to create the collection with the size it will have after loading is complete.

To presize a collection, use the expected_size argument to a collection’s constructor.

80 C++ Collections Guide and Reference

Page 81: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 6Querying Collections

The information about queries is organized in the following manner:

Overview 81

Performing Queries with query() 82

Single-Element Queries with query_pick() 88

Existential Queries with exists() 89

Query Functions and Nested Queries 90

Nested Existential Queries 91

Preanalyzed Queries 92

OverviewThe C++ language makes possible the sort of navigational data access required by typical design applications. However, while navigation provides the most efficient form of access in many circumstances, other situations require associative access. Look-up of an object by name or ID number, for example, is a simple form of associative access. Both associative and navigational retrieval are indispensable to databases supporting complex, data-intensive design applications.

Therefore, among the database services provided by ObjectStore is support for query processing. A query facility with adequate performance must go beyond support for linear searches. So ObjectStore provides a query optimizer, which formulates efficient retrieval strategies, minimizing the number of objects examined in response to a query. The query facilities are used from within C++ programs, and they treat persistent and nonpersistent data in an entirely uniform manner.

Release 6.3 81

Page 82: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Performing Queries with query()

Performing Queries with query()To retrieve a collection of those elements that satisfy a specified condition, use the function os_Collection::query().

For more information, see Chapter 8, Class Reference, on page 121.

This function is declared

os_Collection<E> &query( char *type_string, char *query_string, os_database *schema_database = 0, char *file_name = 0, os_unsigned_int32 line = 0, os_boolean dups = query_dont_preserve_duplicates) const;

where E is the element type parameter.

You must explicitly delete each collection that you allocate. Remember to delete collections that your application allocates as the result of a query. If you do not, your application has memory leaks.

Example QueryFollowing is an example:

os_database *people_database;os_Set<person*> *people;

. . .

os_Set<person*> &teenagers = people->query( "person*", "this->age >= 13 && this->age <= 19", people_database);

Query ArgumentsCalls to the function can take the form

collection-expression.query( element-type-name, query-string, schema-database )

collection-expression

The collection-expression in the preceding example is *people. It defines the collection over which the query will be run.

element-type-name

The argument element-type-name, person* in this example, is a string indicating the element type of the collection being queried.

query-string The query-string is a control expression that indicates the query’s selection criterion. The control expression can be either an int-valued C++ expression or a pattern-matching expression. For more information, see

82 C++ Collections Guide and Reference

Page 83: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 6: Querying Collections

• C++ Control Expressions in Query Strings on page 84

• Matching Patterns in Query Strings on page 84

• Calling Functions in Query Strings on page 86

• Nested Queries on page 87

schema-database

The schema-database is a database whose schema contains all the types mentioned in the selection criterion. This database provides the environment in which the query is analyzed and optimized. The database in which the collection resides is often appropriate.

If the transient database is specified, the application’s schema (stored in the application schema database) is used to evaluate the query. The application schema database almost always contains the required schema, but it might be closed at the time of the call to query(). So using it as the schema_database argument might involve the overhead of a database open.

file_name and line arguments

ObjectStore uses the file_name and line arguments when reporting errors related to the query. You can set these arguments to identify the location of the query’s source code.

dups argument If the dups argument is the enumerator query_dont_preserve_duplicates, duplicate elements that satisfy the query condition are not included in the query result. If dups is the enumerator query_preserve_duplicates, duplicate elements that satisfy the query condition are included in the query result. Using query_dont_preserve_duplicates (the default) typically results in better performance.

Return value The return value of query() refers to a collection that is allocated on the heap. So when you no longer need the resulting collection, you should reclaim its memory with ::operator delete() to avoid memory leaks. The resulting collection has the same behavior as the collection being queried. The order of the elements in the result cannot be guaranteed to be the order of the elements in the collection being queried.

For information about deleting objects, see ::operator delete() in Chapter 3 of C++ A P I Reference.

Release 6.3 83

Page 84: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Performing Queries with query()

C++ Control Expressions in Query Strings If the query string is a C++ control expression, any element, e, satisfies the selection criterion if the control expression evaluates to a nonzero os_int32 (true) when e is bound to this. Any string consisting of an os_int32-valued C++ expression is allowed in a query string that meets the following conditions:

• Variables are also data members of the elements of the collection.

• For local variables (free references), you create an os_coll_query object.

• For global functions (free references), you create an os_coll_query object.

• There are no function calls except calls to strcmp( ) or strcoll( ).

• There are no comparison operators for which the user might be required to define a corresponding rank/hash function.

• All calls to member functions are within the restrictions listed in Calling Functions in Query Strings on page 86.

The following is an example of a C++ control expression:

this->age >= 13 && this->age <= 19

Matching Patterns in Query Strings You can specify a string pattern to be matched in a query with the pattern-matching operator, ~~. This operator has two arguments, which can be null-terminated strings or NULL. The left-hand argument specifies the text to be checked for a match, and the right-hand argument specifies a pattern-matching expression to be matched. A query string that uses the ~~ operator satisfies the selection criterion if the right-hand operand matches the pattern in the left-hand operand.

The following characters have special meanings when used in a pattern-matching expression. All other characters match themselves.

You can escape the special meaning of any of these characters by preceding with the ampersand (&). For example, to represent the ampersand (&) as a literal character in a pattern-matching expression, you must precede it with another ampersand, &&. Note that any of the characters described as “Reserved” in the table are invalid unless they are preceded by an ampersand (&).

Operator Function

? Matches any single character

* Matches 0 or more of any character

& Escape character

[ Reserved

] Reserved

( Reserved

) Reserved

| Reserved

84 C++ Collections Guide and Reference

Page 85: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 6: Querying Collections

Case-sensitivity By default, pattern-matching expressions are case sensitive. You can specify that the entire expression is case insensitive with the &i escape sequence. The &i escape sequence can appear only at the start of a pattern-matching expression.

Optimizing pattern matching

The pattern-matching operator (~~) takes advantage of any ordered indexes available on the text being matched. If the pattern-matching expression begins with a character other than an asterisk (*) or a question mark (?), the query searches only the portion of the index that matches the initial constant prefix. For this reason, patterns that specify a constant prefix produce much more efficient queries.

Examples Following are examples of query strings that use the pattern-matching operator (~~). In all of the examples, name is a char* data member:

• Matches Tom at the beginning of the string in name:

"name ~~ \"Tom*\""

• Bound query that matches Tom at the beginning of the string in name:

const os_coll_query & cp = os_coll_query::create( "foo*", "name ~~ match_name", os_database::get_transient_database()); char name_buf[25]; strcpy(name_buf, "Tom*"); os_bound_query bound_name(cp, (os_keyword_arg( "match_name", name_buf))); os_collection & results = p_collection->query(bound_name);

• Matches man or burn at the end of the string:

"name ~~ \"*man\" || name ~~ \"*burn\""

• Does a case-insensitive match of the string ?foo:

"name ~~ \"&i&?foo\""

• Does a case-insensitive match of *foo anywhere in the string:

"name ~~ \"&i*&*foo*\""

• Matches *foo anywhere in the string, followed by &bar:

"name ~~ \"*foo*&&bar*\""

• Matches the string (a):

"name ~~ \"&(a&)\""

Release 6.3 85

Page 86: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Performing Queries with query()

Calling Functions in Query Strings Restrictions Functions called in query strings are subject to certain restrictions:

• The return type can be a basic type (int, char, float, char*).

• If the function is a member function, it can also return a pointer or a reference to a class type.

• The function can take up to two arguments. The first argument must be a pointer. For member functions, this is the implied first argument.

• Global functions are free references and must be used in an os_coll_query object.

• Member functions can be used like data members.

To perform a query, ObjectStore sometimes (depending on what indexes are present) issues calls to member functions used in paths and queries. If such a member function allocates memory that it does not free (for example if it returns a pointer to newly allocated memory), memory leaks can result; ObjectStore does not free the space the function allocates. So member functions used in paths or queries should not allocate persistent memory or memory in the transient heap.

Member function in a query string

Applications that use a member function (not returning a reference) in a query string must do four things:

• Define an os_backptr-valued data member in the class that defines the member function. The data member must precede the member function declaration in the class definition.

• Call the macro os_query_function( ). This should be defined at file scope, for example, in the header file that contains the class that defines the member function. See os_query_function() on page 269 for more information.

• Call the macro os_query_function_body( ). This should be defined at file scope in a source file that is only compiled into the application once. See os_query_function_body() on page 270 for more information.

• Call the macro OS_MARK_QUERY_FUNCTION( ). This macro should be invoked in the schema source file. See OS_TRANSIENT_DICTIONARY() on page 262 for more information.

86 C++ Collections Guide and Reference

Page 87: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 6: Querying Collections

Member function that returns a reference in a query string

For applications that use a member function that returns a reference in a query string, you must do the following four things:

• Define an os_backptr-valued data member in the class that defines the member function. The data member must precede the member function declaration in the class definition.

• Call the macro os_query_function_returning_ref( ). This should be defined at file scope, for example, in the header file that contains the class that defines the member function. See os_query_function_returning_ref() on page 271 for more information.

• Call the macro os_query_function_body_returning_ref( ). This should be defined at file scope in a source file that is only compiled into the application once. See os_query_function_body_returning_ref() on page 270 for more information.

• Call the macro OS_MARK_QUERY_FUNCTION( ). This macro should be invoked in the schema source file. See OS_TRANSIENT_DICTIONARY() on page 262 for more information.

To maintain indexes keyed by paths containing member function calls, use os_backptr::make_link( ) and os_backptr::break_link( ).

Nested Queries The query string can itself contain queries. A notation is defined to allow the user to conveniently specify such nested queries in a single call to a query member function.

A nested collection-valued query has the form

collection-expression [: os_int32-expression :]

where collection-expression is an expression of type os_collection, and os_int32-expression is the selection criterion for the nested query.

A nested single-element query has the form

collection-expression [% os_int32-expression %]

where collection-expression and os_int32-expression are the same as for nested collection-valued queries. This form evaluates to one element of collection-expression. If there is more than one element that satisfies the nested query’s selection criterion, one of them is picked and returned.

A nested query returning a collection is converted to an os_int32 when appropriate, using os_collection::operator os_int32( ).

Release 6.3 87

Page 88: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Single-Element Queries with query_pick()

Queries Compared to Collection TraversalsThe preceding query serves as a sort of shorthand for the following collection traversal:

os_Set<person*> *people; . . .

os_Cursor<person*> c(*people);os_Set<person*> *teenagers = *new(os_database::get_transient_database(), os_Set<person*>::get_os_typespec()) os_Set<person*>;

person *p = 0;for(p = c.first(); c.more() ; p = c.next()) if (p->age >= 13 && p->age <= 19) *teenagers |= p;

Optimizing queries

Queries, however, can be optimized so that, unlike this traversal, they need not involve examination of every element of the collection being queried. This happens when indexes are added to a collection. Query optimization is discussed later in this chapter (see Executing Bound Queries on page 94).

Within the selection criterion of query expressions, member names are implicitly qualified by this just as are member names in function member bodies. So the preceding query can be rendered as

os_database *people_database;os_Set<person*> *people;. . .

os_Set<person*> &teenagers = people->query( "person*", "age >= 13 && age <= 19", people_database);

Single-Element Queries with query_pick()The preceding sample query returns a reference to a collection. However, some queries are intended to locate just one element. In such cases, it might be more convenient to use os_Collection::query_pick(), a query function that returns a single element rather than a collection. Using this form has the additional advantage that more opportunities for optimization are available when it is known that only a single element is sought.

This function is declared as follows where E is the element type parameter.

E query_pick(char*, char*, os_database*) const;

Calls to query_pick() have the same form as calls to query(). If you are using the parameterized version, os_Collection::query_pick(), the return value is the os_Collection parameter type. If you are using the nonparameterized version, os_collection::query_pick(), the return value is void*, and you will often have to apply a cast to the result.

88 C++ Collections Guide and Reference

Page 89: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 6: Querying Collections

Example query_pick()Following is an example:

os_database * parts_database;os_Set<part*> *parts;. . .

part *part_number_411 = parts->query_pick( "part*", "part_number == 411", parts_database);

If more than one element satisfies the query’s selection criterion, one of them is picked and returned. Therefore, except for the additional opportunities for optimization, using query_pick() is equivalent to calling os_Collection::pick() on the result of invoking query().

If no element satisfies the query, 0 is returned.

Existential Queries with exists()Sometimes a collection is queried to determine whether there exists some element that satisfies the selection criterion, and the identity of the particular element or elements that do satisfy the criterion is not of interest. For such cases, you should use os_Collection::exists(). More opportunities for optimization are available when it is known that this is the ultimate intent of the query.

Existential queries are also discussed in Nested Existential Queries on page 91.

Calls to exists() have the same form as calls to query() and query_pick(), but instead of returning a collection or element, they return a nonzero os_int32 (int or long, whichever is 32 bits on your platform) for true and 0 for false.

Example exists()Following is an example:

os_database *print_request_db;class page {...int page_num;...};class print_request {...os_List<page*> *pages;...}; print_request *request;. . .

if (request->pages->exists( "page*", "page_num > 100", print_request_db )) request->queue_at_end(print_queue);

Release 6.3 89

Page 90: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Query Functions and Nested Queries

Query Functions and Nested QueriesIn all three forms of queries, the query string can itself contain queries. A nested collection query has the form

collection-expression [: int-expression :]

where collection-expression is some element of the top-level integer expression of type os_Collection, and int-expression is the selection criterion for the nested query.

A nested single-element query has the form

collection-expression [% int-expression %]

where collection-expression and int-expression are the same as for nested collection queries.

These nested queries all have the same characteristics as the query expressions discussed in Performing Queries with query() on page 82 except that the collection returned is converted to an int by the query processor. The returned collection is converted to 0 (that is, false) if it is empty and to a nonzero int (that is, true) if it is nonempty.

Nested Query Example Following is a query that finds the musicians among a company’s employees:

class employee {... os_Set<hobby*>& hobbies; ...};class hobby {... char *name; ...};os_Set<employee*> &employees = ...;. . .

os_Set<employee*> musicians = employees->query( "employee*", "hobbies[:!strcmp(name, "music"):]", db);

In this query, the selection criterion is the query string hobbies [: !strcmp(name, "music") :]. Because this is a nested query expression, the collection that it designates is converted to an int. The nested query is converted to 0 (false) when it returns an empty set (there is no hobby named music). Otherwise, it is converted to a nonzero value.

The query string in the preceding example is therefore equivalent to

[:hobbies[:!strcmp(name, "music"):].size !=0:]

90 C++ Collections Guide and Reference

Page 91: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 6: Querying Collections

Nested Existential QueriesThe collection returned by a nested query is converted to an int by the query processor. The returned collection is converted to 0 (that is, false) if it is empty and to a nonzero int (that is, true) if it is nonempty.

This is particularly useful for performing existential queries. Consider the following query:

os_database *db;os_Set<part*> &a_set ... ;a_set->query("part*", "children[:1:]", db);

This query selects all parts in a_set that have children. This is because for each element, e, of a_set, e–>children[:1:] returns e->children, which is converted to an integer, and if the integer is nonzero (true), e is selected. If e->children is empty, it is converted to 0 (false), so it is not selected.

To find the parts in a_set that have no children, you can use the following query:

os_database *db;os_Set<part*> &a_set ... ;a_set->query("part*", "!children[:1:]", db);

Following is a query that selects those descendents of a_part that have children all of which are primitive. So it selects all descendents that are strictly on the second level from the bottom of the assembly:

os_database *db;part *a_part;

a_part->get_descendents()->query( "person*", "children[:1:] && !children[:children:]", db);

Example of a Nested Existential QueryFollowing is a final example involving nesting of queries. This locates the employee whose child has social security number 123456789.

employees->query_pick( "employee*", "children[:ss==123456789:]", db );

The inner query returns 0 (false) for a given employee if none of her children has social security number 123456789. In this case, the employee is not selected. If, for a given employee, at least one of her children does have social security number 123456789, the inner query returns an int greater than 0 (true) and the employee is selected.

Release 6.3 91

Page 92: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Preanalyzed Queries

Preanalyzed QueriesIt is useful to think of query evaluation as consisting of three logical steps:

1 Analysis of the query expression

2 Binding of the free variable and function references in the query (that is, binding of all identifiers except member names), if any

3 Actual interpretation of the bound query

The first step, analysis of the query expression, is likely to be a relatively expensive operation. If the same query is performed several times, perhaps with different values for the free variables each time, and perhaps on different collections each time, you should use a preanalyzed query.

Creating Query Objects with the os_coll_query ClassTo use a preanalyzed query, you create a query object, an instance of the class os_coll_query. This query is analyzed upon creation. Subsequently, each time you want to perform the query, you provide bindings for the free variable and function references, and you specify the collection over which the query is to be performed. This way, the cost of analyzing the query is incurred only once for a query that is bound and interpreted several times.

A preanalyzed query is created with one of the static member functions os_coll_query::create(), os_coll_query::create_pick(), or os_coll_query::create_exists(). Calls to these functions have the form

os_coll_query::create( element-type-name, query-string, schema-database )

A const os_coll_query& is returned in each case.

os_coll_query::create() must be called from within an ObjectStore transaction. An os_coll_query object can be created persistently, but it is up to the application to keep track of how to get at it in subsequent transactions (navigable from a root).

92 C++ Collections Guide and Reference

Page 93: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 6: Querying Collections

Destroying Query Objects You are responsible for managing the lifetimes of query objects. Be sure to destroy instances of the class os_coll_query by calling os_coll_query::destroy(), passing the instance as an argument. For more information, see os_coll_query::destroy() on page 198.

Function Calls in Query StringsAs with the query strings introduced earlier, the query string here is an int-valued expression and calls to strcmp() and strcoll() are allowed, as are calls involving comparison operators for which the user has defined a corresponding rank function and calls to member functions satisfying the restrictions described in Paths and Member Functions on page 64.

For preanalyzed queries, the query string can also include calls to other nonoverloaded global functions as long as

• The return type of each function is specified explicitly with a cast.

• The function references are bound as described below.

• All function calls involve zero, one, or two arguments; for two-argument calls, the first argument is a pointer.

Creating Bound QueriesVariables (including data members) can appear in a query string as long as the type of each variable (except data members) is specified explicitly with a cast. Consider, for example:

const os_coll_query &age_range_query = os_coll_query::create( "person*", "age >= *(int*)min_age_ptr && age <=*(int*)max_age_ptr", db1);This creates a preanalyzed query for people in a given age range. Note the type casts used to specify the types of the free variables min_age_ptr and max_age_ptr.

Binding a query’s variables

After you have a preanalyzed query, you can create a bound query at any time by using the constructor for the class os_bound_query. Bound queries must be transiently allocated; they should not be created with persistent new.

The bound query constructor takes two arguments: a preanalyzed query and a keyword_arg list, an instance of os_keyword_arg_list. Following is an example:

int teenage_min_age = 13, teenage_max_age = 19;

os_bound_query teenage_range_query( age_range_query, ( os_keyword_arg("min_age_ptr", &teenage_min_age), os_keyword_arg("max_age_ptr", &teenage_max_age) ) );

This creates a bound query for finding teenagers using the analyzed query in the previous example.

Release 6.3 93

Page 94: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Preanalyzed Queries

Comma operator overloading

The comma operator is overloaded in such a way that you can designate a keyword_arg_list with an expression of the following form:

( keyword_arg-expr, keyword_arg-expr, . . . , keyword_arg-expr )

You create a keyword_arg with the constructor for the class os_keyword_arg, as in

os_keyword_arg("min_age_ptr", &teenage_min_age)

This binds the address teenage_min_age to the variable min_age_ptr in the query string, specifying the value to be used in analyzing the query.

Binding a query’s functions

Just as a query’s free variable references must be bound before the query is evaluated, so must all function names. For example, the query

const os_coll_query &the_query = os_coll_query::create( "person*", "age >= (int)a_func((int) x)", db1);

might be bound with

int current_x = 7;

os_bound_query the_bound_query( the_query, ( os_keyword_arg("x", current_x), os_keyword_arg("a_func", a_func) ));

Note that when a query is evaluated, functions will be invoked an undefined number of times, depending on the evaluation plan formulated by the query optimizer. Therefore, for functions with side effects, the actual results are undefined.

The functions strcmp() and strcoll() are specially recognized by the query optimizer, so you do not have to bind them.

Note You cannot use the pattern-matching operator (~~) operator with bound queries.

Executing Bound QueriesA version of os_Collection::query() takes a const os_bound_query& argument, as do versions of os_Collection::query_pick() and os_Collection::exists().

The bound query can then be used directly in query evaluation, as in

people.query(teenage_range_query);

Note that as with the other overloadings of query functions, the return value refers to a collection that is allocated on the heap. So when you no longer need the resulting collection, you should reclaim its memory with ::operator delete() to avoid memory leaks. For information about deleting objects, see ::operator delete() in Chapter 3 of C++ A P I Reference.

94 C++ Collections Guide and Reference

Page 95: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 7Using Indexes to Optimize Performance

The information about queries and indexes is organized in the following manner:

Indexes and Query Optimization 95

Index Options 101

Performing or Enabling Index Maintenance 103

Declaring an os_backptr Member 104

Enabling Automatic Index Maintenance 105

User-Controlled Index Maintenance with an os_backptr 109

User-Controlled Index Maintenance Without an os_backptr 112

Rank and Hash Function Requirements 112

Example: Member Function Calls in Query and Path Strings 112

Indexes and Query OptimizationThe following sections discuss different techniques for using indexes to optimize queries.

• Adding an Index to a Collection with add_index()

• Index Maintenance

• Pointer-Valued Members and char* Keys

• Floating-point Keys

• Indexes and Performance

• Dropping Indexes from a Collection with drop_index()

• Testing for the Presence of an Index with has_index()

• Indexes and Complex Paths

• Monitoring Index Use During Queries

• Debugging Index Problems

Release 6.3 95

Page 96: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Indexes and Query Optimization

Adding an Index to a Collection with add_index()You can direct ObjectStore to optimize queries over a particular collection by adding an index into the collection with the member function os_collection::add_index().

Suppose, for example, that you want to optimize look-up of parts in a_set by part number as in the following query:

a_set->query_pick("part*", "part_number==411", db1)

Example: add_index()

You request an index into the set a_set. You specify the key of the index as the value of the data member part_number. To do this, use the member function os_collection::add_index():

os_Set<part*> *a_set;. . .

os_index_path &key_spec = os_index_path::create("part*", "part_number",db1);a_set->add_index(key_spec);

The key here is specified with a reference to a path. See Creating Paths on page 62.

The last argument to add_index() specifies the database, segment, or object cluster in which the index is stored. The index remains until it is removed with drop_index(). By default, an index is placed in the same segment as the collection for which the index is being added.

After you invoke this function, any query over a_set involving look-up by part_number is optimized.

Indexes can also end in functions. In this case, the query must end in the function in order to employ the index.

Index MaintenanceYou might need to perform index maintenance for any data member or member function in the path used to specify the index key. See Performing or Enabling Index Maintenance on page 103.

Pointer-Valued Members and char* KeysIf you create an index with a path to a pointer-valued data member — other than a char*-valued member — you can optimize look-up based on address. char*-valued data members are treated specially. An index based on a char* member optimizes look-up by the string pointed to.

However, because the query is on the address and not the value, pointer-valued members are limited in their usefulness.

Floating-point KeysBecause the collections library has no defined ordering for IEEE floating-point NaN values, if you are using floating-point keys and expect to generate NaN values, there are a number of possible problems. The collections library will not order floating-

96 C++ Collections Guide and Reference

Page 97: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 7: Using Indexes to Optimize Performance

point keys with NaN value in any definitive way. All NaN values cannot be expected to be equal. Some may be greater than all the other keys, some may be less than all the other keys. Furthermore cross platform database compatibility is not ensured when using floating-point keys with NaN values; a NaN value generated on one platform cannot be counted on to be equal with a NaN value generated on another platform. This cross-platform problem could result in “lost keys,” meaning operations that traverse a dictionary or index might not reach all the keys.

The workaround for this problem is to wrap your floating-point key in a user-defined class and supply your own rank and hash function for that class using the os_index_key macro. In this way you can designate the way you want NaN values to be treated and you can address the issue of cross-database compatibility. Keep in mind that these rank and hash functions will be greatly used, so if performance is a priority for your application, you should keep any platform checks and computations to a minimum. See Supplying Rank and Hash Functions on page 78 and os_index_key() on page 266 for more information.

Indexes and PerformanceWithout the index, a linear search must be used to perform such queries, and each element of a_set will have to be examined. By adding an index into a_set, you are instructing the system to maintain an access method (consisting of hash tables and/or a B-tree) allowing efficient look-up by part_number.

Adding an index into a collection slows down updates to the collection somewhat. It also slows down updates to the data member specifying the index key because index maintenance is performed whenever such an update occurs. However, indexes make the associated look-ups significantly faster. Therefore, it is a good idea to request an index if the ratio of look-ups to updates is large.

Dropping Indexes from a Collection with drop_index()Indexes can be added and dropped during the run of an application. If an index makes sense for only part of an application’s run, the application can add an index and then remove it later. For example, if the first part of an application performs many look-ups but relatively few updates and the second part performs many updates and relatively few look-ups, the program can add an index at the beginning of the first part and then remove the index at the beginning of the second part.

Because of this, you might unexpectedly find that you want to drop an index temporarily and later add it again. It is a good idea to design your application to keep track of your indexes so that you can easily drop and re-add them at a later time, especially if you have many indexes.

Example: drop_index() You remove an index with the member function drop_index(). Following is an

example:

os_Set<part*> *a_set;. . . os_index_path &key_spec = os_index_path::create("part*","part_number", db1);

Release 6.3 97

Page 98: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Indexes and Query Optimization

. . . a_set->drop_index(key_spec);

Note that you specify the key with an os_index_path, when dropping an index, because the same collection can have several different indexes to optimize different kinds of look-ups.

The os_index_path argument does not need to be the same instance of os_index_path supplied when the index was added, but it must specify the same key. If the path strings used to create two os_index_paths differ only with regard to white space, the os_index_paths specify the same index key.

If an index with the specified key was never added to the collection, err_no_such_index is signaled.

You can add and drop indexes at run time as frequently as you like. The ObjectStore query optimizer adapts dynamically.

Testing for the Presence of an Index with has_index()You can also test for the presence of an index with a specified key by using the member function has_index().

This function returns a value indicating whether an index can support the index type specified with index_options.

You must supply a path string and one of the index options. An index that supports exact-match queries (hash table) can only be used for exact matches. An index that supports range queries (binary tree) can be used for both exact-match and range queries. In effect, os_collection::has_index answers the question “Can this index support this type of query?” and not the option that was used to create the index.

Possible values for index_option are ordered and unordered.

• For an index created with the ordered option, the following is true:

- has_index(path,os_index::ordered) returns true.

- has_index(path,os_index::unordered) returns true.

• For an index created with the unordered option, the following is true:

- has_index(path,os_index::ordered) returns false.

- has_index(path,os_index::unordered) returns true.

Example Following is an example:

os_Set<part*> *a_set;. . . os_index_path &key_spec = .... . . if (a_set->has_index(key_spec, options)) ...

options for has_index can have the value ordered or unordered.

The function os_collection::get_indexes() allows you to retrieve information on all the indexes into a specified collection.

98 C++ Collections Guide and Reference

Page 99: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 7: Using Indexes to Optimize Performance

Indexes and Complex PathsPath expressions can specify not just a single data member but a navigational path involving multiple member accesses. Such path expressions can be used to specify index keys. For example, suppose that you want to optimize look-up of a part based on the emp_id of any of the responsible_engineers for the part (suppose that the member responsible_engineers is collection valued). You can use the following path:

os_index_path::create( "part*","(*responsible_engineers)[ ]->emp_id", db1)

This path is like ones you have seen before except that here the data member name responsible_engineers is followed by the symbols [ ], indicating that the next component of the path (emp_id) is to be applied to each element of the collection of responsible engineers rather than to the collection itself. Note that you cannot end an expression with the symbols [ ].

Monitoring Index Use During QueriesTo achieve optimal query performance, you need to maintain the correct set of indexes. Consequently, it is important to know which indexes a query actually uses. There are two ways to monitor index use during query processing:

• Set the OS_COLLECTION_TRACE_INDEX_USAGE envrionment variable. When this variable is set, ObjectStore writes index use information to stdout after execution of each query. The default is that this variable is not set.

• Call the trace_index_usage() function. The signature for this function is

os_collection::trace_index_usage(os_boolean run_trace, const char * file_name = 0)

Call this function with run_trace set to true to produce index use information as each query statement is processed. Call this function with run_trace set to false to stop generating index use information.

Specify a value for file_name to direct the index use information to a particular file. The default is to direct use information to stdout. If you specify a file that does not exist, ObjectStore creates it. If you want to change the file to which you are directing index use information, you must stop and restart index use information generation. That is, you must call trace_index_usage() with run_trace set to false, and then call it again with run_trace set to true and a new value for file_name.

If OS_COLLECTION_TRACE_INDEX_USAGE is set and you call trace_index_usage() with a file_name path, information goes only to the file you specify and not to stdout.

Release 6.3 99

Page 100: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Indexes and Query Optimization

Examples Suppose you either turn on the OS_COLLECTION_TRACE_INDEX_USAGE variable or you call the trace_index_usage() function to turn on index tracing. Your program defines the following query:

os_collection::query("my_numbers*", "Number >= 1048 && Number2 == 3");

There is an ordered index on Number and an unordered index on Number2. After processing the query, ObjectStore generates the following trace information:

Index usage for query statement:Number >= 1048 && Number2 == 31) unordered index used for path: Number22) ordered index used for path: Number

If there are no indexes on either data member, or if the query optimizer determines that it is best not to use indexes, ObjectStore generates the following output:

Index usage for query statement:Number >= 1048 && Number2 == 3No indexes used while processing query statement

Now suppose your program defines the following query:

os_collection::query("my_numbers*", "Number > 10");

There is an unordered index on Number2. ObjectStore generates the following output:

Index usage for query statement:Number2 > 10No indexes used while processing query statement

In this example, the query optimizer determines that it cannot use an unordered index to process this query statement. This is because the lack of order requires the query processor to iterate over the whole collection to find elements that meet the search criteria.

Debugging Index ProblemsYou can set the OS_COLL_DEBUG_INDEX environment variable to debug problems that might occur when an application adds indexes to a collection or inserts elements into an index. The default is that this variable is not set.

When set, this variable instructs ObjectStore to check that

• New indexes added to a collection will expect the same type of element as do previously added indexes for that collection

• New indexes added to a collection match the type of existing elements in the collection

• The type of elements inserted into an index match the type of elements in existing indexes on the collection

If this variable is set, running the osverifydb utility checks the consistency of the type of all indexes on each collection with the type of each member of that collection. See osverifydb on page 258 for more information.

100 C++ Collections Guide and Reference

Page 101: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 7: Using Indexes to Optimize Performance

Example Here is a sample of the displayed output from index operations when this variable is set:

DBG: Adding index of type "A*" to collection at 0xe14b0010DBG: Checking element at 0xe14b08d4 of type "A" OKDBG: Checking element at 0xe14b08e8 of type "A2" OK ("A" is a base of "A2")DBG: Checking element at 0xe14b08d8 of type "A" OKDBG: Checking element at 0xe14b08dc of type "B" INCONSISTENCY

Index OptionsAs mentioned previously, the index from part numbers to parts is implemented as hash tables (unordered indexes). This is the default. But if your application performs range queries involving part_number, you can request an ordered index, implemented using a B-tree. With a B-tree, queries involving <, <=, >, or >= comparisons on part numbers can be computed more efficiently than with an index implemented only with hash tables.

Example: B-tree query

Following is an example:

part_extent->query( "part*", "part_number > 411", db1)

part_extent[:part_number > 411:]

Use of a B-tree also makes iteration in order of part_number more efficient (see Controlling Traversal Order on page 68).

os_index_path::ordered EnumeratorYou request an ordered index by specifying os_index_path::ordered as the second argument to add_index(), as in the following example:

os_Set<part*> *a_set;. . . os_index_path &a_path = os_index_path::create("part*","part_number", db1);a_set->add_index(a_path, os_index_path::ordered);

os_index_path::ordered is an ObjectStore-supplied enumerator.

Of course, if a B-tree is best for parts of your application and a hash table is best for other parts, you can add and drop indexes of these types dynamically, as appropriate. You cannot have an ordered and unordered index using the same os_index_path on a collection.

Index Option EnumeratorsYou can also specify a variety of other index options by using various other enumerators. The enumerators can be combined into a bit pattern with bit-wise disjunction (using | (bit-wise OR)).

Following is the complete list of index option enumerators:

Release 6.3 101

Page 102: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Index Options

• os_index_path::ordered indicates an ordered index, implemented as a B-tree, supporting optimization of range queries, that is, queries involving the comparison operators <, >, <=, and >=. Specifying both ordered and unordered (see os_index_path::unordered, following) for the same index results in an ordered index.

• os_index_path::unordered indicates an unordered index, implemented as a hash table. Such an index does not support optimization of range queries. Specifying both ordered and unordered for the same index results in an ordered index.

• os_index_path::allow_duplicates indicates an index that allows duplicate keys. You should use such an index for collections in which two or more elements can share a key value. Specifying both allow_duplicates and no_duplicates (see os_index_path::no_duplicates, following) for the same index results in a no_duplicates index.

• os_index_path::no_duplicates indicates an index that does not allow duplicate key values. You should use such an index for collections in which no two elements can share a key value. If duplicate key values might accidentally occur, use this enumerator together with os_index_path::signal_duplicates (see os_index_path::signal_duplicates, following). If signal_duplicates is not also specified for the index, duplicate keys are not detected, which can produce unpredictable results. Always specify os_index_path::signal_duplicates too when you specify os_index_path::no_duplicates.

• os_index_path::signal_duplicates indicates an index that detects duplicate key values. This enumerator can only be used together with os_index_path::no_duplicates. If an index that signals duplicates is added to a collection containing two or more elements that share a key value, the exception err_index_duplicate_key is signaled. In addition, for a collection with an index that signals duplicates, inserting an element with the same key value as some other element also provokes an err_index_duplicate_key exception.

• os_index_path::copy_key indicates an index with entries consisting of key-value/element pairs as opposed to pointer-to-key-value/element pairs (see os_index_path::point_to_key, following). For a copy_key index, an entry is formed by copying the object at the end of the os_index_path that specifies the key. Such an index generally takes up more space than one that points to its keys, but it provides notably faster access times because of reduced paging costs. Specifying both copy_key and point_to_key for the same index results in a point_to_key index.

• os_index_path::point_to_key indicates an index with entries consisting of pointer-to-key-value/element pairs as opposed to key-value/element pairs. For a point_to_key index, an entry includes a pointer to the object at the end of the os_index_path that specifies the key. With point_to_key behavior, the entire page containing the key is paged in. Because of increased paging costs, such an index generally provides slower access times than an index that copies its keys, but a point_to_key index takes up less space. If keys are sparse (for example, one key is contained in a large object), performance can be very slow.

102 C++ Collections Guide and Reference

Page 103: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 7: Using Indexes to Optimize Performance

Specifying both copy_key and point_to_key for the same index results in a point_to_key index.

Default index behavior

The following disjunction of enumerators specifies the default index behavior:

os_index_path::unordered |os_index_path::allow_duplicates |os_index_path::copy_key

By default, an index is allocated in the same segment as its associated collection. If you want, however, you can supply an os_database* or os_segment* indicating where to allocate a new index. Supply this information as the third argument for calls that include an options argument. Otherwise, supply the clustering information as the second argument.

Performing or Enabling Index MaintenanceWhenever you use a path, for each data member mentioned in the path string, except const and collection-valued members, you must perform or enable index maintenance. Note that failing to perform or enable index maintenance can result in corrupted indexes, incorrect query results, and program failures.

os_indexable data members

Data members declared as os_indexable do automatic index maintenance on update. Pointer-valued data members should not be declared as os_indexable because the index will be on the address, not the value.

Collections and indexes

For all collections, a collection can either participate in an index or own an index over itself. In either case, when items are inserted into and removed from collections, automatic index maintenance occurs. This is true whether or not the item is os_indexable and is also true for indexed member functions. However, you must still do index maintenance on update.

Non-os_indexable data members

For data members that are not declared os_indexable (for instance pointer-valued data members), you must do index maintenance when you modify the object that the pointer points to.

Paths as IndexesIf you use a path as an index key or to specify traversal order for a safe cursor, you have two or three options for each data member in the path.

Option 1 Declare an os_backptr member and enable automatic index maintenance. See Declaring an os_backptr Member on page 104. See also Enabling Automatic Index Maintenance on page 105.

This option simplifies the coding of updates compared to options 2 and 3.

Like option 2, this option carries extra space overhead compared to option 3, in the form of an os_backptr member for each object containing the member.

Release 6.3 103

Page 104: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Declaring an os_backptr Member

Option 2 Declare an os_backptr and perform user-controlled index maintenance, using make_link() and break_link(). See Declaring an os_backptr Member on page 104 and User-Controlled Index Maintenance with an os_backptr on page 109.

Like option 3, this option can make coding updates to the member slightly more complex compared to option 1, but it avoids the use of wrapper objects and the apparent value/actual value distinction. See The Actual Value/Apparent Value Distinction on page 108 for more information.

Like option 1, this option carries extra space overhead compared to option 3, in the form of an os_backptr member for each object containing the member.

Option 3 Do not declare an os_backptr and perform user-controlled index maintenance, using the collection operations insert() and remove(). This option only applies if the member is not mentioned in any multistep path used as an index key. See User-Controlled Index Maintenance Without an os_backptr on page 112.

Like option 2, this option can make coding updates to the member slightly more complex, compared to option 1, but it avoids the use of wrapper objects and the apparent value/actual value distinction. See The Actual Value/Apparent Value Distinction on page 108 for more information.

With this option, you need not declare an os_backptr, so you avoid the space overhead, incurred with options 1 and 2, of an os_backptr member for each object containing the member. However, the index maintenance accompanying each data member update can be more expensive.

Such index maintenance is more expensive if there is an index that 1) is not keyed by the data member and 2) indexes a collection on which you perform insert() and remove() for index maintenance associated with updating the member.

With option 3, each such index is updated, whereas with options 1 and 2, such indexes are not updated.

Declaring an os_backptr MemberTo make a data member indexable, you add to the class whose data member you want to be indexable a public or private data member of type os_backptr. The declaration of the data member of type os_backptr must precede the declaration of the data member (or member functions) you want to make indexable.

Following is an example:

class part {public: . . . os_backptr b ; int id ; department *dept ; . . . part(); ~part(); . . .

104 C++ Collections Guide and Reference

Page 105: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 7: Using Indexes to Optimize Performance

};

Note that it is sufficient to define a single data member of type os_backptr for all indexable members of a class.

Inheritance of the os_backptrObjectStore supports inheritance of the os_backptr data member provided that the member is inherited from a base class along the leftmost side of the type inheritance lattice and provided that the leftmost base class is not a virtual base class (directly or through inheritance). In all other cases, you must define a data member of type os_backptr directly in the class defining the members you want to be indexable.

Consider, for example, the following class definitions:

class base1 {... os_backptr b1 ; ...} ;class base2a : public base1 {...} ;class base2b {... os_backptr b2b ;...} ;class derived : public base2a, public base2b { char *name ;} ;

Class derived’s name member can use class base1’s os_backptr member b1. Any data member in class base2a can also use class base1’s os_backptr member b1. Indexable members in class base2b should continue to use base2b’s os_backptr member b2b.

Now consider

class base1 {...os_backptr b1 ;...} ;class base2a : virtual public base1 {...} ;class base2b {...os_backptr b2b ; ... } ;class derived : public base2a, public base2b { os_backptr d ; char *name ;} ;

It is not possible for class derived’s indexable data members to use base1’s os_backptr member because base2a inherits class base1 virtually. For the same reason, data members in class base2a cannot use class base1’s os_backptr member b1. Because base2b is not inherited along the leftmost side of the type inheritance lattice, an additional os_backptr member (d in this example) must be defined to allow name to be indexable.

Enabling Automatic Index MaintenanceUsing the functions os_backptr::break_link() and os_backptr::make_link() whenever you update the member allows ObjectStore to perform index maintenance under user control (see User-Controlled Index Maintenance with an os_backptr on page 109).

This is also true for pointer-valued data members. Because the pointer is the index value, ObjectStore does not detect updates and you must use os_backptr::break_

Release 6.3 105

Page 106: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Enabling Automatic Index Maintenance

link() and os_backptr::make_link() for index maintenance whenever you update the member.

However, for all other data members that are not char* or char[ ] valued, you can avoid using these functions by declaring the data member with the following macros. If you use these macros, updates to the data member trigger automatic index maintenance.

• os_indexable_member() on page 268

• os_indexable_body() on page 267

• os_index() on page 265

106 C++ Collections Guide and Reference

Page 107: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 7: Using Indexes to Optimize Performance

os_indexable_member() MacroFor a data member normally declared as

value-type member-name ;

declare it instead as

os_indexable_member(class-name,member-name,value-type) member-name ;

where class-name is the name of the class defining the indexable member, member-name is the name of the data member being made indexable, and value-type is the member’s type.

os_indexable_body() MacroThe last thing you must do to make a data member indexable is call the macro os_indexable_body() to instantiate the bodies of the functions that provide access to the indexable member. These functions ensure that any indexes keyed by that data member are properly updated when the member is updated. The macro call should appear (at top level) in a file associated with the class defining the indexable member:

os_indexable_body(part,id,int,os_index(part,b));os_indexable_body(part,idx2,int,os_index(part,b));

Here the macro calls have the form

os_indexable_body(class,member,value-type,backptr-spec)

where

• class is the name of the class defining the indexable member.

• member is the name of the data member being made indexable, and value-type is that member’s value type.

• backptr-spec is a call to the macro os_index() indicating the name of the class’s os_backptr member.

os_index() MacroCalls to os_index() have the form

os_index(class,member)

where class is the name of the class defining the indexable member, and member is the name of the os_backptr-valued data member appearing before indexable members of the class.

Avoid White Space in Macro ArgumentsSome macro arguments are used (among other things) to concatenate unique names. The details of cpp macro preprocessing differ from compiler to compiler, and in some cases it is necessary to enter these macro arguments without white space to ensure that the argument concatenation will work correctly. All the examples given

Release 6.3 107

Page 108: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Enabling Automatic Index Maintenance

in this section follow this important convention, and should therefore work with any cpp.

The Actual Value/Apparent Value DistinctionThe actual value of an indexable data member is a special container object that encapsulates the apparent value. For example, the apparent value of the data member id of the previous examples is an int, but the actual value is an instance of a class defined implicitly by the member macro.

This implicitly defined class defines operator =() and a conversion operator (operator int() in this example) for converting instances of the implicitly defined type to instances of the apparent value type. Under most circumstances, these operators make the container object transparent.

Examples For example, to set the id of a part to 411, you simply do

a_part->id = 411

And to get the value and pass it to a function expecting an int argument, you do

f(a_part->id)

Because f() expects an int argument (the apparent but not actual value type of id), the conversion operator is invoked, making the above call equivalent to

f(a_part->id.operator int())

For cases where the actual value cannot be transparent, you should use the functions getvalue() and setvalue() defined by the actual value type of the indexable member. For example:

printf("The id is %d \n", a_part->id); /* This won’t work correctly */

does not work because the compiler cannot tell that the second argument to printf() is supposed to be an int, so the conversion operator is not invoked. Instead you should use

printf("The id is %d \n", a_part->id.getvalue());

or

printf("The id is %d \n", (int)(a_part->id));

The getvalue() and setvalue() functions will always work correctly for getting and setting indexable data member values.

char* and char() Memberschar* and char[ ] indexable data members are typically intended to be associated with indexes keyed by string rather than address. For example, iteration based on a char* member proceeds in order of the string pointed to rather than in order of address. To ensure proper index maintenance for such members, you must use user-controlled index maintenance. See User-Controlled Index Maintenance with an os_backptr on page 109.

108 C++ Collections Guide and Reference

Page 109: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 7: Using Indexes to Optimize Performance

Restriction on UpdatesNote that if the values of an indexable data member are instances of a user-declared class (not pointers to such instances), the values of such an instance’s data members cannot be directly altered without circumventing the required index maintenance. To make such a change, the value of the indexable data member must be replaced wholesale with a modified copy of the old value. That is, the instance must be copied and altered and then the altered object must be copied back as the new value of the indexable member.

User-Controlled Index Maintenance with an os_backptr

Using the macros described in Enabling Automatic Index Maintenance on page 105 allows ObjectStore to perform fully automatic index maintenance for data members. However, for any data member, you can avoid using these macros (and the accompanying actual value/apparent value distinction) by using the functions os_backptr::break_link() and os_backptr::make_link() whenever you update the member. In this case, you need only define the os_backptr member; the indexable member itself can be declared in the normal way.

You also use overloadings of make_link() and break_link() to perform index maintenance for member functions called in query or path strings.

Making and Breaking Links on Indexable Data MembersCall break_link() just before making a change to an indexable data member (this removes an entry from each relevant index), and call make_link() just after making the change (this inserts a new entry into each relevant index, indexing the object by the new value of the relevant path). You can ensure that this happens by encapsulating these calls in a member function for setting the value of the data member.

For indexes keyed by paths that go through the elements of a collection, index maintenance is performed automatically when you change the membership of a collection.

Example: message class definition

For example, given the following class definition:

#include <stddef.h>#include <ostore/ostore.hh>#include <ostore/coll.hh>. . .

class message { public: . . . os_backptr b; int id; /* an indexable member */ char *subject_line; /* a second indexable member */ class date {

Release 6.3 109

Page 110: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

User-Controlled Index Maintenance with an os_backptr

public: int day; int month; int year; } date_received; /* a third indexable member */ . . . message(int id, char*subj, int dd, int mm, int yy); ~message(); int set_id(int); char *set_subject_line(char*); void set_date(int dd, int mm, int yy);};

Example: function definitions

You should define functions for setting each data member as follows:

int message::set_id(int i) { b.break_link( &id, &id, os_index(message,b) - os_index(message,id) ); id = i; b.make_link( &id, &id, os_index(message,b) - os_index(message,id) ); return i;} /* end set_id() definition */

char *message::set_subject_line(char *subj) { b.break_link( &subject_line, &subject_line, os_index(message,b) - os_index(message,subject_line) ); if (strlen(subj) < 500) strcpy(subject_line, subj); else error("string too long"); b.make_link( &subject_line, &subject_line, os_index(message,b) - os_index(message,subject_line) ); return subj;} /* end set_subject_line() definition*/

void message::set_date(int dd, int mm, int yy) { b.break_link( &date_received, &date_received, os_index(message,b) - os_index(message,date_received) ); date_received.day = dd; date_received.month = mm; date_received.year = yy; b.make_link( &date_received, &date_received, os_index(message,b) - os_index(message,date_received)

110 C++ Collections Guide and Reference

Page 111: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 7: Using Indexes to Optimize Performance

);} /* end set_date() definition */

Note that because the values of date_received are instances of a user-defined class, date, this example assumes that you have defined and registered a rank function (and possibly a hash function) for the class date. See the examples in Supplying Rank and Hash Functions on page 78.

If these set-value functions provide the only interface for modifying the values of indexable members, indexes will be properly maintained. Circumventing the interface, for example, by passing the address of an indexable member value to a function that alters its value through the pointer, can result in inconsistent indexes.

Making and Breaking Links to Indexed Member FunctionsTo maintain indexes keyed by paths containing member function calls, use the following new overloadings of os_backptr::make_link() and os_backptr::break_link():

void make_link( void* ptr_to_obj, void* ptr_to_obj, const char* class_name, const char* function_name) const ;

void break_link( void* ptr_to_obj, void* ptr_to_obj, const char* class_name, const char* function_name) const;

Automatic index maintenance is not available for such indexes.

ptr_to_obj is the object whose state changed, requiring an update to one or more indexes. When you call these functions, supply the same value for the first and second arguments.

class_name is the name of the class that defines the member function called in the path of the indexes to be updated.

function_name is the name of the member function itself.

When to use these functions

Call these functions whenever you perform an update that affects the return value of any member function appearing in a query or path string. You must make a pair of calls (one to break_link() and one to make_link()) for each such member function affected by each data member change.

Call break_link() just before making the change (this removes an entry from each relevant index), and call make_link() just after making the change (this inserts a new entry into each relevant index, indexing the object by the new value of the relevant path). You can ensure that this happens by encapsulating these calls in a member function for setting the value of the data member.

For indexes keyed by paths that go through the elements of a collection (for example, * ( (*get_children())[ ]->get_location() ) ) index maintenance is

Release 6.3 111

Page 112: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

User-Controlled Index Maintenance Without an os_backptr

performed automatically when you change the membership of a collection. See Example: Member Function Calls in Query and Path Strings on page 112.

User-Controlled Index Maintenance Without an os_backptr

Collections do automatic index maintenance. Therefore, you avoid os_backptr overhead in the following way: If a member is not mentioned in any multistep path used as an index key, you can perform index maintenance by using collection insert and remove operations. Performing index maintenance in this way allows you to avoid declaring an os_backptr member. See Performing or Enabling Index Maintenance on page 103.

When you update the data member, follow this procedure:

1 For each index keyed by the member, remove the object containing the member from the indexed collection (it might or might not actually be an element of this collection).

2 Update the member.

3 Insert the object back into each collection, if any, mentioned in step 1, provided the object was a member of that collection prior to your performing step 1.

Rank and Hash Function RequirementsIf your application uses paths ending in instances of a class, you must define and register a rank function and possibly a hash function for the path’s terminal type. For ordered indexes keyed by such paths, you must supply a rank function. For unordered indexes keyed by such paths, you must supply both a rank and a hash function (the rank function is used to resolve hashing collisions). See Supplying Rank and Hash Functions on page 78.

Example: Member Function Calls in Query and Path Strings

Following is a listing of three files that make up a simple program using member function calls in paths and queries:

Files used in this example

• rectangle.hh. This file defines two classes (coord and rectangle) and includes calls to the os_query_function() macro.

• schema.cc. This is the schema source file for the program. It contains the calls to OS_MARK_SCHEMA_TYPE() as well as to OS_MARK_QUERY_FUNCTION(). For information about the OS_MARK_QUERY_FUNCTION() macro, see OS_MARK_QUERY_

112 C++ Collections Guide and Reference

Page 113: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 7: Using Indexes to Optimize Performance

FUNCTION() on page 261. For information about the OS_MARK_SCHEMA_TYPE() macro, see OS_MARK_SCHEMA_TYPE() in Chapter 4 of C++ A P I Reference.

• rectangle.cc. This file contains the implementation of the member functions of rectangle as well as calls to the os_query_function_body() macro. There is also a driver program consisting of the main() routine and the function mquery(). A rank function for the class coord is also provided to support range queries involving coords.

The rectangle class

The class rectangle defines public accessor functions for the following pieces of abstract state:

• Label

• Length

• Width

• Children (a collection of related rectangles)

• Location (an instance of the class coord)

• Area

The values for label, length, width, children, and location are stored in private data members. The value for area is computed from the values for length and width.

Query functions Each function for reading a piece of abstract state (a get function) is declared as a query function. In addition, the public members coord::x and coord::y are declared as indexable data members. This allows the member function rectangle::get_location(), for example, to be called in a query and allows indexes to be keyed by, for example, the path

get_location()->x

that is, the x-coordinate of a rectangle’s location.

Rectangle Header File — rectangle.hh#include <ostore/ostore.hh>#include <ostore/coll.hh>#include <iostream>#include <stdlib.h>#include <string.h>

class coord {public: os_backptr b ; /* needed for indexable member */ os_indexable_member(coord,x,int) x ; os_indexable_member(coord,y,int) y ; coord(int x1, int y1) { x = x1 ; y = y1 ; } coord() { x = 0 ; y = 0 ; }} ;

class rectangle {public: os_backptr b ; /* needed for query functions */private: char *label ; int length ; int width ;

Release 6.3 113

Page 114: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Example: Member Function Calls in Query and Path Strings

os_Set<rectangle*> &children ; coord location ;

public: rectangle( const char *lbl, int l, int w, const os_Set<rectangle*> *chldrn_ptr, coord lcn ) ;

rectangle(const char *lbl) ; ~rectangle() ; char *get_label() ; void set_label(const char *lbl) ; int get_length() ; void set_length(int l) ; int get_width() ; void set_width(int w) ; os_Set<rectangle*> *get_children() ; coord *get_location() ; void set_location(coord lcn) ; int get_area() ; static os_typespec *get_os_typespec() ;} ;

os_query_function(rectangle,get_label,char*) ;os_query_function(rectangle,get_length,int) ;os_query_function(rectangle,get_width,int) ;os_query_function(rectangle,get_location,coord*) ;os_query_function(rectangle,get_area,int) ;os_query_function(rectangle,get_children,\ os_Set<rectangle*>*) ;

Notice that there is no function for setting the children of a given rectangle. This is because the same collection is used to record the children of a rectangle throughout the rectangle’s lifetime. Changes in a rectangle’s children are reflected by insertions and removals performed on this collection. This means that rectangle::get_children() need not call make_link() and break_link(); index maintenance is performed by the collection’s insert and remove operations.

Schema Source File — schema.ccFollowing is schema.cc, containing the calls to OS_MARK_QUERY_FUNCTION().

#include <ostore/ostore.hh>#include <ostore/coll.hh>#include <ostore/manschem.hh>#include "rectangle.hh"

OS_MARK_SCHEMA_TYPE(rectangle);OS_MARK_SCHEMA_TYPE(coord);OS_MARK_SCHEMA_TYPE(os_Set<rectangle*>);OS_MARK_QUERY_FUNCTION(rectangle,get_label);OS_MARK_QUERY_FUNCTION(rectangle,get_length);OS_MARK_QUERY_FUNCTION(rectangle,get_width);OS_MARK_QUERY_FUNCTION(rectangle,get_location);OS_MARK_QUERY_FUNCTION(rectangle,get_area);OS_MARK_QUERY_FUNCTION(rectangle,get_children);

114 C++ Collections Guide and Reference

Page 115: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 7: Using Indexes to Optimize Performance

Main Program File — rectangle.ccMacro calls and rank functions

Following is the first part of rectangle.cc:

#include <ostore/ostore.hh>#include <ostore/coll.hh>#include <iostream>#include "rectangle.hh"

os_indexable_body(coord,x,int,os_index(coord,b)) ;os_indexable_body(coord,y,int,os_index(coord,b)) ;

os_query_function_body(rectangle,get_label,char*,b) ;os_query_function_body(rectangle,get_length,int,b) ;os_query_function_body(rectangle,get_width,int,b) ;os_query_function_body(rectangle,get_location,coord*,b) ;os_query_function_body(rectangle,get_area,int,b) ;os_query_function_body(\rectangle,get_children,os_Set<rectangle*>*,b) ;

int coord_rank(const void *arg1, const void *arg2) { const coord *c1 = (const coord *)arg1 ; const coord *c2 = (const coord *)arg2 ;

if ( c1->x < c2->x ) return os_collection::LT ; else if ( c1->x > c2->x ) return os_collection::GT ; else if ( c1->y < c2->y ) return os_collection::LT ; else if (c1->y > c2->y) return os_collection::GT ; else return os_collection::EQ ;}

Notice the calls to os_query_function_body(). The rank function coord_rank() is defined here so as to be able to perform queries comparing coord objects and so as to create an index keyed by a path ending in coord objects, in this case the path

* ( (*get_children())[ ]->get_location() )

Rectangle member function implementa-tions

Following is the second part of rectangle.cc:

rectangle::rectangle( const char *lbl, int l, int w, const os_Set<rectangle*> *chldrn_ptr, coord lcn):children(*new(os_database::of(this), os_Set<rectangle*>::get_os_typespec()) os_Set<rectangle*> ){ label = new( os_database::of(this), os_typespec::get_char(), strlen(lbl)+1 ) char[strlen(lbl)+1] ;

strcpy(label, lbl) ; length = l ; width = w ;

Release 6.3 115

Page 116: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Example: Member Function Calls in Query and Path Strings

children = *chldrn_ptr ; location.x = lcn.x ; location.y = lcn.y ;}

rectangle::rectangle(const char *lbl) : children(*new(os_database::of(this), os_Set<rectangle*>::get_os_typespec()) os_Set<rectangle*>) { label = new( os_database::of(this), os_typespec::get_char(), strlen(lbl)+1 ) char[strlen(lbl)+1] ; strcpy(label, lbl) ; length = 0 ; width = 0 ; location.x = 0 ; location.y = 0 ;}

rectangle::~rectangle() { delete [ ] label ; }

char *rectangle::get_label() { return label ; }

void rectangle::set_label(const char *lbl) { b.break_link(this, this, "rectangle", "get_label") ; label = new( os_database::of(this), os_typespec::get_char(), strlen(lbl)+1 ) char[strlen(lbl)+1] ; strcpy(label, lbl) ; b.make_link(this, this, "rectangle", "get_label") ;}

int rectangle::get_length() { return length ; }

void rectangle::set_length(int l) { // two query member functions depend on this data member // so we call each of make_link() and break_link() twice b.break_link(this, this, "rectangle", "get_length") ; b.break_link(this, this, "rectangle", "get_area") ; length = l ; b.make_link(this, this, "rectangle", "get_length") ; b.make_link(this, this, "rectangle", "get_area") ; }

int rectangle::get_width() { return width ; }

void rectangle::set_width(int w) { // two query member functions depend on this data member // so we call each of make_link() and break_link() twice b.break_link(this, this, "rectangle", "get_width") ; b.break_link(this, this, "rectangle", "get_area") ; width = w ;

116 C++ Collections Guide and Reference

Page 117: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 7: Using Indexes to Optimize Performance

b.make_link(this, this, "rectangle", "get_width") ; b.make_link(this, this, "rectangle", "get_area") ;}

os_Set<rectangle*> *rectangle::get_children() { return &children ;}

coord *rectangle::get_location() { return &location ;}

void rectangle::set_location(coord lcn) { b.break_link(this, this, "rectangle", "get_location") ; location.x = lcn.x ; location.y = lcn.y ; b.make_link(this, this, "rectangle", "get_location") ;}

int rectangle::get_area() { return length * width ; }

void print_rects(os_Set<rectangle*> &the_rects) { os_Cursor<rectangle*> c(the_rects) ; for ( rectangle *r = c.first() ; r ; r = c.next() ) cout << r->get_label() << "\n" ; cout << "\n" ;}

Note that the set functions perform index maintenance, calling break_link() and make_link() for each query function whose return value depends on the underlying private data member. For example, set_width() calls break_link() once for the query function get_width() and once for the query function get_area() because both get_width() and get_area() use the private data member width to derive their return values.

As noted earlier, there are no make_link() and break_link() calls associated with changing a rectangle’s children because index maintenance is performed automatically by the insertion and removal operations of the collection get_children() returns.

The driver Following is the last part of rectangle.cc:

void mquery(os_database *db) { os_index_key(coord,coord_rank,0) ;

rectangle *r1 = new(db, rectangle::get_os_typespec()) rectangle("1") ; rectangle *r2 = new(db, rectangle::get_os_typespec()) rectangle("2") ; rectangle *r3 = new(db, rectangle::get_os_typespec()) rectangle("3") ;

os_Set<rectangle*> &the_rectangles = *new(db, os_Set<rectangle*>::get_os_typespec()) os_Set<rectangle*>; the_rectangles |= r1 ; the_rectangles |= r2 ; the_rectangles |= r3 ;

os_index_path &label_path =

Release 6.3 117

Page 118: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Example: Member Function Calls in Query and Path Strings

os_index_path::create("rectangle*", "get_label()", db) ;

os_index_path &length_path = os_index_path::create("rectangle*", "get_length()", db) ;

os_index_path &width_path = os_index_path::create("rectangle*", "get_width()", db) ;

os_index_path &x_location_path = os_index_path::create("rectangle*", "get_location()->x",db);

os_index_path &y_location_path = os_index_path::create("rectangle*", "get_location()->y", db) ;

os_index_path &area_path = os_index_path::create("rectangle*", "get_area()", db) ;

os_index_path &children_loc_path = os_index_path::create("rectangle*", "* ( (*get_children())[ ]->get_location() )", db) ;

the_rectangles.add_index( label_path, os_index_path::unordered) ;

the_rectangles.add_index(length_path, os_index_path::ordered); the_rectangles.add_index(width_path, os_index_path::ordered) ; the_rectangles.add_index(x_location_path, os_index_path::ordered) ;

the_rectangles.add_index(y_location_path, os_index_path::ordered) ;

the_rectangles.add_index(area_path, os_index_path::ordered) ; the_rectangles.add_index(children_loc_path, os_index_path::ordered) ;

r1->set_label("rect1") ; r1->set_length(20) ; r1->set_width(60) ; r1->set_location(coord(10, 20)) ; r1->get_children()->insert(r2) ;

r2->set_label("rect2") ; r2->set_length(40) ; r2->set_width(35) ; r2->set_location(coord(20, 40)) ; r2->get_children()->insert(r3) ;

r3->set_label("rect3") ; r3->set_length(200) ; r3->set_width(80) ; r3->set_location(coord(50, 60)) ;

cout << "Rectangles labeled \"rect1\":\n" ;

os_Set<rectangle*> &answer = the_rectangles.query( "rectangle*","strcmp(\"rect1\", get_label()) == 0",db) ;

print_rects(answer) ; cout << "Rectangles with length < 100:\n" ;

answer = the_rectangles.query("rectangle*", "get_length() < 100",db) ;

118 C++ Collections Guide and Reference

Page 119: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 7: Using Indexes to Optimize Performance

print_rects(answer) ; cout << "Rectangles with width > 50:\n" ;

answer = the_rectangles.query("rectangle*", "get_width() > 50",db) ;

print_rects(answer) ; cout << "Rectangles with location x coord <= 25:\n" ;

answer = the_rectangles.query("rectangle*", "get_location()->x <= 25",db) ;

print_rects(answer) ; cout << "Rectangles with area >= 3000:\n" ;

answer = the_rectangles.query("rectangle*", "get_area() >= 3000",db) ;

print_rects(answer) ; cout<<"Rectangles with children whose location < (30, 50):\n";

const os_coll_query &children_loc_query = os_coll_query::create("rectangle*", "(*get_children()) [:*get_location()<*(coord*)a_coord_ptr :]", db) ; coord a_coord(30, 50) ;

os_bound_query bound_children_loc_query( children_loc_query, os_keyword_arg("a_coord_ptr", &a_coord)) ;

answer = the_rectangles.query(bound_children_loc_query) ; print_rects(answer) ; os_Set<rectangle*> *answer_ptr = &answer ; delete answer_ptr ; delete children_loc_query; }

main() driver function

main(int, char **argv) { // argv[1] is the database

cout << "\nStarting mquery ...\n\n";

objectstore::initialize(); os_collection::initialize();

OS_ESTABLISH_FAULT_HANDLER { OS_BEGIN_TXN(tx1, 0, os_transaction::update) mquery(os_database::create(argv[1])) ; OS_END_TXN(tx1) } OS_END_FAULT_HANDLER

cout << "Done.\n\n" ;}

The function main() initializes ObjectStore and ObjectStore collections and calls mquery(), passing in a newly created database. The function mquery() registers the coord rank function and then creates three rectangles, adding them to a collection, the_rectangles.

Next mquery() creates several index paths involving member functions. Then it adds indexes to the_rectangles, specifying the paths as index keys. Then various set functions are used, triggering the index maintenance coded earlier in rectangle.cc. The collection of children for two of the rectangles is modified with

Release 6.3 119

Page 120: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Example: Member Function Calls in Query and Path Strings

rectangle::get_children() and os_Collection::insert(), which triggers index maintenance performed by insert().

Finally, various queries involving member functions are performed on the_rectangles.

Example: driver output

The output looks like this:

Starting mquery ...

Rectangles labeled "rect1":rect1

Rectangles with length < 100:rect1rect2

Rectangles with width > 50:rect1rect3

Rectangles with location x coord <= 25:rect1rect2

Rectangles with area >= 3000:rect3

Rectangles with children whose location < (30, 50):rect1

Done.

This driver demonstrates how to express queries with member functions. To verify that index maintenance is being performed properly, you can modify the driver to create more rectangles and insert them into the_rectangles. If the_rectangles has only three elements, the query optimizer chooses not to use indexes in query evaluation. Following is an example:

char s[500];rectangle *rx = irectangle *ry = 0 ;

for (int i = 0 ; i < 200 ; i++) { sprintf(s, "%d", i); rx = new(db, rectangle::get_os_typespec()) rectangle(s) ; the_rectangles |= rx ; rx->set_length(i) ; rx->set_width(i) ; rx->set_location(coord(i, i)) ; if (ry) rx->get_children()->insert(ry) ; ry = rx ;}

120 C++ Collections Guide and Reference

Page 121: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8Class Reference

This chapter describes the following classes and their functions and enumerators. See the Introduction on page 122 for information that applies to all classes.

os_Array 122

os_array 129

os_backptr 135

os_Bag 138

os_bag 144

os_bound_query 149

os_Collection 149

os_collection 166

os_coll_query 192

os_coll_range 199

os_Cursor 203

os_cursor 209

os_Dictionary 215

os_dynamic_extent 224

os_index_name 225

os_index_path 226

os_Ixonly and os_ixonly 229

os_keyword_arg 231

os_keyword_arg_list 233

os_List 234

os_list 241

os_nList and os_nlist 246

os_Set 247

os_set 254

Release 6.3 121

Page 122: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Introduction

IntroductionThe following information applies to all classes related to collections, queries, and indexes:

Type definitions The types os_int32 and os_boolean, used throughout this manual, are each defined as a signed 32-bit integer type. The type os_unsigned_int32 is defined as an unsigned 32-bit integer type.

Required header files

Programs that use collections or collection subtypes (arrays, bags, dictionaries, lists, and sets), after they include the header file <ostore/ostore.hh>, must include the header file <ostore/coll.hh>.

Required libraries for collections

Programs that use collections must link with the library files liboscol.so (UNIX platforms) or ostore.lib (Windows platforms).

Required libraries for queries

libosqry.so and libosmop.so (UNIX), or ostore.lib (Windows)

os_Arraytemplate <class E>class os_Array : public os_Collection<E>

An array, like a list (see os_List on page 234 ), is an ordered collection. Arrays always provide access to collection elements in constant time. That is, the time complexity

of operations such as retrieval of the nth element is order 1 in the array’s cardinality.

Arrays also have a set_cardinality( ) function that changes the array cardinality, filling the additional array slots (if the cardinality is increased) with a specified fill value. Arrays allow both duplicates and nulls. As with other ordered collections, array elements can be inserted, removed, replaced, or retrieved based on a specified numerical array index or based on the position of a specified cursor.

If an element is inserted into an os_Array, elements after it are pushed down in order. If an element is removed, elements after it in the array are pushed up. If you want the index to an element to remain constant, set the element at indexn to either 0 or another pointer.

The class os_Array is parameterized, with a parameter for constraining the type of values allowable as elements (for the nonparameterized version of this class, see os_array on page 129). The element type parameter, E, occurs in the signatures of some of the functions described here. The parameter is used by the compiler to detect type errors.

The element type of any collection type, such as an array, must be a pointer type (for example, employee*).

Create os_Arrays with the os_Array constructor.

122 C++ Collections Guide and Reference

Page 123: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

You must mark parameterized collections types in the schema source file.

Member functions and enumerators

The following tables list the member functions that can be performed on instances of os_Array. The second table lists the enumerators inherited by os_Array from os_collection. Many functions are inherited by os_Array from os_Collection or os_collection. The full explanation of each inherited function or enumerator appears in the entry for the class from which it is inherited. The full explanation of each function defined by os_Array appears in this entry, after the table and list. In each case, the Defined By column gives the class whose entry contains the full explanation.

In the following table, for parameterized os_Array<E>, E means class pointer.

Name Arguments Returns Defined By

add_index ( const os_index_path&, os_database* )

( const os_index_path&, os_int32 options, os_database* )

( const os_index_path&, os_segment* = 0 )

( const os_index_path&, os_int32 options, os_segment* = 0 )

( const os_index_path&, os_cluster* = 0 )

( const os_index_path&, os_int32 options, os_cluster* = 0 )

void

void

void

void

void

void

os_collection

cardinality ( ) const os_int32 os_collection

clear ( ) void os_collection

contains ( const E ) const os_int32 os_Collection

count ( const E ) const os_int32 os_Collection

drop_index ( const os_index_path& ) void os_collection

empty ( ) os_int32 os_collection

exists ( char *element_type_name, char *query_string, os_database *schema_database = 0, char *file os_unsigned_int32 line )

( const os_bound_query& ) const

os_int32

os_int32

os_collection

get_behavior ( ) const os_unsigned_int32

os_collection

has_index ( const os_index_path&, os_int32 index_option_enums ) const

os_int32 os_collection

insert ( const E ) void os_Collection

Release 6.3 123

Page 124: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Array

insert_after ( const E, const os_Cursor<E>& )

( const E, os_unsigned_int32 )

void

void

os_Collection

insert_before ( const E, const os_Cursor<E>& )

( const E, os_unsigned_int32 )

void

void

os_Collection

insert_first ( const E ) void os_Collection

insert_last ( const E ) void os_Collection

multi_trans_add_index

static void multi_trans_add_index( os_reference c, const os_index_path & p, os_int32 index_options, os_segment * index_seg, os_segment * scratch_seg, os_unsigned_int32 num_per_trans )

os_collection

multi_trans_drop_index

static void multi_trans_drop_index( os_reference c, const os_index_path & p, os_segment * scratch_seg, os_unsigned_int32 num_per_trans )

os_collection

only ( ) const E os_Collection

operator os_array&

( ) os_collection

operator const os_array&

( ) const os_collection

operator os_Bag<E>&

( ) os_Collection

operator const os_Bag<E>&

( ) const os_Collection

operator os_bag&

( ) os_collection

operator const os_bag&

( ) const os_collection

operator os_List<E>&

( ) os_Collection

operator const os_List<E>&

( ) const os_Collection

operator os_list&

( ) os_collection

Name Arguments Returns Defined By

124 C++ Collections Guide and Reference

Page 125: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

operator const os_list&

( ) const os_collection

operator os_Set<E>&

( ) os_Collection

operator const os_Set<E>&

( ) const os_Collection

operator os_set&

( ) os_collection

operator const os_set&

( ) const os_collection

operator == ( const os_Collection<E>& ) const

( E ) const

os_int32

os_int32

os_Collection

operator != ( const os_Collection<E>& ) const

( E ) const

os_int32

os_int32

os_Collection

operator < ( const os_Collection<E>& ) const

( E ) const

os_int32

os_int32

os_Collection

operator <= ( const os_Collection<E>& ) const

( E ) const

os_int32

os_int32

os_Collection

operator > ( const os_Collection<E>& ) const

( E ) const

os_int32

os_int32

os_Collection

operator >= ( const os_Collection<E>& ) const

( E ) const

os_int32

os_int32

os_Collection

operator = ( const os_Array<E>& ) const

( const os_Collection<E>& ) const

( E ) const

os_Array<E>&

os_array&

os_array

os_Array

operator |= ( const os_Collection<E>& ) const

( E ) const

os_Array<E>&

os_Array<E>&

os_Array

operator | ( const os_Collection<E>& ) const

( E ) const

os_Collection<E>&

os_Collection<E>&

os_Collection

operator &= ( const os_Collection<E>& ) const

( E ) const

os_Array<E>&

os_Array<E>&

os_Array

operator & ( const os_Collection<E>& ) const

( E ) const

os_Collection<E>&

os_Collection<E>&

os_Collection

operator –= ( const os_Collection<E>& ) const

( E ) const

os_Array<E>&

os_Array<E>&

os_Array

Name Arguments Returns Defined By

Release 6.3 125

Page 126: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Array

operator - ( const os_Collection<E>& ) const

( E ) const

os_Collection<E>&

os_Collection<E>&

os_Collection

os_Array<E> ( )

( os_unsigned_int32 expected_size )( const os_Array<E>& )

( const const os_Collection<E>& )

( os_unsigned_int32 expected_size = 0, os_unsigned_int32 card = 0, E * fill_value = 0 )

os_Array

pick ( ) const

( const os_index_path&, const os_coll_range& ) const

E

E

os_Collection

query ( char *element_type_name, char *query_string, os_database *schema_database = 0, char *filename, os_unsigned_int32 line, os_boolean dups ) const

( const os_bound_query&, os_boolean dups ) const

os_Collection<E>&

os_Collection<E>&

os_Collection

query_pick ( char *element_type_name, char *query_string, os_database *schema_database = 0, char *filename, os_unsigned_int32 line ) const

( const os_bound_query& ) const

E

E

os_Collection

remove ( const E ) os_int32 os_Collection

remove_at ( const os_Cursor<E>& )

( os_unsigned_int32 )

void

void

os_Collection

remove_first ( const E& )

( )

os_int32

E

os_Collection

remove_last ( const E& )

( )

os_int32

E

os_Collection

replace_at ( const E, const os_Cursor<E>& )

( const E, os_unsigned_int32 )

E

E

os_Collection

retrieve ( os_unsigned_int32 ) const

( const os_Cursor<E>& ) const

E

E

os_Collection

Name Arguments Returns Defined By

126 C++ Collections Guide and Reference

Page 127: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

os_Array enumerators

The following table lists the enumerators that can be used for os_Array member functions.

Assignment Operator SemanticsAssignment operator semantics are described for the following functions in terms of insert operations into the target collection. Although the actual implementation of the assignment might be different, the associated semantics are maintained.

os_Array::operator =()os_Array<E> &operator =(const os_Array<E> &s);

os_Array<E> &operator =(const os_Collection<E> &s);

Copies the contents of the collection s into the target array and returns the target array. The copy is performed by effectively clearing the target, iterating over the source collection, and inserting each element into the target array. The iteration is ordered if the source collection is ordered. The target array semantics are enforced as usual during the insertion process.

os_Array<E> &operator =(const E e);

Clears the target array, inserts the element e into the target array, and returns the target array.

os_Array::operator |=()os_Array<E> &operator |=(const os_Collection<E> &s);

Inserts the elements contained in s into the target array and returns the target array. In effect, this appends the elements of a collection to an os_Array.

os_Array<E> &operator |=(const E e);

retrieve_first ( ) const

( const E& ) const

E

os_int32

os_Collection

retrieve_last ( ) const

( const E& ) const

E

os_int32

os_Collection

set_cardinality

( os_unsigned_int32 new_card, E fill_value )

void os_Array

Name Arguments Returns Defined By

Name Inherited From

allow_duplicates os_collection

allow_nulls os_collection

EQ os_collection

GT os_collection

LT os_collection

maintain_order os_collection

Release 6.3 127

Page 128: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Array

Inserts the element e into the target array and returns the target array.

os_Array::operator &=()os_Array<E> &operator &=(const os_Collection<E> &s);

For each element in the target collection, reduces the count of the element in the target to the minimum of the counts in the source and target collections. If the collection is ordered and contains duplicates, it does so by retaining the appropriate number of leading elements. The function returns the target collection.

os_Array<E> &operator &=(const E e);

If e is present in the target, converts the target into a collection containing just the element e. Otherwise, it clears the target collection. The function returns the target collection.

os_Array::operator –=()os_Array<E> &operator –=(const os_Collection<E> &s);

For each element in the collection s, removes s.count(e) occurrences of the element from the target collection. If the collection is ordered, it is the first s.count(e) elements that are removed. The function returns the target collection.

os_Array<E> &operator –=(const E e);

Removes the element e from the target collection. If the collection is ordered, it is the first occurrence of the element that is removed from the target collection. The function returns the target collection.

os_Array::os_Array()os_Array( );

Returns an empty array.

os_Array(os_unsigned_int32);

Returns an empty array whose initial implementation is based on the expectation that the specified os_unsigned_int32 indicates the approximate usual cardinality of the array after it has been loaded with elements.

os_Array(const os_Array<E>&);

Returns an array that results from assigning the specified array to an empty array.

os_Array(const os_Collection<E>&);

Returns an array that results from assigning the specified collection to an empty array.

os_Array(os_unsigned_int32 expected_size = 0, os_unsigned_int32 card = 0, void* fill_value = 0 );

The arguments have the following meaning:

• expected_size presizes the array. If this argument is not specified, the array is presized to 5 slots.

128 C++ Collections Guide and Reference

Page 129: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

• card specifies the cardinality of the initial array.

• The array’s slots are set to the value specified by fill_value. If this argument is unspecified, the array is null filled.

os_Array::set_cardinality()void set_cardinality(os_unsigned_int32 new_card, E fill_value);

Augments the array to have the specified cardinality, using the specified fill_value to occupy the array’s new slots.

os_arrayclass os_array : public os_collection

An array, like a list (see the class os_list on page 241), is an ordered collection. Unlike lists, arrays allow nulls and have a set_cardinality( ) function that changes the array cardinality, filling the additional array slots (if the cardinality is increased) with a specified fill value.

Arrays allow both duplicates and nulls. Array elements can be inserted, removed, replaced, or retrieved based on a specified numerical array index or based on the position of a specified cursor.

If an element is inserted into an os_array, elements after it are pushed down in order. If an element is removed, elements after it in the array are pushed up. If you want the index to an element to remain constant, set the element at indexn to either 0 or another pointer.

The class os_array is nonparameterized. For the parameterized version of this class, see os_Array on page 122.

Array elements are pointers, so the element type of any array must be a pointer type (for example, employee*).

Create arrays with the os_array constructor.

Tables of member functions and enumerators

The first of the following tables lists the member functions that can be performed on instances of os_array. The second table lists the enumerators inherited by os_array from os_collection. Many functions are also inherited by os_array from os_collection. The full explanation of each inherited function or enumerator appears in the entry for the class from which it is inherited. The full explanation of each

Release 6.3 129

Page 130: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_array

function defined by os_array appears in this entry, after the tables. In each case, the Defined By column gives the class whose entry contains the full explanation.

Name Arguments Returns Defined By

add_index ( const os_index_path&, os_int32 options, os_database* )

( const os_index_path&, os_int32 options, os_segment* = 0 )

( const os_index_path&, os_int32 options, os_cluster* = 0 )

( const os_index_path&, os_database* )

( const os_index_path&, os_segment* = 0 )

( const os_index_path&, os_cluster* = 0 )

void

void

void

void

void

void

os_collection

cardinality ( ) const os_int32 os_collection

clear ( ) void os_collection

contains ( const void* ) const os_int32 os_collection

count ( const void* ) const os_int32 os_collection

drop_index ( const os_index_path& ) void os_collection

empty ( ) const os_int32 os_collection

exists ( char *element_type_name, char *query_string, os_database *schema_database = 0, char *file os_unsigned_int32 line )

( const os_bound_query& ) const

os_int32

os_int32

os_collection

get_behavior ( ) const os_unsigned_int32

os_collection

has_index ( const os_index_path&, os_int32 index_option_enums ) const

os_int32 os_collection

insert ( const void* ) void os_collection

insert_after ( const void*, const os_cursor& )

( const void*, os_unsigned_int32 )

void

void

os_collection

insert_before ( const void*, const os_cursor& )

( const void*, os_unsigned_int32 )

void

void

os_collection

130 C++ Collections Guide and Reference

Page 131: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

insert_first ( const void* ) void os_collection

insert_last ( const void* ) void os_collection

multi_trans_add_index

static void multi_trans_add_index( os_reference c, const os_index_path & p, os_int32 index_options, os_segment * index_seg, os_segment * scratch_seg, os_unsigned_int32 num_per_trans )

os_collection

multi_trans_drop_index

static void multi_trans_drop_index( os_reference c, const os_index_path & p, os_segment * scratch_seg, os_unsigned_int32 num_per_trans )

os_collection

only ( ) const void* os_collection

operator os_bag&

( ) os_collection

operator const os_bag&

( ) const os_collection

operator os_list&

( ) os_collection

operator const os_list&

( ) const os_collection

operator os_set&

( ) os_collection

operator constos_set&

( ) const os_collection

operator == ( const os_collection& ) const

( const void* ) const

os_int32

os_int32

os_collection

operator != ( const os_collection& ) const

( const void* ) const

os_int32

os_int32

os_collection

operator < ( const os_collection& ) const

( const void* ) const

os_int32

os_int32

os_collection

operator <= ( const os_collection& ) const

( const void* ) const

os_int32

os_int32

os_collection

operator > ( const os_collection& ) const

( const void* ) const

os_int32

os_int32

os_collection

operator >= ( const os_collection& ) const

( const void* ) const

os_int32

os_int32

os_collection

Name Arguments Returns Defined By

Release 6.3 131

Page 132: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_array

operator = ( const os_array& ) const

( const os_collection& ) const

( const void* ) const

os_array&

os_array&

os_array

os_array

operator |= ( const os_collection& ) const

( const void* ) const

os_array&

os_array&

os_array

operator | ( const os_collection& ) const

( const void* ) const

os_collection&

os_collection&

os_collection

operator &= ( const os_collection& ) const

( const void* ) const

os_array&

os_array&

os_array

operator & ( const os_collection& ) const

( const void* ) const

os_collection&

os_collection&

os_collection

operator –= ( const os_collection& ) const

( const void* ) const

os_array&

os_array&

os_array

operator - ( const os_collection& ) const

( const void* ) const

os_collection&

os_collection&

os_collection

os_array ( )

( os_unsigned_int32 expected_size )

( const os_array& )

( const os_collection& )

( os_unsigned_int32 expected_size = 0, os_unsigned_int32 card = 0, void *fill_value = 0)

os_array

pick ( ) const

( const os_index_path&, const os_coll_range& ) const

void*

void*

os_collection

query ( char *element_type_name, char *query_string, os_database *schema_database = 0, char *filename, os_unsigned_int32 line, os_boolean dups ) const

( const os_bound_query&, os_boolean dups ) const

os_collection&

os_collection&

os_collection

query_pick ( char *element_type_name, char *query_string, os_database *schema_database = 0, char *filename, os_unsigned_int32 line ) const

( const os_bound_query& ) const

void*

void*

os_collection

Name Arguments Returns Defined By

132 C++ Collections Guide and Reference

Page 133: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

os_array enumerators

The following table lists the enumerators that can be used by os_array member functions.

Assignment Operator SemanticsAssignment operator semantics are described for the following functions in terms of insert operations into the target collection. The actual implementation of the assignment might be different, but the associated semantics are maintained.

os_array::operator =()os_array &operator =(const os_array &s);

os_array &operator =(const os_collection &s);

Copies the contents of the collection s into the target collection and returns the target collection. The copy is performed by effectively clearing the target, iterating over the

remove ( const void* ) os_int32 os_collection

remove_at ( const os_cursor& )

( os_unsigned_int32 )

void

void

os_collection

remove_first ( const void*& )

( )

os_int32

void*

os_collection

remove_last ( const void*& )

( )

os_int32

void*

os_collection

replace_at ( const void*, const os_cursor& )

( const void*, os_unsigned_int32 )

void*

void*

os_collection

retrieve ( os_unsigned_int32 ) const

( const os_cursor& ) const

void*

void*

os_collection

retrieve_first ( ) const

( const void*& ) const

void*

os_int32

os_collection

retrieve_last ( ) const

( const void*& ) const

void*

os_int32

os_collection

set_cardinality ( os_unsigned_int32 new_card, void *fill_value )

void os_array

Name Arguments Returns Defined By

Name Inherited From

allow_nulls os_collection

EQ os_collection

GT os_collection

LT os_collection

maintain_order os_collection

Release 6.3 133

Page 134: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_array

source collection, and inserting each element into the target collection. The iteration is ordered if the source collection is ordered. The target array semantics are enforced as usual during the insertion process.

os_array &operator =(const void *e);

Clears the target array, inserts the element e into the target array, and returns the target array.

os_array::operator |=()os_array &operator |=(const os_collection &s);

Inserts the elements contained in s into the target collection and returns the target collection.

os_array &operator |=(const void *e);

Inserts the element e into the target collection and returns the target collection. In effect, this appends the elements of a collection to an os_array.

os_array::operator &=()os_array &operator &=(const os_collection &s);

For each element in the target collection, reduces the count of the element in the target to the minimum of the counts in the source and target collections. If the collection is ordered and contains duplicates, it does so by retaining the appropriate number of leading elements. The function returns the target collection.

os_array &operator &=(const void *e);

If e is present in the target, converts the target into a collection containing just the element e. Otherwise, it clears the target collection. The function returns the target collection.

os_array::operator –=()os_array &operator –=(const os_collection &s);

For each element in the collection s, removes s.count(e) occurrences of the element from the target collection. If the collection is ordered, it is the first s.count(e) elements that are removed. The function returns the target collection.

os_array &operator –=(const void *e);

Removes the element e from the target collection. If the collection is ordered, it is the first occurrence of the element that is removed from the target collection. The function returns the target collection.

os_array::os_array()os_array( );

Returns an empty array.

os_array(os_unsigned_int32);

134 C++ Collections Guide and Reference

Page 135: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

Returns an empty array whose initial implementation is based on the expectation that the specified os_unsigned_int32 indicates the approximate usual cardinality of the array after it has been loaded with elements.

os_array(const os_array&);

Returns an array that results from assigning the specified array to an empty array.

os_array(const os_collection&);

Returns an array that results from assigning the specified collection to an empty array.

os_array(os_unsigned_int32 expected_size = 0, os_unsigned_int32 card = 0, void* fill_value = 0 );

The arguments have the following meaning:

• expected_size presizes the array. If this argument is not specified, the array is presized to 5 slots.

• card specifies the cardinality of the initial array.

• The array’s slots are set to the value specified by fill_value. If this argument is unspecified, the array is null filled.

os_array::set_cardinality()void set_cardinality(os_unsigned_int32 new_card, void *fill_value);

Augments the array to have the specified cardinality, using the specified fill_value to occupy the array’s new slots.

os_backptrIf there is a possibility that a data member of an object could be modified and this data member is used in an index, then index maintenance must occur before and after the update. This is possible only if the object has an os_backptr data member and appropriate index maintenance occurs. The os_backptr is an object that allows the object to point back to all indexes it participates in.

The os_backptr declaration must appear before the declaration of the data members intended to be indexable. Note that you must define at most one data member of type os_backptr. With one such member, all members (data and function) of the class declared after it are established as indexable.

When an element is inserted or removed from a collection that has an index on it, implicit index maintenance occurs whether the element has an os_backptr or not. Another possibility for update of data members that participate in an index is that you remove the element from the collection, update the data member, then insert it back into the collection. This then performs the appropriate index maintenance. Using this scenario avoids the requirement of having an os_backptr in your object. Because an os_backptr data member takes up 12 bytes and points back to the

Release 6.3 135

Page 136: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_backptr

indexes, using an os_backptr data member might not be desirable in some cases, such as when you are using reference-based indexes.

ObjectStore supports inheritance of the os_backptr data member provided that the member is inherited from a base class along the leftmost side of the type inheritance lattice and provided that the leftmost base class is not a virtual base class (directly or through inheritance). In all other cases, the user must define a data member of type os_backptr directly in the class defining the members intended to be indexable.

The os_backptr member is used internally for index maintenance associated with indexable members defined using the os_indexable_member( ) macro or with data members for which you are doing manual index maintenance (break_link() or make_link()). For example, manual index maintenance is required if the data member is a pointer and what gets updated is what is pointed to rather than the pointer value. The member functions described below can also be used explicitly by the user for index maintenance associated with indexable members defined without the os_indexable_member( ) macro.

The break_link( ) function should be invoked to break the index association before a modification to an indexable data member. This removes an entry from the index. In addition, after an indexable member has been given a new value, make_link( ) should be invoked to bring the index up to date. This inserts a new entry into the index, indexing the object by its new member value. You can ensure that this happens by encapsulating these calls in a member function for setting the value of the indexable member. The function should call break_link( ), assign the new value to the member, then call make_link( ). There are also special considerations for index maintenance when member functions are concerned.

For examples, see User-Controlled Index Maintenance with an os_backptr in the ObjectStore Advanced C++ A P I User Guide.

os_backptr::break_link()void break_link(void *, void*, os_int32 = 0) const;

Removes an entry from the index associated with the indexable data member pointed to by the void* arguments. For a class C with os_backptr member C::b and indexable member m, the void* arguments should both be

&m

The os_int32 argument should be

os_index(C,b) – os_index(C,m)

The this pointer points to the os_backptr for the object indexed by the removed entry. The removed entry indexes the object by the value of the specified member m.

void break_link( void* ptr_to_obj, void* ptr_to_obj, const char* class_name, const char* function_name) const;

136 C++ Collections Guide and Reference

Page 137: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

Use this function to maintain indexes keyed by paths containing member function calls.

ptr_to_obj is the object whose state changed, requiring an update to one or more indexes. When you call these functions, supply the same value for the first and second arguments.

class_name is the name of the class that defines the member function called in the path of the indexes to be updated.

function_name is the name of the member function itself.

Call this function before you perform an update that affects the return value of any member function appearing in an index. You must make a pair of calls (one to break_link( ) and one to make_link( )) for each such member function affected by each data member change. If there are multiple functions affected by change, you must call it for each function that participates in an index.

Call break_link( ) just before making the change (this removes an entry from each relevant index), and call make_link( ) just after making the change (this inserts a new entry into each relevant index, indexing the object by the new value of the relevant path). You can ensure that this happens by encapsulating these calls in a member function for setting the value of the data member.

For indexes keyed by paths that go through the elements of a collection (for example, * ( (*get_children( ))[ ]->get_location( ) ) ), index maintenance is performed automatically when you change the membership of a collection.

os_backptr::make_link()void make_link(void *, void*, os_int32 = 0) const;

Inserts an entry into the index associated with the indexable data member pointed to by the void* arguments. For a class, C, with os_backptr member C::b and indexable member m, the void* arguments should both be

&m

and the os_int32 argument should be

os_index(C,b) – os_index(C,m)

The this pointer points to the os_backptr for the object being indexed. The inserted entry indexes this object by the value of the specified member, m.

void make_link( void* ptr_to_obj, void* ptr_to_obj, const char* class_name, const char* function_name) const;

Use this function to maintain indexes keyed by paths containing member function calls.

Release 6.3 137

Page 138: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Bag

ptr_to_obj is the object whose state changed, requiring an update to one or more indexes. When you call these functions, supply the same value for the first and second arguments.

class_name is the name of the class that defines the member function called in the path of the indexes to be updated.

function_name is the name of the member function itself.

Call this function before you perform an update that affects the return value of any member function appearing in an index. You must make a pair of calls (one to break_link( ) and one to make_link( )) for each such member function affected by each data member change. If there are multiple functions affected by change, then you must call it for each function that participates in an index.

Call break_link( ) just before making the change (this removes an entry from each relevant index), and call make_link( ) just after making the change (this inserts a new entry into each relevant index, indexing the object by the new value of the relevant path). You can ensure that this happens by encapsulating these calls in a member function for setting the value of the data member.

For indexes keyed by paths that go through the elements of a collection (for example, * ( (*get_children( ))[ ]->get_location( ) ) ), index maintenance is performed automatically when you change the membership of a collection.

os_Bagtemplate <class E>class os_Bag : public os_Collection<E>

A bag (sometimes called a multiset) is an unordered collection. Unlike elements in sets, elements can occur in a bag more than once at a given time.

The count of a value in a given bag is the number of times it occurs in the bag. Each insertion of a value into a bag increases its count in the bag by 1. The count of a value in a bag is 0 if and only if the value is not an element of the bag.

Values are inserted into an os_Bag anywhere. That is, the user has no control over the ordering of the elements.

Use the constructor os_Bag::os_Bag() to create bags.

You can presize a bag when you create it.

The class os_Bag is parameterized, with a parameter for constraining the type of values allowable as elements (for the nonparameterized version of this class, see os_bag on page 144). The element type parameter, E, occurs in the signatures of some of the functions described below. The parameter is used by the compiler to detect type errors.

The element type of any instance of os_Bag must be a pointer type.

You must mark parameterized collections types in the schema source file.

138 C++ Collections Guide and Reference

Page 139: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

Tables of member functions and enumerators

The first of the following tables lists the member functions that can be performed on instances of os_Bag. The second table lists the enumerators inherited by os_Bag from os_collection. Many functions are also inherited by os_Bag from os_Collection or os_collection. The full explanation of each inherited function or enumerator appears in the entry for the class from which it is inherited. The full explanation of each function defined by os_Bag appears in this entry, after the tables. In each case, the Defined By column gives the class whose entry contains the full explanation.

Name Arguments Returns Defined By

add_index ( const os_index_path&, os_int32 options, os_database* )

( const os_index_path&, os_int32 options, os_segment* = 0 )

( const os_index_path&, os_int32 options, os_cluster* = 0 )

( const os_index_path&, os_database* )

( const os_index_path&, os_segment* = 0 )

( const os_index_path&, os_cluster* = 0 )

void

void

void

void

void

void

os_collection

cardinality ( ) const os_int32 os_collection

clear ( ) void os_collection

contains ( const E ) const os_int32 os_Collection

count ( const E ) const os_int32 os_Collection

drop_index ( const os_index_path& ) void os_collection

empty ( ) os_int32 os_collection

exists ( char *element_type_name, char *query_string, os_database *schema_database = 0, char *filename, os_unsigned_int32 line ) const

( const os_bound_query& ) const

os_int32

os_int32

os_collection

get_behavior ( ) const os_unsigned_int32

os_collection

has_index ( const os_index_path&, os_int32 index_options ) const

os_int32 os_collection

insert ( const E ) void os_Collection

insert_after ( const void*, const os_cursor& )

( const void*, os_unsigned_int32 )

void os_collection

Release 6.3 139

Page 140: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Bag

insert_before ( const void*, const os_cursor& )

( const void*, os_unsigned_int32 )

void os_collection

insert_first ( const void* ) void os_collection

insert_last ( const void* ) void os_collection

multi_trans_add_index

static void multi_trans_add_index( os_reference c, const os_index_path & p, os_int32 index_options, os_segment * index_seg, os_segment * scratch_seg, os_unsigned_int32 num_per_trans )

os_collection

multi_trans_drop_index

static void multi_trans_drop_index( os_reference c, const os_index_path & p, os_segment * scratch_seg, os_unsigned_int32 num_per_trans )

void os_collection

only ( ) const E os_Collection

operator os_Array<E>&

( ) os_Collection

operator const os_Array<E>&

( ) const os_Collection

operator os_array&

( ) os_collection

operator const os_array&

( ) const os_collection

operator os_bag&

( ) os_collection

operator const os_bag&

( ) const os_collection

operator os_List<E>&

( ) os_Collection

operator const os_List<E>&

( ) const os_Collection

operator os_list&

( ) os_collection

operator const os_list&

( ) const os_collection

operator os_Set<E>&

( ) os_Collection

operator const os_Set<E>&

( ) const os_Collection

Name Arguments Returns Defined By

140 C++ Collections Guide and Reference

Page 141: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

operator os_set&

( ) os_collection

operator const os_set&

( ) const os_collection

operator == ( const os_Collection<E>& ) const

( const E ) const

os_int32

os_int32

os_Collection

operator != ( const os_Collection<E>& ) const

( const E ) const

os_int32

os_int32

os_Collection

operator < ( const os_Collection<E>& ) const

( const E ) const

os_int32

os_int32

os_Collection

operator <= ( const os_Collection<E>& ) const

( const E ) const

os_int32

os_int32

os_Collection

operator > ( const os_Collection<E>& ) const

( const E ) const

os_int32

os_int32

os_Collection

operator >= ( const os_Collection<E>& ) const

( const E ) const

os_int32

os_int32

os_Collection

operator = ( const os_Bag<E>& ) const

( const os_Collection<E>& ) const

( const E ) const

os_Bag<E>&

os_Bag<E>&

os_Bag<E>&

os_Bag

operator |= ( const os_Collection<E>& ) const

( const E ) const

os_Bag<E>&

os_Bag<E>&

os_Bag

operator | ( const os_Collection<E>& ) const

( const E ) const

os_Collection<E>&

os_Collection<E>&

os_Collection

operator &= ( const os_Collection<E>& ) const

( const E ) const

os_Bag<E>&

os_Bag<E>&

os_Bag

operator & ( const os_Collection<E>& ) const

( const E ) const

os_Collection<E>&

os_Collection<E>&

os_Collection

operator –= ( const os_Collection<E>& ) const

( const E ) const

os_Bag<E>&

os_Bag<E>&

os_Bag

Name Arguments Returns Defined By

Release 6.3 141

Page 142: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Bag

operator - ( const os_Collection<E>& ) const

( const E ) const

os_Collection<E>&

os_Collection<E>&

os_Collection

os_Bag ( )

( os_int32 expected_size )

( const os_Bag<E>& )

( const os_Collection<E>& )

os_Bag

pick ( ) const

( const os_index_path&, const os_coll_range& ) const

E

E

os_Collection

query ( char *element_type_name, char *query_string, os_database *schema_database = 0, char *filename, os_unsigned_int32 ) const

( const os_bound_query& ) const

os_Collection<E>&

os_Collection<E>&

os_Collection

query_pick ( char *element_type_name, char *query_string, os_database *schema_database = 0 ) const

( const os_bound_query& ) const

E

E

os_Collection

remove ( const E ) os_int32 os_Collection

remove_at ( const os_Cursor<E>& ) void os_Collection

remove_first ( const void*& )

( )

os_int32

void*

os_collection

remove_last ( const void*& )

( )

os_int32

void*

os_collection

replace_at ( const E, const os_Cursor<E>& )

E os_Collection

retrieve ( const os_Cursor<E>& ) const E os_Collection

retrieve_first ( ) const

( const void*& ) const

void*

os_int32

os_collection

retrieve_last ( ) const

( const void*& ) const

void*

os_int32

os_collection

Name Arguments Returns Defined By

142 C++ Collections Guide and Reference

Page 143: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

os_Bag enumerators

The following table lists the enumerators inherited by os_Bag from os_collection.

Assignment Operator SemanticsAssignment operator semantics are described for the following functions in terms of insert operations into the target collection. The actual implementation of the assignment might be different, but the associated semantics are maintained.

os_Bag::operator =()os_Bag<E> &operator =(const os_Collection<E> &s);

os_Bag<> &operator=(const os_Bag<E> &s);

Copies the contents of the collection s into the target collection and returns the target collection. The copy is performed by effectively clearing the target, iterating over the source collection, and inserting each element into the target collection. The target collection semantics are enforced as usual during the insertion process.

os_Bag<E> &operator =(const E e);

Clears the target collection, inserts the element e into the target collection, and returns the target collection.

os_Bag::operator |=()os_Bag<E> &operator |=(const os_Collection<E> &s);

Inserts the elements contained in s into the target collection and returns the target collection.

os_Bag<E> &operator |=(const E e);

Inserts the element e into the target collection and returns the target collection.

os_Bag::operator &=()os_Bag<E> &operator &=(const os_Collection<E> &s);

For each element in the target collection, reduces the count of the element in the target to the minimum of the counts in the source and target collections. The function returns the target collection.

os_Bag<E> &operator &=(const E e);

If e is present in the target, converts the target into a collection containing just the element e. Otherwise, the function clears the target collection. The function returns the target collection.

Enumerator Inherited From

allow_nulls os_collection

EQ os_collection

GT os_collection

LT os_collection

maintain_order os_collection

Release 6.3 143

Page 144: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_bag

os_Bag::operator –=()os_Bag<E> &operator –=(const os_Collection<E> &s);

For each element in the collection s, removes s.count(e) occurrences of the element from the target collection. It returns the target collection.

os_Bag<E> &operator –=(const E e);

Removes the element e from the target collection. The function returns the target collection.

os_Bag::os_Bag()os_Bag( );

Returns an empty bag.

os_Bag(os_int32);

Returns an empty bag whose initial implementation is based on the expectation that the specified os_int32 indicates the approximate usual size of the bag, after it has been loaded with elements.

os_Bag(const os_Bag<E>&);

Returns a bag that results from assigning the specified bag to an empty bag.

os_Bag(const os_Collection<E>&);

Returns a bag that results from assigning the specified collection to an empty bag.

os_bagclass os_bag : public os_collection

A bag (sometimes called a multiset) is an unordered collection. Unlike values in sets, values can occur in a bag more than once at a given time. The count of a value in a given bag is the number of times it occurs in the bag. Repeated insertion of a value into a bag increases its count in the bag by 1 each time. The count of a value in a bag is 0 if and only if the value is not an element of the bag.

The class os_bag is nonparameterized. For the parameterized version of this class, see os_Bag on page 138.

Tables of member functions and enumerators

The first of the following tables lists the member functions that can be performed on instances of os_bag. The second table lists the enumerators inherited by os_bag from os_collection. Many functions are also inherited by os_bag from os_collection. The full explanation of each inherited function or enumerator appears in the entry for the class from which it is inherited. The full explanation of each function defined

144 C++ Collections Guide and Reference

Page 145: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

by os_bag appears in this entry, after the tables. In each case, the Defined By column gives the class whose entry contains the full explanation.

Name Arguments Returns Defined By

add_index ( const os_index_path&, os_int32 options, os_database* )

( const os_index_path&, os_int32 options, os_segment* = 0 )

( const os_index_path&, os_int32 options, os_cluster* = 0 )

( const os_index_path&, os_database* )

( const os_index_path&, os_segment* = 0 )

( const os_index_path&, os_cluster* = 0 )

void

void

void

void

void

void

os_collection

cardinality ( ) const os_int32 os_collection

clear ( ) void os_collection

contains ( const void* ) const os_int32 os_collection

count ( const void* ) const os_int32 os_collection

drop_index ( const os_index_path& ) void os_collection

empty ( ) os_int32 os_collection

exists ( char *element_type_name, char *query_string, os_database *schema_database = 0, char *filename, os_unsigned_int32 line ) const

( const os_bound_query& ) const

os_int32

os_int32

os_collection

get_behavior ( ) const os_unsigned_int32

os_collection

has_index ( const os_index_path&, os_int32 index_options ) const

os_int32 os_collection

insert ( const void* ) void os_collection

multi_trans_add_index

static void multi_trans_add_index( os_reference c, const os_index_path & p, os_int32 index_options, os_segment * index_seg, os_segment * scratch_seg, os_unsigned_int32 num_per_trans )

os_collection

Release 6.3 145

Page 146: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_bag

multi_trans_drop_index

static void multi_trans_drop_index( os_reference c, const os_index_path & p, os_segment * scratch_seg, os_unsigned_int32 num_per_trans )

void os_Collection

only ( ) const void* os_Collection

operator os_array&

( ) os_collection

operator const os_array&

( ) const os_collection

operator os_list&

( ) os_collection

operator const os_list&

( ) const os_collection

operator os_set&

( ) os_collection

operator const os_set&

( ) const os_collection

operator == ( const os_collection& ) const

( const void* ) const

os_int32

os_int32

os_collection

operator != ( const os_collection& ) const

( const void* ) const

os_int32

os_int32

os_collection

operator < ( const os_collection& ) const

( const void* ) const

os_int32

os_int32

os_collection

operator <= ( const os_collection& ) const

( const void* ) const

os_int32

os_int32

os_collection

operator > ( const os_collection& ) const

( const void* ) const

os_int32

os_int32

os_collection

operator >= ( const os_collection& ) const

( const void* ) const

os_int32

os_int32

os_collection

operator = ( const os_bag& ) const

( const os_collection& ) const

( const void* ) const

os_bag&

os_bag&

os_bag

os_bag

operator |= ( const os_collection& ) const

( const void* ) const

os_bag&

os_bag&

os_bag

operator | ( const os_collection& ) const

( const void* ) const

os_collection&

os_collection&

os_collection

operator &= ( const os_collection& ) const

( const void* ) const

os_bag&

os_bag&

os_bag

Name Arguments Returns Defined By

146 C++ Collections Guide and Reference

Page 147: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

os_bag enumerators

The following table lists the enumerators inherited by os_bag from os_collection.

operator & ( const os_collection& ) const

( const void* ) const

os_collection&

os_collection&

os_collection

operator –= ( const os_collection& ) const

( const void* ) const

os_bag&

os_bag&

os_bag

operator - ( const os_collection& ) const

( const void* ) const

os_collection&

os_collection&

os_collection

os_bag ( )

( os_int32 expected_size )

( const os_bag& )

( const os_collection& )

os_bag

pick ( ) const

( const os_index_path&, const os_coll_range& ) const

void*

void*

os_collection

query ( char *element_type_name, char *query_string, os_database *schema_database = 0, char *filename, os_unsigned_int32 ) const

( const os_bound_query& ) const

os_collection&

os_collection&

os_collection

query_pick ( char *element_type_name, char *query_string, os_database *schema_database = 0 ) const

( const os_bound_query& ) const

void*

void*

os_collection

remove ( const void* ) os_int32 os_collection

remove_at ( const os_cursor& ) void os_collection

replace_at ( const void*, const os_cursor& )

void* os_collection

retrieve ( const os_cursor& ) const void* os_collection

Name Arguments Returns Defined By

Name Inherited From

allow_nulls os_collection

EQ os_collection

GT os_collection

LT os_collection

maintain_order os_collection

Release 6.3 147

Page 148: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_bag

Assignment Operator SemanticsAssignment operator semantics are described for the following functions in terms of insert operations into the target collection. The actual implementation of the assignment might be different, but the associated semantics are maintained.

os_bag::operator =()os_bag &operator = (const os_collection &s);

Copies the contents of the collection s into the target collection and returns the target collection. The copy is performed by effectively clearing the target, iterating over the source collection, and inserting each element into the target collection. The target collection semantics are enforced as usual during the insertion process.

os_bag &operator =(const void *e);

Clears the target collection, inserts the element e into the target collection, and returns the target collection.

os_bag::operator |=()os_bag &operator |=(const os_bag &s);

Inserts the elements contained in s into the target collection and returns the target collection.

os_bag &operator |=(const void *e);

Inserts the element e into the target collection and returns the target collection.

os_bag::operator &=()os_bag &operator &=(const os_collection &s);

For each element in the target collection, reduces the count of the element in the target to the minimum of the counts in the source and target collections. The function returns the target collection.

os_bag &operator &=(const void *e);

If e is present in the target, converts the target into a collection containing just the element e. Otherwise, it clears the target collection. The function returns the target collection.

os_bag::operator –=()os_bag &operator –=(const os_collection &s);

For each element in the collection s, removes s.count(e) occurrences of the element from the target collection. The function returns the target collection.

os_bag &operator –=(const void *e);

Removes the element e from the target collection. It returns the target collection.

148 C++ Collections Guide and Reference

Page 149: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

os_bag::os_bag()os_bag( );

Returns an empty bag.

os_bag(os_int32);

Returns an empty bag whose initial implementation is based on the expectation that the specified os_int32 indicates the approximate usual cardinality of the bag, after it has been loaded with elements.

os_bag(const os_bag&);

Returns a bag that results from assigning the specified bag to an empty bag.

os_bag(const os_collection&);

Returns a bag that results from assigning the specified collection to an empty bag.

os_bound_queryInstances of this class are query objects built from instances of os_coll_query and os_keyword_arg_list. Bound queries must be transiently allocated; they should not be allocated in persistent memory.

os_bound_query::os_bound_query()os_bound_query( const os_coll_query&, const os_keyword_arg_list&);

Creates a bound query, binding the free references in the os_coll_query according to the os_keyword_arg_list. The os_bound_query constructor makes its own copy of the os_keyword_arg_list. If os_keyword_arg_list is created dynamically, it must be explicitly deleted by the user because it is not deleted when the os_bound_query destructor is called.

os_bound_query( const os_coll_query&);

Creates a bound query from an os_coll_query with no free references.

os_Collectiontemplate <class E>class os_Collection : public os_collection

The os_Collection class is an interface class. It defines functions that operate on collections. Use it as the declaration type for arguments to user-defined functions that take the collections subtype os_Array, os_Bag, os_Set, or os_List. Also, use it

Release 6.3 149

Page 150: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Collection

as an abstract base class for deriving other collections subtypes. Do not instantiate os_Collection.

A collection is an object that serves to group together other objects. The objects so grouped are the collection’s elements. For some collections, a value can occur as an element more than once. The count of a value in a given collection is the number of times (possibly 0) it occurs in the collection.

The class os_Collection is parameterized, with a parameter for constraining the type of values allowable as elements (for the nonparameterized version of this class, see os_collection on page 166). This means that when specifying os_Collection as a function’s formal parameter or as the type of a variable or data member, you must specify the the collection’s element type parameter. This is accomplished by appending to os_Collection the name of the element type enclosed in angle brackets (< >):

os_Collection<element-type-name>

The element type parameter, E, occurs in the signatures of some of the functions described below. The parameter is used by the compiler to detect type errors.

The element type of any instance of os_Collection must be a pointer type.

Tables of member functions and enumerators

The first of the following tables lists the member functions that can be performed on instances of os_Collection. The second table lists the enumerators inherited by os_Collection from os_collection. Many functions are also inherited by os_Collection from os_collection. The full explanation of each inherited function or enumerator appears in the entry for the class from which it is inherited. The full explanation of each function defined by os_Collection appears in this entry, after the tables. In each case, the Defined By column gives the class whose entry contains the full explanation.

Name Arguments Returns Defined By

add_index ( const os_index_path&, os_int32 options, os_database* )

( const os_index_path&, os_int32 options, os_segment* = 0 )

( const os_index_path&, os_int32 options, os_cluster* = 0 )

( const os_index_path&, os_database* )

( const os_index_path&, os_segment* = 0 )

( const os_index_path&, os_cluster* = 0 )

void

void

void

void

void

void

os_collection

cardinality ( ) const os_unsigned_int32

os_collection

clear ( ) void os_collection

150 C++ Collections Guide and Reference

Page 151: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

contains ( const E ) const os_int32 os_Collection

count ( const E ) const os_int32 os_Collection

drop_index ( const os_index_path& ) void os_collection

empty ( ) os_int32 os_collection

exists ( char *element_type_name, char *query_string, os_database *schema_database = 0, char *filename, os_unsigned_int32 line ) const

( const os_bound_query& ) const

os_int32

os_int32

os_collection

get_behavior ( ) const os_unsigned_int32

os_collection

insert ( const E ) void os_Collection

insert_after ( const E, const os_Cursor<E>& )

( const E, os_unsigned_int32 )

void

void

os_Collection

insert_before ( const E, const os_Cursor<E>& )

( const E, os_unsigned_int32 )

void

void

os_Collection

insert_first ( const E ) void os_Collection

insert_last ( const E ) void os_Collection

multi_trans_add_index

( os_reference c, const os_index_path & p, os_int32 index_options, os_segment * index_seg, os_segment * scratch_seg, os_unsigned_int32 num_per_trans )

os_collection

multi_trans_drop_index

( os_reference c, const os_index_path & p, os_segment * scratch_seg, os_unsigned_int32 num_per_trans )

os_collection

only ( ) const E os_Collection

operator os_Array<E>&

( ) os_Collection

operator const os_Array<E>&

( ) const os_Collection

operator os_array&

( ) os_collection

operator const os_array&

( ) const os_collection

Name Arguments Returns Defined By

Release 6.3 151

Page 152: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Collection

operator os_Bag<E>&

( ) os_Collection

operator const os_Bag<E>&

( ) const os_Collection

operator os_bag&

( ) os_collection

operator const os_bag&

( ) const os_collection

operator os_List<E>&

( ) os_Collection

operator const os_List<E>&

( ) const os_Collection

operator os_list&

( ) os_collection

operator const os_list&

( ) const os_collection

operator os_Set<E>&

( ) os_Collection

operator const os_Set<E>&

( ) const os_Collection

operator os_set&

( ) os_collection

operator const os_set&

( ) const os_collection

operator == ( const os_Collection<E>& ) const

( E ) const

os_int32

os_int32

os_Collection

operator != ( const os_Collection<E>& ) const

( E ) const

os_int32

os_int32

os_Collection

operator < ( const os_Collection<E>& ) const

( E ) const

os_int32

os_int32

os_Collection

operator <= ( const os_Collection<E>& ) const

( E ) const

os_int32

os_int32

os_Collection

operator > ( const os_Collection<E>& ) const

( E ) const

os_int32

os_int32

os_Collection

operator >= ( const os_Collection<E>& ) const

( E ) const

os_int32

os_int32

os_Collection

operator = ( const os_Collection<E>& ) const

( E ) const

os_Collection<E>&

os_Collection<E>&

os_Collection

Name Arguments Returns Defined By

152 C++ Collections Guide and Reference

Page 153: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

operator |= ( const os_Collection<E>& ) const

( E ) const

os_Collection<E>&

os_Collection<E>&

os_Collection

operator | ( const os_Collection<E>& ) const

( E ) const

os_Collection<E>&

os_Collection<E>&

os_Collection

operator &= ( const os_Collection<E>& ) const

( E ) const

os_Collection<E>&

os_Collection<E>&

os_Collection

operator & ( const os_Collection<E>& ) const

( E ) const

os_Collection<E>&

os_Collection<E>&

os_Collection

operator –= ( const os_Collection<E>& ) const

( E ) const

os_Collection<E>&

os_Collection<E>&

os_Collection

operator - ( const os_Collection<E>& ) const

( E ) const

os_Collection<E>&

os_Collection<E>&

os_Collection

pick ( ) const

( const os_index_path&, const os_coll_range& ) const

E

E

os_Collection

query ( char *element_type_name, char *query_string, os_database *schema_database = 0, char *filename, os_unsigned_int32 line, os_boolean dups ) const

( const os_bound_query& ) const

os_Collection<E>&

os_Collection<E>&

os_Collection

query_pick ( char *element_type_name, char *query_string, os_database *schema_database = 0, char *filename, os_unsigned_int32 line ) const

( const os_bound_query& ) const

E

E

os_Collection

remove ( const E ) os_int32 os_Collection

remove_at ( const os_Cursor<E>& )

( os_unsigned_int32 )

void

void

os_Collection

Name Arguments Returns Defined By

Release 6.3 153

Page 154: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Collection

os_Collection enumerators

The following table lists the enumerators for os_Collection.

os_Collection::contains()os_int32 contains(E) const;

Returns a nonzero os_int32 if the specified E is an element of the specified collection, and 0 otherwise.

os_Collection::count()os_int32 count(E);

Returns the number of occurrences (possibly 0) of the specified E in the collection for which the function was called.

os_Collection::exists()os_int32 exists( char *element_type_name, char *query_string, os_database *schema_database = 0, char *file_name = 0,

remove_first ( const E& )

( )

os_int32

E

os_Collection

remove_last ( const E& )

( )

os_int32

E

os_Collection

replace_at ( const E, const os_Cursor<E>& )

( E, os_unsigned_int32 )

E

E

os_Collection

retrieve ( os_unsigned_int32 ) const

( const os_Cursor<E>& ) const

E

E

os_Collection

retrieve_first ( ) const

( E& ) const

E

os_int32

os_Collection

retrieve_last ( ) const

( E& ) const

E

os_int32

os_Collection

Name Arguments Returns Defined By

Name Inherited From

allow_duplicates os_collection

allow_nulls os_collection

EQ os_collection

GT os_collection

LT os_collection

maintain_order os_collection

154 C++ Collections Guide and Reference

Page 155: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

os_unsigned_int32 line = 0, ) const;

For a description of os_Collection::exists() and its arguments, see os_collection::exists() on page 175.

os_Collection::insert()void insert(const E);

Adds the specified instance of E to the collection for which the function was called. The behavior of insert() depends on the characteristics of the collection you are using:

• If the collection is ordered, the element is inserted at the end of the collection.

• If the collection disallows nulls and the specified E is 0, err_coll_nulls is signaled.

• If the collection disallows duplicates and the specified E is already an element of the collection, the insertion is ignored; that is, nothing is inserted into the collection.

os_Collection::insert_after()void insert_after(const E, const os_Cursor<E>&);

Adds the specified instance of E to the collection for which the function was called. The new element is inserted immediately after the element at which the specified cursor is positioned. The index of all elements after the new element increases by 1. The cursor must be a default cursor (that is, one that results from a constructor call with only a single argument). If the cursor is null, err_coll_null_cursor is signaled. If the cursor is invalid, err_coll_illegal_cursor is signaled.

void insert_after(const E, os_unsigned_int32);

Adds the specified instance of E to the collection for which the function was called. The new element is inserted after the position indicated by the os_unsigned_int32. The index of all elements after the new element increases by 1. If the index is not less than the collection’s cardinality, err_coll_out_of_range is signaled.

The behavior of insert_after() (both signatures) depends on the characteristics of the collection you are using:

• If the collection is not ordered, err_coll_not_supported is signaled.

• If the collection disallows nulls and the specified E is 0, err_coll_nulls is signaled.

• If the collection is an array, all elements after this element are pushed down.

• If the collection disallows duplicates and the specified E is already an element of the collection, the insertion is ignored; that is, nothing is inserted into the collection.

os_Collection::insert_before()void insert_before(const E, const os_Cursor<E>&);

Release 6.3 155

Page 156: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Collection

Adds the specified instance of E to the collection for which the function was called. The new element is inserted immediately before the element at which the specified cursor is positioned. The index of all elements after the new element increases by 1. The cursor must be a default cursor (that is, one that results from a constructor call with only a single argument). If the cursor is null, err_coll_null_cursor is signaled. If the cursor is invalid, err_coll_illegal_cursor is signaled.

void insert_before(const E, os_unsigned_int32);

Adds the specified instance of E to the collection for which the function was called. The new element is inserted immediately before the position indicated by the os_unsigned_int32. The index of all elements after the new element increases by 1. If the index is not less than the collection’s cardinality, err_coll_out_of_range is signaled.

The behavior of insert_before() (both signatures) depends on the characteristics of the collection you are using:

• If the collection is not ordered, err_coll_not_supported is signaled.

• If the collection disallows nulls and the specified E is 0, err_coll_nulls is signaled.

• If the collection is an array, all elements after the inserted element are pushed down.

• If the collection disallows duplicates and the specified E is already an element of the collection, the insertion is ignored; that is, nothing is inserted into the collection.

os_Collection::insert_first()void insert_first(const E);

Adds the specified instance of E to the beginning of the collection for which the function was called. The behavior of insert_first() depends on the characteristics of the collection you are using:

• If the collection is not ordered, err_coll_not_supported is signaled.

• If the collection disallows nulls and the specified E is 0, err_coll_nulls is signaled.

• If the collection is an array, all elements after the inserted element are pushed down.

• If the collection disallows duplicates and the specified E is already an element of the collection, the insertion is ignored; that is, nothing is inserted into the collection.

os_Collection::insert_last()void insert_last(const E);

Adds the specified instance of E to the end of the collection for which the function was called.

• If the collection is not ordered, err_coll_not_supported is signaled.

156 C++ Collections Guide and Reference

Page 157: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

• If the collection disallows nulls and the specified E is 0, err_coll_nulls is signaled.

• If the collection disallows duplicates and the specified E is already an element of the collection, the insertion is ignored; that is, nothing is inserted into the collection.

os_Collection::only()E only( ) const;

Returns the only element of the specified collection. If the collection has more than one element, err_coll_not_singleton is signaled. If the collection is empty, 0 is returned.

os_Collection::operator os_Array()operator os_Array<E>&( );

Returns an array with the same elements and behavior as the specified collection. An exception is signaled if the collection’s behavior is incompatible with the required behavior of arrays.

os_Collection::operator const os_Array()operator const os_Array<E>&( ) const;

Returns an array with the same elements and behavior as the specified collection. An exception is signaled if the collection’s behavior is incompatible with the required behavior of arrays.

os_Collection::operator os_Bag()operator os_Bag<E>&( );

Returns a bag with the same elements and behavior as the specified collection. An exception is signaled if the collection’s behavior is incompatible with the required behavior of bags.

os_Collection::operator const os_Bag()operator const os_Bag<E>&( ) const;

Returns a bag with the same elements and behavior as the specified collection. An exception is signaled if the collection’s behavior is incompatible with the required behavior of bags.

os_Collection::operator os_List()operator os_List<E>&( );

Returns a list with the same elements and behavior as the specified collection. An exception is signaled if the collection’s behavior is incompatible with the required behavior of lists.

Release 6.3 157

Page 158: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Collection

os_Collection::operator const os_List()operator const os_List<E>&( ) const;

Returns a list with the same elements and behavior as the specified collection. An exception is signaled if the collection’s behavior is incompatible with the required behavior of lists.

os_Collection::operator os_Set()operator os_Set<E>&( );

Returns a set with the same elements and behavior as the specified collection. An exception is signaled if the collection’s behavior is incompatible with the required behavior of sets.

os_Collection::operator const os_Set()operator const os_Set<E>&( ) const;

Returns a set with the same elements and behavior as the specified collection. An exception is signaled if the collection’s behavior is incompatible with the required behavior of sets.

os_Collection::operator ==()os_int32 operator ==(const os_Collection<E> &s) const;

Returns a nonzero value if and only if for each element in the this collection count(element) == s.count(element) and both collections have the same cardinality. Note that the comparison does not take order into account.

os_int32 operator ==(const E s) const;

Returns a nonzero value if and only if the collection contains s and nothing else.

os_Collection::operator !=()os_int32 operator !=(const os_Collection<E> &s) const;

Returns a nonzero value if and only if it is not the case both that (1) for each element in the this collection, count(element) == s.count(element), and (2) both collections have the same cardinality. Note that the comparison does not take order into account.

os_int32 operator !=(const E s) const;

Returns a nonzero value if and only if it is not the case that the collection contains s and nothing else.

os_Collection::operator <()os_int32 operator <(const os_Collection<E> &s) const;

Returns a nonzero value if and only if for each element in the this collection count(element) <= s.count(element) and cardinality( ) < s.cardinality( ).

158 C++ Collections Guide and Reference

Page 159: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

os_int32 operator <(const E s) const;

Returns a nonzero value if and only if the specified collection is empty.

os_Collection::operator <=()os_int32 operator <=(const os_Collection<E> &s) const;

Returns a nonzero value if and only if for each element in the this collection count(element) <= s.count(element).

os_int32 operator <=(const E s) const;

Returns a nonzero value if and only if the specified collection is empty or e is the only element in the collection.

os_Collection::operator >()os_int32 operator >(const os_Collection<E> &s) const;

Returns a nonzero value if and only if for each element of s.count(element) >= s.count(element) and cardinality( ) > s.cardinality( ).

os_int32 operator >(const E s) const;

Returns a nonzero value if and only if count(s) >= 1 and cardinality( ) > 1.

os_Collection::operator >=()os_int32 operator >=(const os_Collection<E> &s) const;

Returns a nonzero value if and only if for each element of s count(element) >= s.count(element).

os_int32 operator >=(const E s) const;

Returns a nonzero value if and only if count(s) >= 1.

Assignment Operator SemanticsAssignment operator semantics are described for the following functions in terms of insert operations into the target collection. The actual implementation of the assignment might be different, but the associated semantics are maintained.

os_Collection::operator =()os_Collection<E> &operator =(const os_Collection<E> &s);

Copies the contents of the collection s into the target collection and returns the target collection. The copy is performed by effectively clearing the target, iterating over the source collection, and inserting each element into the target collection. The iteration is ordered if the source collection is ordered. The target collection semantics are enforced as usual during the insertion process.

os_Collection<E> &operator =(const E e);

Clears the target collection, inserts the element e into the target collection, and returns the target collection.

Release 6.3 159

Page 160: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Collection

os_Collection::operator |=()os_Collection<E> &operator |=(const os_Collection<E> &s);

Inserts the elements contained in s into the target collection and returns the target collection.

os_Collection<E> &operator |=(const E e);

Inserts the element e into the target collection and returns the target collection.

os_Collection::operator |()os_Collection<E> &operator |(const os_Collection<E> &s) const;

Copies the contents of this into a new collection, c, and then performs c |= s. The new collection, c, is then returned. If either operand allows duplicates or nulls, the result does. If both operands maintain order, the result does.

os_Collection<E> &operator |(const E e) const;

Copies the contents of this into a new collection, c, and then performs c |= e. The new collection, c, is then returned. If this allows duplicates, maintains order, or allows nulls, the result does.

os_Collection::operator &=()os_Collection<E> &operator &=(const os_Collection<E> &s);

For each element in the target collection, reduces the count of the element in the target to the minimum of the counts in the source and target collections. If the collection is ordered and contains duplicates, it does so by retaining the appropriate number of leading elements. The function returns the target collection.

os_Collection<E> &operator &=(const E e);

If e is present in the target, converts the target into a collection containing just the element e. Otherwise, it clears the target collection. The function returns the target collection.

os_Collection::operator &()os_Collection<E> &operator &(const os_Collection<E> &s) const;

Copies the contents of this into a new collection, c, and then performs c &= s. The new collection, c, is then returned. If either operand allows duplicates or nulls, the result does. If both operands maintain order, the result does.

os_Collection<E> &operator &(E e) const;

Copies the contents of this into a new collection, c, and then performs c &= e. The new collection, c, is then returned. If this allows duplicates, maintains order, or allows nulls, the result does.

os_Collection::operator –=()os_Collection<E> &operator –=(const os_Collection<E> &s);

160 C++ Collections Guide and Reference

Page 161: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

For each element in the collection s, removes s.count(e) occurrences of the element from the target collection. If the collection is ordered, it is the first s.count(e) elements that are removed. It returns the target collection.

os_Collection<E> &operator –=(E e);

Removes the element e from the target collection. If the collection is ordered, it is the first occurrence of the element that is removed from the target collection. It returns the target collection.

os_Collection::operator –()os_Collection<E> &operator –(const os_Collection<E> &s) const;

Copies the contents of this into a new collection, c, and then performs c –= s. The new collection, c, is then returned. If either operand allows duplicates or nulls, the result does. If both operands maintain order, the result does.

os_Collection<E> &operator –(E e) const;

Copies the contents of this into a new collection, c, and then performs c –= s. The new collection, c, is then returned. If this allows duplicates, maintains order, or allows nulls, the result does.

os_Collection::pick()E pick( ) const;

Returns an arbitrary element of the specified collection. If the collection is empty, 0 is returned.

os_Collection::query()os_Collection<E> &query( char *element_type_name, char *query_string, os_database *schema_database = 0, char *file_name = 0, os_unsigned_int32 line = 0, os_boolean dups = query_dont_preserve_duplicates) const;

Returns a reference to a heap-allocated collection with default behavior containing those elements of this that satisfy the selection criterion expressed by the query_string. When you no longer need the resulting collection, you should reclaim its memory with ::operator delete( ) to avoid memory leaks.

For information about deleting objects, see ::operator delete() in Chapter 3 of the C++ A P I Reference.

The element_type_name argument is the name of the element type of this. Names established through the use of typedef are not allowed.

Query strings The query_string argument indicates the query’s selection criterion. It can be either a C++ control expression or an expression that uses the pattern-matching operator (~~). For more information about query strings, see the following:

Release 6.3 161

Page 162: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Collection

• C++ Control Expressions in Query Strings on page 84

• Matching Patterns in Query Strings on page 84

• Calling Functions in Query Strings on page 86

• Nested Queries on page 87

Within the selection criterion of query expressions, member names are implicitly qualified by this, just as are member names in function member bodies.

The schema_database is a database whose schema contains all the types mentioned in the selection criterion. This database provides the environment in which the query is analyzed and optimized. If this argument is not supplied, the database in which the collection resides is used, which is always adequate. If the query is being performed over a transient collection, the application schema database is used by default.

In addition to being used as the default schema database for queries over transient collections, the application schema database is used if the transient database is supplied explicitly.

Because the application schema database is never opened just before analysis of a query, use of the application schema database in query analysis carries the overhead of a database open. Therefore, explicitly supplying an appropriate database that is already open improves query performance.

ObjectStore uses file_name and line when reporting errors related to the query. You can set them to identify the location of the query’s source code.

If dups is the enumerator os_collection::query_dont_preserve_duplicates, duplicate elements that satisfy the query condition are not included in the query result. If dups is the enumerator os_collection::query_preserve_duplicates, duplicate elements that satisfy the query condition are included in the query result.

os_Collection <E> &query( const os_bound_query& , os_boolean dups = query_dont_preserve_duplicates) const;

Returns a reference to a heap-allocated collection with default behavior containing those elements of this that satisfy the os_bound_query. If dups is the enumerator query_dont_preserve_duplicates, duplicate elements that satisfy the query condition are not included in the query result. If dups is the enumerator query_preserve_duplicates, duplicate elements that satisfy the query condition are included in the query result.

When you no longer need the resulting collection, you should reclaim its memory with ::operator delete( ) to avoid memory leaks. For information about deleting objects, see ::operator delete() in Chapter 3 of the C++ A P I Reference.

os_Collection::query_pick()E query_pick( char *element_type_name, char *query_string,

162 C++ Collections Guide and Reference

Page 163: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

os_database *schema_database = 0, char *filename, os_unsigned_int32 line) const;

Returns an element of this that satisfies the selection criterion expressed by the query_string. If there is more than one such element, one is picked arbitrarily and returned. If no element satisfies the query or the collection is empty, 0 is returned.

The argument element_type_name is the name of the element type of this. Names established through the use of typedef are not allowed.

Query strings The query_string argument indicates the query’s selection criterion. It can be either a C++ control expression or an expression that uses the pattern-matching operator (~~). For more information about query strings, see the following:

• C++ Control Expressions in Query Strings on page 84

• Matching Patterns in Query Strings on page 84

• Calling Functions in Query Strings on page 86

• Nested Queries on page 87

Within the selection criterion of query expressions, member names are implicitly qualified by this, just as are member names in function member bodies.

The schema_database is a database whose schema contains all the types mentioned in the selection criterion. This database provides the environment in which the query is analyzed and optimized. The database in which the collection resides is often an appropriate choice for this.

If the transient database is specified, the application’s schema (stored in the application schema database) is used to evaluate the query.

E query_pick(const os_bound_query&) const;

Returns an element of this that satisfies the os_bound_query. If there is more than one such element, one is picked arbitrarily and returned. If no element satisfies the query or the collection is empty, 0 is returned.

os_Collection::remove()os_int32 remove(const E);

Removes the specified instance of E from the collection for which the function was called, if present. If the collection is ordered, the first occurrence of the specified E is removed. If the collection is an array, all elements after this element are pushed up.

os_Collection::remove_first()os_int32 remove_first(const E&);

Removes the first element from the specified collection and returns the removed element, or 0 if the collection is empty. If successful, the function modifies its argument to refer to the removed element. If the specified collection is not ordered, err_coll_not_supported is signaled. If the collection is an array, all elements after the removed element are pushed up.

Release 6.3 163

Page 164: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Collection

E remove_first( );

Removes the first element from the specified collection and returns the removed element, or 0 if the collection is empty. Note that for collections that allow null elements, the significance of the return value can be ambiguous. The preceding alternative overloading of remove_first( ) can be used to avoid the ambiguity. If the specified collection is not ordered, err_coll_not_supported is signaled. If the collection is an array, all elements after the removed element are pushed up.

os_Collection::remove_last()os_int32 remove_last(const E&);

Removes the last element from the specified collection if the collection is not empty, returns a nonzero os_int32 if the collection is not empty, and modifies its argument to refer to the removed element. If the specified collection is not ordered, err_coll_not_supported is signaled.

E remove_last( );

Removes the last element from the specified collection and returns the removed element, or 0 if the collection was empty. Note that for collections that allow null elements, the significance of the return value can be ambiguous. The preceding alternative overloading of remove_last( ) can be used to avoid the ambiguity. If the specified collection is not ordered, err_coll_not_supported is signaled.

os_Collection::replace_at()E replace_at(const E, const os_Cursor<E>&);

Returns the element at which the specified cursor is positioned and replaces it with the specified instance of E. The cursor must be a default cursor (that is, one that results from a constructor call with only a single argument). If the cursor is null, err_coll_null_cursor is signaled. If the cursor is invalid, err_coll_illegal_cursor is signaled.

E replace_at(const E, os_unsigned_int32 position);

Returns the element at the specified position and replaces it with the specified instance of E. If the position is not less than the collection’s cardinality, err_coll_out_of_range is signaled. If the collection is not ordered, err_coll_not_supported is signaled.

os_Collection::retrieve()E retrieve(const os_Cursor<E>&) const;

Returns the element at which the specified cursor is positioned. The cursor must be a default cursor (that is, one that results from a constructor call with only a single argument). If the cursor is null, err_coll_null_cursor is signaled. If the cursor is invalid, err_coll_illegal_cursor is signaled.

E retrieve(os_unsigned_int32 position) const;

164 C++ Collections Guide and Reference

Page 165: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

Returns the element at the specified position. If the position is not less than the collection’s cardinality, err_coll_out_of_range is signaled. If the collection is not ordered, err_coll_not_supported is signaled.

os_Collection::retrieve_first()E retrieve_first( ) const;

Returns the specified collection’s first element, or 0 if the collection is empty. For collections that contain zeros, see the other overloading of this function, following. If the collection is not ordered, err_coll_not_supported is signaled.

os_int32 retrieve_first(const E&) const;

Returns 0 if the specified collection is empty; returns a nonzero os_int32 otherwise. Modifies the argument to refer to the collection’s first element. If the collection is not ordered, err_coll_not_supported is signaled.

os_Collection::retrieve_last()E retrieve_last( ) const;

Returns the specified collection’s last element, or 0 if the collection is empty. For collections that contain zeros, see the other overloading of this function, following. If the collection is not ordered, err_coll_not_supported is signaled.

os_int32 retrieve_last(const E&) const;

Returns 0 if the specified collection is empty; returns a nonzero os_int32 otherwise. Modifies the argument to refer to the collection’s last element. If the collection is not ordered, err_coll_not_supported is signaled.

Release 6.3 165

Page 166: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Collection

os_collectionA collection is an object that serves to group together other objects. The objects so grouped are the collection’s elements. For some collections, a value can occur as an element more than once. The count of a value in a given collection is the number of times (possibly 0) it occurs in the collection.

Like an os_Collection, an os_collection is not meant to be instantiated. It is a base class for the other collection subtypes. It can be used as a generic handle to be passed around to user-defined functions that can take any collection subtype as an argument.

This class has a parameterized subtype. See os_bound_query on page 149.

The element type of any instance of os_collection must be a pointer type.

In addition, the static member function os_collection::initialize( ) must be executed in a process before using any ObjectStore collection or relationship functionality is made.

166 C++ Collections Guide and Reference

Page 167: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

Table of member functions

The following table lists the member functions defined by os_collection, together with their formal argument lists and return types. The full explanation of each function follows the table.

Name Arguments Returns

add_index ( const os_index_path&, os_int32 options, os_database* )

( const os_index_path&, os_int32 options, os_segment* = 0 )

( const os_index_path&, os_int32 options, os_cluster* = 0 )

( const os_index_path&, os_database* )

( const os_index_path&, os_segment* = 0 )

( const os_index_path&, os_cluster* = 0 )

void

void

void

void

void

void

cardinality ( ) const os_int32

cardinality_estimate ( ) const os_unsigned_int32

cardinality_is_maintained

( ) const os_int32

clear ( ) void

contains ( const void* ) const

count ( const void* ) const os_int32

drop_index ( const os_index_path& ) void

empty ( ) os_int32

exists ( char *element_type_name, char *query_string, os_database *schema_database = 0, char *filename, os_unsigned_int32 line ) const

( char *element_type_name, char *query_string, os_str_conv::encode_type \ string_literal_ char_encoding, os_database *schema_database = 0, char *filename, os_unsigned_int32 line ) const

( const os_bound_query& ) const

os_int32

os_int32

os_int32

get_behavior ( ) const os_unsigned_int32

get_indexes ( ) const os_collection*

has_index ( const os_index_path&, os_int32 index_options = unordered ) const

os_int32

Release 6.3 167

Page 168: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Collection

initialize ( ) void

insert ( const void* ) void

insert_after ( const void*, const os_cursor& )

( const void*, os_unsigned_int32 )

void

void

insert_before ( const void*, const os_cursor& )

( const void*, os_unsigned_int32 )

void

void

insert_first ( const void* ) void

insert_last ( const void* ) void

multi_trans_add_index ( os_reference c, const os_index_path & p, os_int32 index_options, os_segment * index_seg, os_segment * scratch_seg, os_unsigned_int32 num_per_trans )

multi_trans_drop_index

( os_reference c, const os_index_path & p, os_segment * scratch_seg, os_unsigned_int32 num_per_trans )

only ( ) const void*

operator os_array& ( )

operator const os_array&

( ) const

operator os_bag& ( )

operator const os_bag&

( ) const

operator os_int32 ( ) const

operator os_list& ( )

operator const os_list&

( ) const

operator os_set& ( )

operator const os_set&

( ) const

operator == ( const os_collection& ) const

( const void* ) const

os_int32

os_int32

operator != ( const os_collection& ) const

( const void* ) const

os_int32

os_int32

operator < ( const os_collection& ) const

( const void* ) const

os_int32

os_int32

Name Arguments Returns

168 C++ Collections Guide and Reference

Page 169: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

operator <= ( const os_collection& ) const

( const void* ) const

os_int32

os_int32

operator > ( const os_collection& ) const

( const void* ) const

os_int32

os_int32

operator >= ( const os_collection& ) const

( const void* ) const

os_int32

os_int32

operator = ( const os_collection& ) const

( const void* ) const

os_collection&

os_collection&

operator |= ( const os_collection& ) const

( const void* ) const

os_collection&

os_collection&

operator | ( const os_collection& ) const

( const void* ) const

os_collection&

os_collection&

operator &= ( const os_collection& ) const

( const void* ) const

os_collection&

os_collection&

operator & ( const os_collection& ) const

( const void* ) const

os_collection&

os_collection&

operator –= ( const os_collection& ) const

( const void* ) const

os_collection&

os_collection&

operator - ( const os_collection& ) const

( const void* ) const

os_collection&

os_collection&

pick ( ) const void*

query ( char *element_type_name, char *query_string, os_database *schema_database = 0, char *filename, os_unsigned_int32 line, os_boolean dups ) const

( char *element_type_name, char *query_string, os_str_conv::encode_type \ string_literal_ char_encoding, os_database *schema_database = 0, char *filename, os_unsigned_int32 line, os_boolean dups ) const

( const os_bound_query&, os_boolean dups ) const

os_collection&

os_collection&

os_collection&

Name Arguments Returns

Release 6.3 169

Page 170: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Collection

os_collection enumerators

The following lists enumerators for os_collection.

• allow_duplicates

• allow_nulls

• EQ

• GE

• GT

• LE

query_pick ( char *element_type_name, char *query_string, os_database *schema_database = 0, char *filename, os_unsigned_int32 line ) const

( char *element_type_name, char *query_string, os_str_conv::encode_type \ string_literal_ char_encoding, os_database *schema_database = 0, char *filename, os_unsigned_int32 line ) const

( const os_bound_query& ) const

void*

void*

void*

remove ( const void* ) os_int32

remove_at ( const os_cursor& )

( os_unsigned_int32 )

void

void

remove_first ( const void*& )

( )

os_int32

void*

remove_last ( const void*& )

( )

os_int32

void*

replace_at ( const void*, const os_cursor& )

( const void*, os_unsigned_int32 )

void*

void*

retrieve ( os_unsigned_int32 ) const

( const os_cursor& ) const

void*

void*

retrieve_first ( ) const

( const void*& ) const

void*

os_int32

retrieve_last ( ) const

( const void*& ) const

void*

os_int32

set_query_memory_mode (os_query_memory_mode mode) void

trace_index_usage (os_boolean run_trace,

const char * file_name = 0)

void

update_cardinality ( ) os_unsigned_int32

Name Arguments Returns

170 C++ Collections Guide and Reference

Page 171: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

• LT

• maintain_order

• NE

• optimized_list

os_collection::add_index()void add_index( const os_index_path&, os_int32 options, os_segment* = 0);

Creates an index into the specified collection, keyed by the specified os_index_path. The presence of the index allows optimization of queries involving look-up of collection elements based on the specified path. See the class os_index_path on page 226. If the specified collection already has an index with the specified key, this call is ignored. Two instances of os_index_path specify the same key if they were created with the same path string and element type.

Collections with large cardinality might warrant adding the index by using multiple transactions. See os_collection::multi_trans_add_index() on page 179.

The exception err_am is signaled if a class mentioned in the path serving as index key cannot be found in the schema of the database containing the index (or the application schema, if the index is transient).

The options argument is a bit pattern indicating the behavior of the index. You supply the bit pattern by forming the bit-wise disjunction (using | ) of enumerators signifying the desired behavior. For information about the individual enumerators, see the following:

• os_index_path::allow_duplicates

• os_index_path::copy_key

• os_index_path::no_duplicates

• os_index_path::ordered

• os_index_path::create()

• os_index_path::unordered

• os_index_path::signal_duplicates

By default, indexes have the following behavior:

os_index_path::unordered |os_index_path::allow_duplicates |os_index_path::copy_key.

The os_segment* argument points to the segment in which the new index is to be allocated. If the argument is omitted or specified as 0, the index is allocated in the same segment as the collection being indexed. Putting each index in its own dedicated segment often results in better performance.

The function add_index( ) can be invoked at any point in the lifetime of a collection.

Release 6.3 171

Page 172: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Collection

For a given os_index_path, you can have only one index on the collection. This index is either ordered or unordered for a given index path.

Restrictions A restriction in the creation of an index path for use with an os_ixonly collection is that the first component of an index path cannot be a collection.

Also, you cannot set an index on the return value of a member function that returns a temporary char* value.

Another restriction about index keys when they are user class types is that they cannot contain data members that are os_references to objects in a different segment. This is because, for copy key indexes, the key is copied with memcpy(). This does not work for os_references because a per-segment table keyed by the os_reference needs to be updated. This does not happen with an os_reference that is copied with memcpy(). It only happens if the os_reference is copied with operator=.

void add_index( const os_index_path&, os_int32 options, os_cluster* clstr = 0 );

Creates an unordered, copy-key index that allows duplicates into the specified collection, keyed by the specified os_index_path. The presence of the index allows optimization of queries involving look-up of collection elements based on the specified path. See the class os_index_path on page 226. If the specified collection already has an index with the specified key, this call is ignored. The clstr argument points to the cluster in which the new index is to be allocated. The index may create an additional internal cluster within the same segment.

If the clstr argument is omitted or specified as 0, the index is allocated in the same cluster as the collection being indexed. See the os_segment overloading of add_index() for an explanation of the options argument.

void add_index( const os_index_path&, os_int32 options, os_database* );

Creates an unordered, copy-key index that allows duplicates into the specified collection, keyed by the specified os_index_path. The presence of the index allows optimization of queries involving look-up of collection elements based on the specified path. See the class os_index_path on page 226. If the specified collection already has an index with the specified key, this call is ignored. The os_database* argument points to the database in which the new index is to be allocated. See the os_segment overloading of add_index() for an explanation of the options argument.

void add_index( const os_index_path&, os_segment* seg = 0);

172 C++ Collections Guide and Reference

Page 173: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

Creates an unordered, copy-key index that allows duplicates into the specified collection, keyed by the specified os_index_path. The presence of the index allows optimization of queries involving look-up of collection elements based on the specified path. See the class os_index_path on page 226. If the specified collection already has an index with the specified key, this call is ignored. The seg argument points to the segment in which the new index is to be allocated. If the argument is omitted or if 0 is supplied, the index is allocated in the same segment as the collection being indexed.

void add_index( const os_index_path&, os_cluster* clstr = 0 );

Creates an unordered, copy-key index that allows duplicates into the specified collection, keyed by the specified os_index_path. The presence of the index allows optimization of queries involving look-up of collection elements based on the specified path. See the class os_index_path on page 226. If the specified collection already has an index with the specified key, this call is ignored. The clstr argument points to the cluster in which the new index is to be allocated. The index may create an additional internal cluster within the same segment. If the argument is omitted or if 0 is supplied, the index is allocated in the same cluster as the collection being indexed.

void add_index( const os_index_path&, os_database* );

Creates an unordered, copy-key index that allows duplicates into the specified collection, keyed by the specified os_index_path. The presence of the index allows optimization of queries involving look-up of collection elements based on the specified path. See the class os_index_path on page 226. If the specified collection already has an index with the specified key, this call is ignored. The os_database* argument points to the database in which the new index is to be allocated.

os_collection::allow_duplicates Possible element of the bit-wise disjunction return value of the os_collection::get_behavior() members of os_collection, os_Collection, and their subtypes. Indicates that the collection allows duplicate insertions of elements, and increments the count of each element by 1 with each insertion.

os_collection::allow_nulls Possible element of the bit-wise disjunction return value of the os_collection::get_behavior() members of os_collection, os_Collection, and their subtypes. Indicates that the collection allows the insertion of null pointers.

os_collection::cardinality()os_unsigned_int32 cardinality( ) const;

Returns the sum of the counts of each element of the specified collection.

Release 6.3 173

Page 174: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Collection

os_collection::cardinality_estimate()os_unsigned_int32 cardinality_estimate( ) const;

Returns an estimate of a collection’s cardinality. This is an O(1) operation in the size of the collection. This function returns the cardinality as of the last call to os_collection::update_cardinality( ); or, for collections that maintain cardinality, the actual cardinality is returned. For maintain_cardinality behavior, see os_Ixonly and os_ixonly on page 229. Also, see os_Dictionary::os_Dictionary() on page 220.

os_collection::cardinality_is_maintained()os_int32 cardinality_is_maintained( ) const;

Returns nonzero if the collection maintains cardinality; returns 0 otherwise. For maintain_cardinality behavior, see os_Ixonly and os_ixonly on page 229. Also, see os_Dictionary::os_Dictionary() on page 220 and os_Dictionary::os_Dictionary() on page 220.

os_collection::clear()void clear( );

Removes all elements of the specified collection.

os_collection::contains()os_int32 contains(const void*) const;

Returns a nonzero os_int32 if the specified void* is an element of the specified collection, and 0 otherwise.

os_collection::count()os_int32 count(const void*) const

Returns the number of occurrences (possibly 0) of the specified void* in the collection for which the function was called.

os_collection::drop_index()void drop_index(const os_index_path &p);

Destroys the index into the specified collection whose key is specified by p. The argument p does not need to be the same instance of os_index_path supplied when the index was added, but it must specify the same key. Two os_index_paths created with the same path string and type string specify the same index key.

Collections with large cardinality might warrant removing the index with multiple transactions. See os_collection::multi_trans_drop_index() on page 180.

os_collection::empty()os_int32 empty( );

Returns a nonzero os_int32 if the specified collection is empty, and 0 otherwise.

174 C++ Collections Guide and Reference

Page 175: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

os_collection::EQPossible return value of the user-supplied rank functions and possible argument to os_coll_range constructors, signifying equal.

os_collection::exists()os_int32 exists( char *element_type_name, char *query_string, os_database *schema_database = 0, char *file_name = 0, os_unsigned_int32 line = 0, ) const;

Returns nonzero (true) if there exists an element of this that satisfies the selection criterion expressed by the query_string; otherwise, it returns 0 (false).

The argument element_type_name is the name of the element type of this. Names established through the use of typedef are not allowed.

Query strings The query_string argument indicates the query’s selection criterion. It can be either a C++ control expression or an expression that uses the pattern-matching operator (~~). For more information about query strings, see the following:

• C++ Control Expressions in Query Strings on page 84

• Matching Patterns in Query Strings on page 84

• Calling Functions in Query Strings on page 86

• Nested Queries on page 87

Within the selection criterion of query expressions, member names are implicitly qualified by this, just as are member names in function member bodies.

The schema_database is a database whose schema contains all the types mentioned in the selection criterion. This database provides the environment in which the query is analyzed and optimized. The database in which the collection resides is often appropriate.

If the transient database is specified, the application’s schema (stored in the application schema database) is used to evaluate the query. ObjectStore uses file_name and line when reporting errors related to the query. You can set them to identify the location of the query’s source code.

os_int32 exists(const os_bound_query&) const;

Returns a nonzero os_int32 (true) if there exists an element of this that satisfies the os_bound_query. Otherwise, 0 (false) is returned.

Multibyte characters query support

The following form includes an argument of type os_str_conv::encode_type in order to support literal strings containing multibyte characters. Valid values for this argument are ASCII, UNICODE, UNICODE_BIG, UNICODE_LITTLE, UTF8, EUC_JP, JIS, or SJIS.

os_int32 exists( char *element_type_name,

Release 6.3 175

Page 176: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Collection

char *query_string, os_str_conv::encode_type string_literal_char_encoding, os_database *schema_database = 0, char *file_name = 0, os_unsigned_int32 line = 0, ) const;

os_collection::GEPossible argument to os_coll_range constructors, signifying greater than or equal to.

os_collection::GTPossible return value of the user-supplied rank functions, and possible argument to os_coll_range constructors, signifying greater than.

os_collection::get_behavior()os_unsigned_int32 get_behavior( ) const;

Returns a bit pattern indicating the specified collection’s behavior. The return value is a bit-wise disjunction of enumerators indicating all the properties of the collection. For information about the enumerators, see

• os_collection::allow_duplicates

• os_collection::allow_nulls

• os_collection::maintain_order

os_collection::get_indexes()os_collection *get_indexes( ) const;

If this has associated indexes, returns a collection of os_index_name*s, one for each index. If this has no indexes, 0 is returned. The caller is responsible for deleting the collection and its contents.

os_collection::has_index()os_int32 has_index( const os_index_path&, os_int32 index_options = unordered ) const;

Returns a value indicating whether an index can support the index type specified with index_options. Possible values for index_options are ordered and unordered.

You must supply a path string and one of the index options. An index that supports exact-match queries (hash table) can only be used for exact matches. An index that supports range queries (binary tree) can be used for both exact match and range queries. In effect, os_collection::has_index answers the question “Can this index support this type of query?” and not what option was used to create the index.

• For an index created with the ordered option, the following is true:

- has_index(path,os_index::ordered) returns true.

176 C++ Collections Guide and Reference

Page 177: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

- has_index(path,os_index::unordered) returns true.

• For an index created with the unordered option, the following is true

- has_index(path,os_index::ordered) returns false.

- has_index(path,os_index::unordered) returns true.

os_collection::initialize()static void initialize( );

Must be called in a session before using any ObjectStore collection or relationship functionality. Calling initialize( ) initializes the collections facility for the entire process. Calling initialize( ) outside a session or more than once has no effect.

For more information about sessions, see Chapter 5, Performing Advanced Collections Operations, in the ObjectStore Advanced C++ A P I User Guide.

os_collection::insert()void insert(const void*);

Adds the specified void* to the collection for which the function was called. The behavior of insert() depends on the characteristics of the collection you are using:

• If the collection is ordered, the element is inserted at the end of the collection.

• If the collection disallows duplicates, and the specified void* is already present in the collection, the insertion is silently ignored.

• If the collection disallows nulls, and the specified void* is 0, err_coll_nulls is signaled.

os_collection::insert_after()void insert_after(const void*, const os_cursor&);

Adds the specified void* to the collection for which the function was called. The new element is inserted immediately after the element at which the specified cursor is positioned. The index of all elements after the new element increases by 1. The cursor must be a default cursor (that is, one that results from a constructor call with only a single argument). If the cursor is null, err_coll_null_cursor is signaled. If the cursor is invalid, err_coll_illegal_cursor is signaled. If the collection maintained internally by the cursor is not the same as the collection maintained by the dictionary, the err_coll_cursor_mismatch exception is signaled.

void insert_after(const void*, os_unsigned_int32);

Adds the specified void* to the collection for which the function was called. The new element is inserted after the position indicated by the os_unsigned_int32. The index of all elements after the new element increases by 1. If the index is not less than the collection’s cardinality, err_coll_out_of_range is signaled.

The behavior of insert_after() (both signatures) depends on the characteristics of the collection you are using:

• If the collection is not ordered, err_coll_not_supported is signaled.

Release 6.3 177

Page 178: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Collection

• If the collection disallows duplicates, and the specified void* is already present in the collection, the insertion is silently ignored.

• If the collection disallows nulls, and the specified void* is 0, err_coll_nulls is signaled.

• If the collection is an array, all elements after the inserted element are pushed down.

os_collection::insert_before()void insert_before(const void*, const os_cursor&);

Adds the specified void* to the collection for which the function was called. The new element is inserted immediately before the element at which the specified cursor is positioned. The index of all elements after the new element increases by 1. The cursor must be a default cursor (that is, one that results from a constructor call with only a single argument). If the cursor is null, err_coll_null_cursor is signaled. If the cursor is invalid, err_coll_illegal_cursor is signaled. If the collection maintained internally by the cursor is not the same as the collection maintained by the dictionary, the err_coll_cursor_mismatch exception is signaled.

void insert_before(const void*, os_unsigned_int32);

Adds the specified instance of void* to the collection for which the function was called. The new element is inserted immediately before the position indicated by the os_unsigned_int32. The index of all elements after the new element increases by 1. If the index is not less than the collection’s cardinality, err_coll_out_of_range is signaled.

The behavior of insert_before() (both signatures) depends on the characteristics of the collection you are using:

• If the collection is not ordered, err_coll_not_supported is signaled.

• If the collection disallows duplicates, and the specified void* is already present in the collection, the insertion is silently ignored.

• If the collection disallows nulls, and the specified void* is 0, err_coll_nulls is signaled.

• If the collection is an array, all elements after this element are pushed down.

os_collection::insert_first()void insert_first(const void*);

Adds the specified void* to the beginning of the collection for which the function was called. The index of all elements after the new element increases by 1.

The behavior of insert_first() depends on the characteristics of the collection you are using:

• If the collection is not ordered, err_coll_not_supported is signaled.

• If the collection disallows duplicates, and the specified void* is already present in the collection, err_coll_duplicates is signaled.

178 C++ Collections Guide and Reference

Page 179: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

• If the collection disallows nulls, and the specified void* is 0, the insertion is silently ignored.

• If the collection is an array, all elements after this element are pushed down.

os_collection::insert_last()void insert_last(const void*);

Adds the specified void* to the end of the collection for which the function was called.

The behavior of insert_last() depends on the characteristics of the collection you are using:

• If the collection is not ordered, err_coll_not_supported is signaled.

• If the collection disallows duplicates, and the specified void* is already present in the collection, err_coll_duplicates is signaled.

• If the collection disallows nulls, and the specified void* is 0, the insertion is silently ignored.

os_collection::LEPossible argument to os_coll_range constructors, signifying less than or equal to.

os_collection::LTPossible return value of the user-supplied rank() functions, and possible argument to os_coll_range constructors, signifying less than.

os_collection::maintain_orderPossible element of the bit-wise disjunction return value of the os_collection::get_behavior() members of os_collection, os_Collection, and their subtypes. Indicates that the collection maintains its elements in their order of insertion. This order is used as the default iteration order, as well as the relevant order for the members insert_after( ), insert_before( ), insert_first( ), insert_last( ), remove_at( ), remove_first( ), remove_last( ), retrieve_first( ), retrieve_last( ), and replace_at( ).

os_collection::multi_trans_add_index()static void multi_trans_add_index( os_reference c, const os_index_path & p, os_int32 index_options, os_segment * index_seg, os_segment * scratch_seg, os_unsigned_int32 num_per_trans );

Creates an index into the collection specified by the os_reference c, keyed by the specified os_index_path. This function adds the given index to the given collection by using multiple transactions. Until the index is fully added, it is unusable. That is, the index raises an exception if an attempt is made to insert or remove through other

Release 6.3 179

Page 180: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Collection

means. This implies that the collection is effectively write locked until all the transactions needed to add the index commit. This function should not be called in a transaction because it creates its own transactions.

Function arguments

• c is an os_reference to the collection to which to add the index.

• p is an os_index_path.

• index_options is the same as it is for add_index.

• index_seg is the segment in which to create the index (just like add_index).

• scratch_seg is a segment that is used internally and should be deleted when the function returns. It cannot be os_segment::get_transient_segment().

• num_per_trans is the number of collection elements to insert into the collection per transaction.

If there is no index at the key, then this function simply returns.

os_collection::multi_trans_drop_index()static void multi_trans_drop_index( os_reference c, const os_index_path & p, os_segment * scratch_seg, os_unsigned_int32 num_per_trans );

Destroys the index into the specified collection whose key is specified by p. This differs from os_collection::drop_index() only in that index maintenance is done using multiple transactions.

The index is unusable while it is being removed. The index raises an exception if an attempt is made to insert or remove it by other means. This means that the collection is effectively write locked until all the transactions needed to remove the index commit. This function should not be called in a transaction because it creates its own transactions.

Function arguments

• c is an os_reference to the collection from which the index should be removed.

• p is an os_index_path.

• scratch_seg is the segment that is used internally, which should be deleted when the function returns. It cannot be os_segment::get_transient_segment().

• num_per_trans is the number of collection elements to update per transaction.

If the multi_trans_drop_index() operation fails partway through, os_collection::drop_index() can be used. If there is no index at the key, then this function simply returns.

os_collection::NEPossible argument to os_coll_range constructors, signifying not equal to.

os_collection::only()void* only( ) const;

180 C++ Collections Guide and Reference

Page 181: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

Returns the only element of the specified collection. If the collection has more than one element, err_coll_not_singleton is signaled. If the collection is empty, 0 is returned.

os_collection::operator os_array&()operator os_array&( );

Returns an array with the same elements and behavior as the specified collection. An exception is signaled if the collection’s behavior is incompatible with the required behavior of arrays.

os_collection::operator const os_array&()operator const os_array&( ) const;

Returns a const array with the same elements and behavior as the specified collection. An exception is signaled if the collection’s behavior is incompatible with the required behavior of arrays.

os_collection::operator os_bag&()operator os_bag&( );

Returns a bag with the same elements and behavior as the specified collection. An exception is signaled if the collection’s behavior is incompatible with the required behavior of bags.

os_collection::operator const os_bag&()operator const os_bag&( ) const;

Returns a const bag with the same elements and behavior as the specified collection. An exception is signaled if the collection’s behavior is incompatible with the required behavior of bags.

os_collection::operator os_int32()operator os_int32( ) const;

Returns a nonzero os_int32 if the specified collection is not empty, and 0 otherwise.

os_collection::operator os_list&()operator os_list&( );

Returns a list with the same elements and behavior as the specified collection. An exception is signaled if the collection’s behavior is incompatible with the required behavior of lists.

os_collection::operator const os_list&()operator const os_list&( ) const;

Returns a const list with the same elements and behavior as the specified collection. An exception is signaled if the collection’s behavior is incompatible with the required behavior of lists.

Release 6.3 181

Page 182: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Collection

os_collection::operator os_set&()operator os_set&( );

Returns a set with the same elements and behavior as the specified collection. An exception is signaled if the collection’s behavior is incompatible with the required behavior of sets.

os_collection::operator const os_set&()operator const os_set&( ) const;

Returns a const set with the same elements and behavior as the specified collection. An exception is signaled if the collection’s behavior is incompatible with the required behavior of sets.

os_collection::operator ==()os_int32 operator ==(const os_collection &s) const;

Returns a nonzero value if and only if for each element in the this collection count(element) == s.count(element), and both collections have the same cardinality. Note that the comparison does not take order into account.

os_int32 operator ==(const void* s) const;

Returns a nonzero value if and only if the collection contains s and nothing else.

os_collection::operator !=()os_int32 operator !=(const os_collection &s) const;

Returns a nonzero value if and only if it is not the case both that (1) for each element in the this collection count(element) == s.count(element), and (2) both collections have the same cardinality. Note that the comparison does not take order into account.

os_int32 operator !=(const void* s) const;

Returns a nonzero value if and only if it is not the case that the collection contains s and nothing else.

os_collection::operator <()os_int32 operator <(const os_collection &s) const;

Returns a nonzero value if and only if for each element in the this collection count(element) <= s.count(element) and cardinality( ) < s.cardinality( ).

os_int32 operator <(const void* s) const;

Returns a nonzero value if and only if the specified collection is empty.

os_collection::operator <=()os_int32 operator <=(const os_collection &s) const;

182 C++ Collections Guide and Reference

Page 183: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

Returns a nonzero value if and only if for each element in the this collection count(element) <= s.count(element).

os_int32 operator <=(const void* s) const;

Returns a nonzero value if and only if the specified collection is empty or e is the only element in the collection.

os_collection::operator >()os_int32 operator >(const os_collection &s) const;

Returns a nonzero value if and only if for each element of s, count(element) >=s.count(element) and cardinality( ) > s.cardinality( ).

os_int32 operator >(const void* s) const;

Returns a nonzero value if and only if count(s) >= 1 and cardinality( ) > 1.

os_collection::operator >=()os_int32 operator >=(const os_collection &s) const;

Returns a nonzero value if and only if for each element of s, count(element) >=s.count(element).

os_int32 operator >=(const void* s) const;

Returns a nonzero value if and only if count(s) >= 1.

Assignment Operator SemanticsAssignment operator semantics are described for the following functions in terms of insert operations into the target collection. The actual implementation of the assignment might be different, while still maintaining the associated semantics.

os_collection::operator =()os_collection &operator =(const os_collection &s);

Copies the contents of the collection s into the target collection and returns the target collection. The copy is performed by effectively clearing the target, iterating over the source collection, and inserting each element into the target collection. The iteration is ordered if the source collection is ordered. The target collection semantics are enforced as usual during the insertion process.

os_collection &operator =(const void* e);

Clears the target collection, inserts the element e into the target collection, and returns the target collection.

os_collection::operator |=()os_collection &operator |=(const os_collection &s);

Inserts the elements contained in s into the target collection and returns the target collection.

os_collection &operator |=(const void* e);

Release 6.3 183

Page 184: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Collection

Inserts the element e into the target collection and returns the target collection.

os_collection::operator |()os_collection &operator |(const os_collection &s) const;

Copies the contents of this into a new collection, c, and then performs c |= s. The new collection, c, is then returned. If either operand allows duplicates or nulls, the result does. If both operands maintain order, the result does.

os_collection &operator |(const void *e) const;

Copies the contents of this into a new collection, c, and then performs c |= e. The new collection, c, is then returned. If this allows duplicates, maintains order, or allows nulls, the result does.

os_collection::operator &=()os_collection &operator &=(const os_collection &s);

For each element in the target collection, reduces the count of the element in the target to the minimum of the counts in the source and target collections. If the collection is ordered and contains duplicates, it does so by retaining the appropriate number of leading elements. It returns the target collection.

os_collection &operator &=(const void* e);

If e is present in the target, converts the target into a collection containing just the element e. Otherwise, it clears the target collection. It returns the target collection.

os_collection::operator &()os_collection &operator &(const os_collection &s) const;

Copies the contents of this into a new collection, c, and then performs c &= s. The new collection, c, is then returned. If either operand allows duplicates or nulls, the result does. If both operands maintain order, the result does.

os_collection &operator &(const void *e) const;

Copies the contents of this into a new collection, c, and then performs c &= e. The new collection, c, is then returned. If this allows duplicates, maintains order, or allows nulls, the result does.

os_collection::operator –=()os_collection &operator –=(const os_collection &s);

For each element in the collection s, removes s.count(e) occurrences of the element from the target collection. If the collection is ordered, it is the first s.count(e) elements that are removed. It returns the target collection.

os_collection &operator –=(const void* e);

Removes the element e from the target collection. If the collection is ordered, it is the first occurrence of the element that is removed from the target collection. It returns the target collection.

184 C++ Collections Guide and Reference

Page 185: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

os_collection::operator -()os_collection &operator -(const os_collection &s) const;

Copies the contents of this into a new collection, c, and then performs c –= s. The new collection, c, is then returned. If either operand allows duplicates or nulls, the result does. If both operands maintain order, the result does.

os_collection &operator -(const void *e) const;

Copies the contents of this into a new collection, c, and then performs c –= e. The new collection, c, is then returned. If this allows duplicates, maintains order, or allows nulls, the result does.

os_collection::optimized_list Possible argument to os_List and os_list constructors. This option should be used when the list is transient and is expected to hold persistent element pointers. This option will increase performance by creating a hard-pointer-based list.

You can also set this flag from the command line you use to compile your application. For more information, see Compiling for Collections Optimization on page 39.

os_collection::pick()void* pick( ) const;

Returns an arbitrary element of the specified collection. If the collection is empty, 0 is returned.

void* pick( const os_index_path &path, const os_coll_range &range) const;

Returns an element of the specified collection such that the result of applying path to the element is a value that satisfies range (see the class os_coll_range on page 199). If there is no such element, 0 is returned.

os_collection::query()os_collection &query( char *element_type_name, char *query_string, os_database *schema_database = 0, char *file_name = 0, os_unsigned_int32 line = 0, os_boolean dups = query_dont_preserve_duplicates) const;

Returns a reference to a heap-allocated collection containing those elements of this that satisfy the selection criterion expressed by the query_string. When you no longer need the resulting collection, you should reclaim its memory with ::operator delete( ) to avoid memory leaks. For information about deleting objects, see ::operator delete() in Chapter 3 of C++ A P I Reference.

Release 6.3 185

Page 186: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Collection

The argument element_type_name is the name of the element type of this. Names established through the use of typedef are not allowed.

Query strings The query_string argument indicates the query’s selection criterion. It can be either a C++ control expression or an expression that uses the pattern-matching operator (~~). For more information about query strings, see the following:

• C++ Control Expressions in Query Strings on page 84

• Matching Patterns in Query Strings on page 84

• Calling Functions in Query Strings on page 86

• Nested Queries on page 87

Within the selection criterion of query expressions, member names are implicitly qualified by this, just as are member names in function member bodies.

The schema_database is a database whose schema contains all the types mentioned in the selection criterion. This database provides the environment in which the query is analyzed and optimized. The database in which the collection resides is often appropriate.

ObjectStore uses file_name and line when reporting errors related to the query. You can set them to identify the location of the query’s source code.

If dups is the enumerator query_dont_preserve_duplicates, duplicate elements that satisfy the query condition are not included in the query result. If dups is the enumerator query_preserve_duplicates, duplicate elements that satisfy the query condition are included in the query result.

If the transient database is specified, the application’s schema (stored in the application schema database) is used to evaluate the query.

os_collection &query( const os_bound_query&, os_boolean dups = query_dont_preserve_duplicates) const;

Returns a reference to a heap-allocated collection containing those elements of this that satisfy the os_bound_query. If dups is the enumerator query_dont_preserve_duplicates, duplicate elements that satisfy the query condition are not included in the query result. If dups is the enumerator query_preserve_duplicates, duplicate elements that satisfy the query condition are included in the query result.

When you no longer need the resulting collection, you should reclaim its memory with ::operator delete( ) to avoid memory leaks. For information about deleting objects, see ::operator delete() in Chapter 3 of C++ A P I Reference.

Multibyte characters query support

The following form includes an argument of type os_str_conv::encode_type in order to support literal strings containing multibyte characters. Valid values for this argument are ASCII, UNICODE, UNICODE_BIG, UNICODE_LITTLE, UTF8, EUC_JP, JIS, or SJIS.

os_collection &query( char *element_type_name, char *query_string,

186 C++ Collections Guide and Reference

Page 187: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

os_str_conv::encode_type string_literal_char_encoding, os_database *schema_database = 0, char *file_name = 0, os_unsigned_int32 line = 0, os_boolean dups = query_dont_preserve_duplicates) const;

os_collection::query_pick()void *query_pick( char *element_type_name, char *query_string, os_database *schema_database = 0, char *file_name=0 os_unsigned_int32 line=0) const;

Returns an element of this that satisfies the selection criterion expressed by the query_string. If there is more than one such element, one is picked arbitrarily and returned. If no element satisfies the query or the collection is empty, 0 is returned.

The argument element_type_name is the name of the element type of this. Names established through the use of typedef are not allowed.

Query strings The query_string argument indicates the query’s selection criterion. It can be either a C++ control expression or an expression that uses the pattern-matching operator (~~). For more information about query strings, see the following:

• C++ Control Expressions in Query Strings on page 84

• Matching Patterns in Query Strings on page 84

• Calling Functions in Query Strings on page 86

• Nested Queries on page 87

Within the selection criterion of query expressions, member names are implicitly qualified by this, just as are member names in function member bodies.

The schema_database is a database whose schema contains all the types mentioned in the selection criterion. This database provides the environment in which the query is analyzed and optimized. The database in which the collection resides is often appropriate.

If the transient database is specified, the application’s schema (stored in the application schema database) is used to evaluate the query.

void *query_pick(const os_bound_query&) const;

ObjectStore uses file_name and line when reporting errors related to the query. You can set them to identify the location of the query’s source code.

Returns an element of this that satisfies the os_bound_query. If there is more than one such element, one is picked arbitrarily and returned. If no element satisfies the query or the collection is empty, 0 is returned.

Multibyte characters query support

The following form includes an argument of type os_str_conv::encode_type in order to support literal strings containing multibyte characters. Valid values for this

Release 6.3 187

Page 188: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Collection

argument are ASCII, UNICODE, UNICODE_BIG, UNICODE_LITTLE, UTF8, EUC_JP, JIS, or SJIS.

void *query_pick( char *element_type_name, char *query_string, os_str_conv::encode_type string_literal_char_encoding, os_database *schema_database = 0, char *file_name=0 os_unsigned_int32 line=0) const;

os_collection::remove()os_int32 remove(const void*);

Removes the specified void* from the collection for which the function was called, if the void* is an element of the collection. If the collection is ordered, the first occurrence of the specified void* is removed. Returns a nonzero os_int32 if an element was removed, and 0 otherwise. If the collection is an array, all elements after this element are pushed up.

os_collection::remove_at()void remove_at(const os_cursor&);

Removes from the specified collection the element at which the cursor is positioned. The position of all elements after the removed element decreases by 1. The cursor must be a default cursor (that is, one that results from a constructor call with only a single argument). If the cursor is not positioned at an element, err_coll_illegal_cursor is signaled. If the collection is not ordered, err_coll_not_supported is signaled. If the collection maintained internally by the cursor is not the same as the collection maintained by the dictionary, the err_coll_cursor_mismatch exception is signaled.

void remove_at(os_unsigned_int32 position);

Removes from the specified collection the element with the specified position. The position of all elements after the removed element decreases by 1. If the position is less than 0 or greater than cardinality minus 1, err_coll_out_of_range is signaled. If the collection is not ordered, err_coll_not_supported is signaled. If the collection is an array, all elements after this element are pushed up.

For both signatures,

• If the cursor is null, err_coll_null_cursor is signaled.

• If the cursor is invalid, err_coll_illegal_cursor is signaled.

os_collection::remove_first()os_int32 remove_first(const void*&);

Removes the first element from the specified collection, if the collection is not empty. Returns a nonzero os_int32 if the collection was not empty, and 0 otherwise; and modifies its argument to refer to the removed element. If the specified collection is not ordered, err_coll_not_supported is signaled.

188 C++ Collections Guide and Reference

Page 189: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

void* remove_first( );

Removes the first element from the specified collection; returns the removed element, or 0 if the collection was empty. Note that for collections that allow null elements, the significance of the return value can be ambiguous. The alternative overloading of remove_first( ), above, can be used to avoid the ambiguity. If the specified collection is not ordered, err_coll_not_supported is signaled. If the collection is an array, all elements after this element are pushed up.

os_collection::remove_last()os_int32 remove_last(const void*&);

Removes the last element from the specified collection, if the collection is not empty; returns a nonzero os_int32 if the collection was not empty, and modifies its argument to refer to the removed element. If the specified collection is not ordered, err_coll_not_supported is signaled.

void* remove_last( );

Removes the last element from the specified collection; returns the removed element, or 0 if the collection was empty. Note that for collections that allow null elements, the significance of the return value can be ambiguous. The alternative overloading of remove_last( ), above, can be used to avoid the ambiguity. If the specified collection is not ordered, err_coll_not_supported is signaled.

os_collection::replace_at()void* replace_at(const void*, const os_cursor&);

Returns the element at which the specified cursor is positioned, and replaces it with the specified void*. The cursor must be a default cursor (that is, one that results from a constructor call with only a single argument). If the cursor is null, err_coll_null_cursor is signaled. If the cursor is nonnull but not positioned at an element, err_coll_illegal_cursor is signaled. If the collection maintained internally by the cursor is not the same as the collection maintained by the dictionary, the err_coll_cursor_mismatch exception is signaled.

• If the cursor is null, err_coll_null_cursor is signaled.

• If the cursor is invalid, err_coll_illegal_cursor is signaled.

• If the collection is not ordered, err_coll_not_supported is signaled.

void* replace_at(const void*, os_unsigned_int32 position);

Returns the element with the specified position, and replaces it with the specified void*. If the position is not less than the collection’s cardinality, err_coll_out_of_range is signaled. If the collection is not ordered, err_coll_not_supported is signaled.

os_collection::retrieve()void* retrieve(const os_cursor&) const;

Returns the element at which the specified cursor is positioned. The cursor must be a default cursor (that is, one that results from a constructor call with only a single

Release 6.3 189

Page 190: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Collection

argument). If the cursor is null, err_coll_null_cursor is signaled. If the cursor is nonnull but not positioned at an element, err_coll_illegal_cursor is signaled. If the collection maintained internally by the cursor is not the same as the collection maintained by the dictionary, the err_coll_cursor_mismatch exception is signaled.

• If the cursor is null, err_coll_null_cursor is signaled.

• If the cursor is invalid, err_coll_illegal_cursor is signaled.

• If the collection is not ordered, err_coll_not_supported is signaled.

void* retrieve(os_unsigned_int32 position) const;

Returns the element with the specified position. If the position is not less than the collection’s cardinality, err_coll_out_of_range is signaled. If the collection is not ordered, err_coll_not_supported is signaled.

os_collection::retrieve_first()void* retrieve_first( ) const;

Returns the specified collection’s first element, or 0 if the collection is empty. For collections that contain zeros, see the following overloading of this function. If the collection is not ordered, err_coll_not_supported is signaled.

os_int32 retrieve_first(const void*&) const;

Returns 0 if the specified collection is empty; returns a nonzero os_int32 otherwise. Modifies the argument to refer to the collection’s first element. If the collection is not ordered, err_coll_not_supported is signaled.

os_collection::retrieve_last()void* retrieve_last( ) const;

Returns the specified collection’s last element, or 0 if the collection is empty. For collections that contain zeros, see the following overloading of this function. If the collection is not ordered, err_coll_not_supported is signaled.

os_int32 retrieve_last(const void*&) const;

Returns 0 if the specified collection is empty; returns a nonzero os_int32 otherwise. Modifies the argument to refer to the collection’s last element. If the collection is not ordered, err_coll_not_supported is signaled.

os_collection::set_query_memory_mode()static void set_query_memory_mode( os_query_memory_mode mode);

This function allows you to manage address space use during execution of a query.

os_query_memory_mode is an enumeration type whose enumerators are

• os_query_memory_mode_none — Use this mode when you know you are doing small or well-optimized queries and do not want to incur even a small amount of

190 C++ Collections Guide and Reference

Page 191: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

overhead. This mode is the default when the query is being executed in a nested transaction.

• os_query_memory_mode_normal — Marks the address space at the start of the query. If at any time during the query address space runs out, the query is restarted from the beginning using low memory mode.

Use this mode if your application typically does not run queries that use large amounts of address space, but you still want to safeguard against running out of address space. This mode is the default for queries being executed in nonnested transactions.

• os_query_memory_mode_low — Marks the address space at the start of the query. The query operation will put the results in a collection of references. It will catch the err_address_space_full exception inside the query processor. When the exception is signaled, the operation will release the address space and continue the query from where it left off. At the end of the query, a final release is performed.

Use this mode for running large queries that can use a great deal of address space. This mode requires some overhead, but it ensures that the query completes without restarting.

os_collection::trace_index_usage()static void trace_index_usage(os_boolean run_trace, const char * file_name = 0);

Generates index use information after ObjectStore processes each query statement. Set the run_trace agument to true to initiate tracing and to false to stop tracing. Set the file_name argument to write the index use information to a file of your choice. The default is to direct information to stdout.

If you specify a value for the file_name argument and you stop and restart tracing, ObjectStore overwrites any information in the specified file.

If you want to change the file to which you are directing index use information, you must stop and restart index use information generation. That is, you must call trace_index_usage() with run_trace set to false, and then call it again with run_trace set to true and a new value for file_name.

For information about the OS_COLLECTION_TRACE_INDEX_USAGE environment variable, which performs the same operation, and for an example of using this function, see Monitoring Index Use During Queries on page 99.

os_collection::update_cardinality()os_unsigned_int32 update_cardinality( );

Updates the value returned by os_collection::cardinality_estimate( ), by scanning the collection and computing the actual cardinality.

Before you add a new index to an os_ixonly_bc collection, call this function. If you do not, add_index( ) will work correctly, but less efficiently than if you do.

Release 6.3 191

Page 192: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_coll_query

For maintain_cardinality behavior, see os_Ixonly and os_ixonly on page 229. Also, os_Dictionary::os_Dictionary() on page 220 and os_Dictionary::os_Dictionary() on page 220.

os_coll_queryInstances of this class are query objects. For more information on query objects, see Preanalyzed Queries on page 92.

os_coll_query::create()static const os_coll_query &create( const char *element_type_name, const char *query_string, os_database *schema_database, os_boolean cache_query = 0, char *file_name = 0, os_unsigned_int32 line = 0);

Creates a query object, possibly with free variables and function references. The query object can be used to create an os_bound_query, which can then be executed with os_collection::query( ).

The argument element_type_name is the name of the element type of this. Names established through the use of typedef are not allowed.

The query_string is a C++ control expression indicating the query’s selection criterion. An element, e, satisfies the selection criterion if the control expression evaluates to a nonzero os_int32 (true) when e is bound to this. Only some kinds of function calls are allowed in the query string. See “Restrictions on member functions in query strings” on page 193 for more information.

The schema_database is a database whose schema contains all the types mentioned in the selection criterion. This database provides the environment in which the query is analyzed and optimized. The database in which the collection resides is often appropriate. If the transient database is specified, the application’s schema (stored in the application schema database) is used to evaluate the query.

If cache_query is a nonzero os_int32 (true), the query object is allocated in the schema segment of the database specified. If the database specified is the transient database, the object is allocated in the schema segment of the application schema database. If cache_query is zero (the default), the object is transiently allocated. The user is responsible for deleting the query object.

file_name, if supplied, should be the name of the source file containing the call to create( ). It is used only if an error is signaled during query analysis. Its sole purpose is to allow the resulting error message to make reference to the source file containing the code that caused an error.

line, if supplied, should be the number of the line in the source file on which the call to create( ) appears. It is used only if an error is signaled during query analysis. Its

192 C++ Collections Guide and Reference

Page 193: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

sole purpose is to allow the resulting error message to make reference to the source file line containing the code that caused an error.

Restrictions on member functions in query strings

Any string consisting of an os_int32-valued C++ expression is allowed in a query string, as long as

• Variables are also data members of the elements of the collection.

• For local variables (free references), you create an os_coll_query object.

• For global functions (free references), you create an os_coll_query object.

• There are no function calls, except calls to strcmp( ) or strcoll( ),

• There are no comparison operators for which the user might be required to define a corresponding rank/hash function.

• There are no calls to member functions that do not satisfy the restrictions listed below.

Within the selection criterion of query expressions, member names are implicitly qualified by this, just as are member names in function member bodies.

Restrictions Functions called in query strings are subject to certain restrictions:

• The return type can be a basic type (int, char, float, char*).

• If the function is a member function, it can also return a pointer or a reference to a class type.

• The function can take up to two arguments. The first argument must be a pointer. For member functions, this is the implied first argument.

• Global functions are free references and must be used in an os_coll_query object.

• Member functions can be used like data members.

To perform a query, ObjectStore sometimes (depending on what indexes are present) issues calls to member functions used in paths and queries. If such a member function allocates memory that it does not free (for example if it returns a pointer to newly allocated memory), memory leaks can result; ObjectStore does not free the space the function allocates. So member functions used in paths or queries should not allocate persistent memory or memory in the transient heap.

Member function in a query string

Applications that use a member function (not returning a reference) in a query string must do four things:

• Define an os_backptr-valued data member in the class that defines the member function. The data member must precede the member function declaration in the class definition.

• Call the macro os_query_function( ). This should be defined at file scope, for example, in the header file that contains the class that defines the member function. See os_query_function() on page 269 for more information.

• Call the macro os_query_function_body( ). This should be defined at file scope in a source file that is only compiled into the application once. See os_query_function_body() on page 270 for more information.

Release 6.3 193

Page 194: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_coll_query

• Call the macro OS_MARK_QUERY_FUNCTION( ). This macro should be invoked in the schema source file. See OS_TRANSIENT_DICTIONARY() on page 262 for more information.

Member function that returns a reference in a query string

For applications that use a member function that returns a reference in a query string, you must do the following four things:

• Define an os_backptr-valued data member in the class that defines the member function.

• Call the macro os_query_function_returning_ref( ). This should be defined at file scope, for example, in the header file that contains the class that defines the member function. See os_query_function_returning_ref() on page 271 for more information.

• Call the macro os_query_function_body_returning_ref( ). This should be defined at file scope in a source file that is only compiled into the application once. See os_query_function_body_returning_ref() on page 270 for more information.

• Call the macro OS_MARK_QUERY_FUNCTION( ). This macro should be invoked in the schema source file. See OS_TRANSIENT_DICTIONARY() on page 262 for more information.

To maintain indexes keyed by paths containing member function calls, use os_backptr::make_link( ) and os_backptr::break_link( ).

The query string can itself contain queries. A notation is defined to allow the user to conveniently specify such nested queries in a single call to a query member function.

A nested collection-valued query has the form

collection-expression [: os_int32-expression :]

where collection-expression is an expression of type os_Collection, and os_int32-expression is the selection criterion for the nested query.

A nested single-element query has the form

collection-expression [% os_int32-expression %]

where collection-expression and os_int32-expression are the same as for nested collection-valued queries. This form evaluates to one element of collection-expression. If there is more than one element that satisfies the nested query’s selection criterion, one of them is picked and returned.

A nested query returning a collection is converted to an os_int32 when appropriate, using os_collection::operator os_int32( ).

static const os_coll_query &create( const char *element_type_name, const char *query_string, os_segment *schema_database_segment, os_boolean cache_query = 0, char *file_name = 0, os_unsigned_int32 line = 0);

194 C++ Collections Guide and Reference

Page 195: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

Creates a query object, possibly with free variables and function references. The query object can be used to create an os_bound_query. The arguments are the same as those for the previous version of create( ), except schema_database_segment points to a segment in the schema database.

static const os_coll_query &create( const char *element_type_name, const char *query_string, const void *schema_database_object, os_boolean cache_query = 0, char *file_name = 0, os_unsigned_int32 line = 0);

Creates a query object, possibly with free variables and function references. The query object can be used to create an os_bound_query. The arguments are the same as those for the previous version of create( ), except schema_database_object points to an object in the schema database.

Multibyte characters query support

The following forms include an argument of type os_str_conv::encode_type in order to support literal strings containing multibyte characters. Valid values for this argument are ASCII, UNICODE, UNICODE_BIG, UNICODE_LITTLE, UTF8, EUC_JP, JIS, or SJIS.

:static const os_coll_query &create( const char *element_type_name, const char *query_string, os_str_conv::encode_type string_literal_char_encoding, os_database *schema_database, os_boolean cache_query = 0, char *file_name = 0, os_unsigned_int32 line = 0);

static const os_coll_query &create( const char *element_type_name, const char *query_string, os_str_conv::encode_type string_literal_char_encoding, os_segment *schema_database_segment, os_boolean cache_query = 0, char *file_name = 0, os_unsigned_int32 line = 0);

static const os_coll_query &create( const char *element_type_name, const char *query_string, os_str_conv::encode_type string_literal_char_encoding, const void *schema_database_object, os_boolean cache_query = 0, char *file_name = 0, os_unsigned_int32 line = 0);

os_coll_query::create_exists()static const os_coll_query &create_exists( const char *element_type_name, const char *query_string,

Release 6.3 195

Page 196: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_coll_query

os_database *schema_database, os_boolean cache_query = 0, char *file_name = 0, os_unsigned_int32 line = 0);

Creates an existential query object, possibly with free variables and function references. The query object can be used to create an os_bound_query, which can then be executed with os_collection::exists( ). The arguments are the same as those for os_coll_query::create() on page 192.

static const os_coll_query &create_exists( const char *element_type_name, const char *query_string, os_segment *schema_database_segment, os_boolean cache_query = 0, char *file_name = 0, os_unsigned_int32 line = 0);

Creates an existential query object, possibly with free variables and function references. The query object can be used to create an os_bound_query, which can then be executed with os_collection::exists( ). The arguments are the same as those for the previous version of create_exists( ), except the schema database is specified with a pointer to one of its segments.

static const os_coll_query &create_exists( const char *element_type_name, const char *query_string, const void *schema_database_object, os_boolean cache_query = 0, char *file_name = 0, os_unsigned_int32 line = 0);

Creates an existential query object, possibly with free variables and function references. The query object can be used to create an os_bound_query, which can then be executed with os_collection::exists( ). The arguments are the same as those for the previous version of create_exists( ), except the schema database is specified with a pointer to an object it contains.

Multibyte query support

The following forms include an argument of type os_str_conv::encode_type in order to support literal strings containing multibyte characters. Valid values for this argument are ASCII, UNICODE, UNICODE_BIG, UNICODE_LITTLE, UTF8, EUC_JP, JIS, or SJIS.

static const os_coll_query &create_exists( const char *element_type_name, const char *query_string, os_str_conv::encode_type string_literal_char_encoding, os_database *schema_database, os_boolean cache_query = 0, char *file_name = 0, os_unsigned_int32 line = 0);

static const os_coll_query &create_exists( const char *element_type_name,

196 C++ Collections Guide and Reference

Page 197: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

const char *query_string, os_str_conv::encode_type string_literal_char_encoding, os_segment *schema_database_segment, os_boolean cache_query = 0, char *file_name = 0, os_unsigned_int32 line = 0);

static const os_coll_query &create_exists( const char *element_type_name, const char *query_string, os_str_conv::encode_type string_literal_char_encoding, const void *schema_database_object, os_boolean cache_query = 0, char *file_name = 0, os_unsigned_int32 line = 0);

os_coll_query::create_pick()static const os_coll_query &create_pick( const char *element_type_name, const char *query_string, os_database *schema_database, os_boolean cache_query = 0, char *file_name = 0, os_unsigned_int32 line = 0);

Creates a single-element query object, possibly with free variables and function references. The query object can be used to create an os_bound_query, which can then be executed with os_collection::query_pick( ). The arguments are the same as those for os_coll_query::create( ).

static const os_coll_query &create_pick( const char *element_type_name, const char *query_string, os_segment *schema_database_segment, os_boolean cache_query = 0, char *file_name = 0, os_unsigned_int32 line = 0);

Creates a single-element query object, possibly with free variables and function references. The query object can be used to create an os_bound_query, which can then be executed with os_collection::query_pick( ). The arguments are the same as those for the previous version of create_pick( ), except the schema database is specified with a pointer to one of its segments.

static const os_coll_query &create_pick( const char *element_type_name, const char *query_string, const void *schema_database_object, os_boolean cache_query = 0, char *file_name = 0, os_unsigned_int32 line = 0);

Release 6.3 197

Page 198: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_coll_query

Creates a single-element query object, possibly with free variables and function references. The query object can be used to create an os_bound_query, which can then be executed with os_collection::query_pick( ). The arguments are the same as those for the previous version of create_pick( ), except the schema database is specified with a pointer to an object it contains.

Multibyte characters query support

The following forms include an argument of type os_str_conv::encode_type in order to support literal strings containing multibyte characters. Valid values for this argument are ASCII, UNICODE, UNICODE_BIG, UNICODE_LITTLE, UTF8, EUC_JP, JIS, or SJIS.

static const os_coll_query &create_pick( const char *element_type_name, const char *query_string, os_str_conv::encode_type string_literal_char_encoding, os_database *schema_database, os_boolean cache_query = 0, char *file_name = 0, os_unsigned_int32 line = 0);

static const os_coll_query &create_pick( const char *element_type_name, const char *query_string, os_str_conv::encode_type string_literal_char_encoding, os_segment *schema_database_segment, os_boolean cache_query = 0, char *file_name = 0, os_unsigned_int32 line = 0);

static const os_coll_query &create_pick( const char *element_type_name, const char *query_string, os_str_conv::encode_type string_literal_char_encoding, const void *schema_database_object, os_boolean cache_query = 0, char *file_name = 0, os_unsigned_int32 line = 0);

os_coll_query::destroy()static void destroy( const os_coll_query& target);

Destroys target. You must use this function to delete an instance of os_coll_query, not ::operator delete().

os_coll_query::get_element_type()const char *get_element_type( ) const;

Returns a string naming the element type supplied when the specified os_coll_query was created.

os_coll_query::get_query_string()const char *get_query_string( ) const;

198 C++ Collections Guide and Reference

Page 199: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

Returns the query string supplied when the specified os_coll_query was created.

os_coll_query::get_file_name()const char *get_file_name( ) const;

Returns the file name supplied when the specified os_coll_query was created.

os_coll_query::get_line_number()os_unsigned_int32 get_line_number( ) const;

Returns the line number supplied when the specified os_coll_query was created.

os_coll_rangeAn instance of this class can be used to represent a selection criterion for collection elements. Each os_coll_range is associated with either a particular value or range of values. Instances of os_coll_range can be used as arguments to the os_Cursor constructor to create a restricted cursor, or as arguments to os_Dictionary::pick( ).

os_coll_range::os_coll_range()The constructor for os_coll_range has many overloadings. Each overloading falls into one of the following two groups:

• Overloadings that specify a lower bound only or an upper bound only (for example, “all values less than or equal to 7”)

• Overloadings that specify both a lower and upper bound on a range of values (for example, “all values greater than 4 and less than or equal to 7”)

In each of these two groups, there is one overloading for each C++ fundamental type of value, and one for the type void*. To specify a range for any type of pointer value, use a void* overloading and pass a pointer to the value to serve as upper or lower bound.

Overloadings that specify a boundary only

os_coll_range( os_collection::restriction rel_op, unsigned char value);

os_coll_range( os_collection::restriction rel_op, short value);

os_coll_range( os_collection::restriction rel_op, os_signed_int8);

os_coll_range( os_collection::restriction rel_op, unsigned short value

Release 6.3 199

Page 200: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_coll_range

);

os_coll_range( os_collection::restriction rel_op, int value);

os_coll_range( os_collection::restriction rel_op, unsigned int value);

os_coll_range( os_collection::restriction rel_op, long value);

os_coll_range( os_collection::restriction rel_op, unsigned long value);

os_coll_range( os_collection::restriction rel_op, float value);

os_coll_range( os_collection::restriction rel_op, double value);

os_coll_range( os_collection::restriction rel_op, long double value);

os_coll_range( os_collection::restriction rel_op, const void* value);

os_coll_range( os_collection::restriction rel_op, os_coll_int64 value);

os_coll_range( os_collection::restriction rel_op, os_coll_uint64 value);

The previous overloadings construct an os_coll_range satisfied by all values that bear the relation rel_op to value. The argument rel_op should be coded as one of the following enumerators:

• os_collection::EQ (equal to)

• os_collection::NE (not equal to)

• os_collection::LT (less than)

• os_collection::LE (less than or equal to)

• os_collection::GT (greater than)

200 C++ Collections Guide and Reference

Page 201: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

• os_collection::GE (greater than or equal to)

Overloadings that specify a range

os_coll_range( os_collection::restriction rel_op1, unsigned char value1, os_collection::restriction rel_op2, unsigned char value2);

os_coll_range( os_collection::restriction rel_op1, int value1, os_collection::restriction rel_op2, int value2);

os_coll_range( os_collection::restriction rel_op1, unsigned int value1, os_collection::restriction rel_op2, unsigned int value2);

os_coll_range( os_collection::restriction rel_op1, short value1, os_collection::restriction rel_op2, short value2);

os_coll_range( os_collection::restriction rel_op1, unsigned short value1, os_collection::restriction rel_op2, unsigned short value2);

os_coll_range( os_collection::restriction rel_op1, os_signed_int8 value1, os_collection::restriction rel_op2, os_signed_int8 value2);

os_coll_range( os_collection::restriction rel_op1, long value1, os_collection::restriction rel_op2, long value2);

os_coll_range( os_collection::restriction rel_op1, unsigned long value1, os_collection::restriction rel_op2, unsigned long value2);

os_coll_range( os_collection::restriction rel_op1, float value1, os_collection::restriction rel_op2, float value2);

os_coll_range(

Release 6.3 201

Page 202: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_coll_range

os_collection::restriction rel_op1, double value1, os_collection::restriction rel_op2, double value2);

os_coll_range( os_collection::restriction rel_op1, long double value1, os_collection::restriction rel_op2, long double value2);

os_coll_range( os_collection::restriction rel_op1, const void *value1, os_collection::restriction rel_op2, const void *value2);

Each of the previous overloadings constructs an os_coll_range satisfied by all values that bear both the relation rel_op1 to value1 and the relation rel_op2 to value2. The arguments rel_op1 and rel_op2 should be one of the following enumerators:

When the value type is char*, the relational expression is defined in terms of strcmp( ). When the value type is a pointer to a user-defined class object, the user must supply rank/hash functions.

Examples The following example is satisfied by all ints greater than 4 and less than or equal to 7.

os_coll_range( os_collection::GT, 4, os_collection::LE, 7 )

Do not specify the null range, for example,

os_coll_range( os_collection::LT, 4, os_collection::GT, 7 )

Do not specify a discontinuous range, for example,

os_coll_range( os_collection::GT, 4, os_collection::NE, 7 )

If you do, the exception err_am is signaled, and the following message is issued:

No handler for exception:<maint-0023-0001>invalid restriction on unordered index (err_am)

Enumerator Meaning

os_collection::EQ Equal to

os_collection::NE Not equal to

os_collection::LT Less than

os_collection::LE Less than or equal to

os_collection::GT Greater than

os_collection::GE Greater than or equal to

202 C++ Collections Guide and Reference

Page 203: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

os_Cursortemplate <class E>class os_Cursor : public os_cursor

An instance of this class serves to record the state of an iteration by pointing to the current element of an associated collection. A cursor’s associated collection is specified when the cursor is created. The user can position the cursor in a relative fashion (using next( ) and previous( )) or in absolute fashion (using first( ) and last( )). The current element is retrieved using the positioning functions or retrieve( ).

You can allocate a cursor in either transient or persistent memory.

Every cursor has an associated ordering for the elements of its associated collection. This ordering can be the order in which elements appear in the collection (for ordered collections), an arbitrary order (for unordered collections), the order in which elements appear in persistent memory (see os_cursor::order_by_address on page 211), or an order based on an attribute or path of the elements. In the last case, the order is specified by an os_index_path specified when the cursor is created.

Upon creation of a persistent, ordered cursor for which the collection does not have an index on the given path, a write lock is acquired on segment 0 that effectively locks the entire database.

If a cursor is positioned at a collection’s last element (in the cursor’s associated ordering) and next( ) is performed on it, the cursor becomes null. Similarly, if a cursor is positioned at a collection’s first element (in the cursor’s associated ordering) and previous( ) is performed on it, the cursor becomes null. In other words, a cursor becomes null when it is either advanced past the last element or positioned before the first element. The function os_Cursor::more( ) returns a nonzero os_int32 (true) if the specified cursor is not null, and returns 0 (false) if it is null.

If a cursor is positioned at an element of a collection, and then that element is removed from the collection, the cursor becomes invalid. Repositioning such a cursor has undefined results unless the flag os_cursor::update_insensitive was passed to the cursor constructor when the cursor was created. The function os_Cursor::valid( ) returns nonzero (true) if the specified cursor is valid, and returns 0 (false) if it is invalid.

Release 6.3 203

Page 204: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Cursor

The states null and invalid are mutually exclusive.

The class os_Cursor is parameterized, with a parameter indicating the element type of the associated collection — if an attempt is made to associate a cursor with a collection whose element type does not match the cursor’s parameter, a compile-time error results. (For the nonparameterized version of this class, see os_cursor on page 209.) The parameter E occurs in the signatures of some of the functions described below. The parameter is used by the compiler to detect type errors.

os_Cursor::first()E first( );

Locates the specified cursor at the first element, in the cursor’s associated ordering, of the cursor’s associated collection. The first element is returned. If the collection is empty, the cursor is set to null and 0 is returned.

E first(os_address_space_marker&);

Navigates a collection as described for os_Cursor<E>::first() but uses the os_address_space_marker argument to manage address_space_full exceptions while retrieving the pointer to E. See Using os_address_space_marker Cursors on page 47.

os_Cursor::insert_after()void insert_after(const E p) const;

Inserts p into the cursor’s associated collection immediately after the cursor’s current location. If performed on a null cursor, err_coll_null_cursor is signaled. If the collection is an array, all elements after this one being inserted are pushed down.

os_Cursor::insert_before()void insert_before(const E p) const;

Inserts p into the cursor’s associated collection immediately before the cursor’s current location. If performed on a null cursor, err_coll_null_cursor is signaled.

null invalid valid

collection element

removed from collection

null

a cursor

Key:

validvalid

204 C++ Collections Guide and Reference

Page 205: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

If the collection is an array, all elements after this one being inserted are pushed down.

os_Cursor::last()E last( );

Locates the specified cursor at the last element, in the cursor’s associated ordering, of the cursor’s associated collection. The last element is returned. If the collection is empty, the cursor is set to null and 0 is returned.

E last(os_address_space_marker&);

Navigates a collection as described for os_Cursor<E>::last() but uses the os_address_space_marker argument to manage address_space_full exceptions while retrieving the pointer to E. See Using os_address_space_marker Cursors on page 47.

os_Cursor::more()os_int32 more( );

Returns a nonzero os_int32 (true) if the specified cursor is not null, that is, if the cursor is located at an element of the specified set or is invalid. The function returns 0 (false) otherwise.

os_Cursor::next()E next( );

Advances the specified cursor to the immediate next element of the cursor’s associated collection, according to the cursor’s associated ordering. The next element is returned. If there is no next element, or if the set is empty, the cursor is set to null and 0 is returned. If the cursor is null, a run-time error is signaled.

E next(os_address_space_marker&);

Navigates a collection as described for os_Cursor<E>::next() but uses the os_address_space_marker argument to manage address_space_full exceptions while retrieving the pointer to E. See Using os_address_space_marker Cursors on page 47.

os_Cursor::null()os_int32 null( );

Returns a nonzero os_int32 (true) if the specified cursor is null. The function returns 0 (false) if the cursor is located at an element of the specified set or is invalid. Inherited from os_cursor.

os_Cursor::os_Cursor()os_Cursor<E> ( const os_collection & coll, os_int32 os_cursor_enums = 0);

Release 6.3 205

Page 206: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Cursor

Constructs a cursor associated with coll. If the collection is not ordered, the cursor’s associated order is arbitrary, unless os_cursor_enums is os_cursor::order_by_address, in which case the cursor’s associated order is the order in which elements appear in persistent memory. If the collection is ordered and os_cursor_enums is 0, the cursor’s associated order is the order in which elements appear in the collection.

If you update a collection while traversing it without using an update-insensitive cursor, the results of the traversal are undefined.

If os_cursor_enums is os_cursor::order_by_address, the cursor’s associated order is the order in which elements appear in persistent memory. If you dereference each collection element as you retrieve it, and the objects pointed to by collection elements do not all fit in the client cache at once, this order can dramatically reduce paging overhead. An order-by-address cursor is update insensitive.

If os_cursor_enums is os_cursor::update_insensitive, the collection supports updates to it during traversal. The traversal visits exactly the elements of the collection at the time the cursor was bound. No insertions or removals performed during the traversal are reflected in the traversal.

If os_cursor_enums is 0, the default, the cursor does not support updates to its associated collection during iteration.

os_Cursor<E>( const os_Collection<E> & coll, _Rank_fcn rfcn, os_int32 os_cursor_enums = 0);

An _Rank_fcn is a rank function for the element type of coll. Iteration using that cursor follows the order determined by the specified rank function. The rank function must be registered with the os_index_key macro. Rank-function-based cursors are update insensitive.

os_Cursor<E> ( const os_Collection<E> & coll, const os_index_path &path, os_int32 os_cursor_enums = 0);

Constructs a cursor associated with coll. The path specifies the cursor’s associated order. If the endpoint of the os_index_path is a user class, a rank function must be defined and registered. If os_cursor_enums is 0, the cursor does not support updates to its associated collection during iteration.

os_Cursor<E> ( const os_Collection<E> & coll, const char *typename, os_int32 os_cursor_enums = 0);

typename is the name of the element type. Iteration using that cursor follows the order determined by the element type’s rank function. The rank function must be registered with the os_index_key macro. Rank-function-based cursors are update insensitive.

206 C++ Collections Guide and Reference

Page 207: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

os_Cursor<E> ( const os_Dictionary & coll, const os_coll_range &range, os_int32 os_cursor_enums = 0);

Constructs a cursor that can be used to traverse ordered dictionaries. A traversal with this cursor visits only those collection elements whose key satisfies range. The order of iteration is all the elements at a key value, followed by all the elements at the next key value, and so on. The order of the elements at each key value is arbitrary. Note that, for this overloading of os_Cursor(), if os_cursor::update_insensitive is specified for the os_cursor_enums argument, it is ignored.

os_Cursor<E> ( const os_Collection<E> & coll, const os_index_path &path, const os_coll_range &range, os_int32 os_cursor_enums = 0);

A traversal with this cursor visits only those collection elements that satisfy the cursor’s restriction. An element satisfies the cursor’s restriction if the result of applying path to the element satisfies range. The order of iteration is determined by os_index_path based on the index.

If the index is not present, a transient internal index is created. If this cursor is created persistently and no index exists, an exception occurs. An index is required when you are creating a persistent restricted cursor.

If the index is present, the iteration order is based upon the existing index that relates to the given os_index_path.

Note that, for this overloading of os_Cursor(), if os_cursor::update_insensitive is specified for the os_cursor_enums argument, it is ignored.

os_Cursor::owner()const os_collection *owner( ) const;

Returns a pointer to the specified cursor’s associated collection. Inherited from os_cursor.

os_collection *owner( );

Returns a pointer to the specified cursor’s associated collection. Inherited from os_cursor.

os_Cursor::previous()E previous( );

Moves the specified cursor to the immediate previous element of the cursor’s associated collection, according to the cursor’s associated ordering. If there is no previous element, or if the collection is empty, the cursor is set to null and 0 is returned. If the cursor is null, a run-time error is signaled.

E previous(os_address_space_marker&);

Release 6.3 207

Page 208: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Cursor

Navigates a collection as described for os_Cursor<E>::previous() but uses the os_address_space_marker argument to manage address_space_full exceptions while retrieving the pointer to E. See Using os_address_space_marker Cursors on page 47.

os_Cursor::rebind()void rebind(const os_Collection<E>&);

Associates the specified cursor with the specified collection, positioning the cursor at the collection’s first element. If the collection is empty, the cursor is not valid.

void rebind(const os_collection &, _Rank_Fcn);

Associates the specified cursor with the specified collection, positioning the cursor at the collection’s first element according to the ordering provided by the rank function. If the collection is empty, the cursor is not valid.

os_Cursor::remove_at()void remove_at( ) const;

Removes that element of the cursor’s associated collection at which the specified cursor is currently located. If performed on a null or invalid cursor, err_coll_null_cursor is signaled. If the collection is an array, all elements after this one are pushed up.

os_Cursor::resolve_all() void resolve_all();

This function enables you to hold a default cursor across transaction boundaries. You must call this function when starting a new transaction in order to reestablish the internal os_Cursor pointers.

Only default cursors can be held across transactions. For more information, see os_Cursor::os_Cursor() on page 205.

os_Cursor::retrieve()E retrieve( );

Returns the element of the specified cursor’s associated collection at which the specified cursor is currently located. A run-time error is signaled if the cursor is not located at an element of the set.

E retrieve(os_address_space_marker&);

Returns the element of the specified cursor’s associated collection at which the specified cursor is currently located. A run-time error is signaled if the cursor is not located at an element of the set. The function uses the os_address_space_marker argument to manage address_space_full exceptions while retrieving the pointer to E. See Using os_address_space_marker Cursors on page 47.

208 C++ Collections Guide and Reference

Page 209: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

os_Cursor::valid()os_int32 valid( );

Returns a nonzero os_int32 (true) if the specified cursor is null or is located at an element of the associated collection. The function returns 0 (false) if the cursor was located at an element that has been removed. Inherited from os_cursor.

os_Cursor::~os_Cursor()void ~os_Cursor( );

Breaks the association between the cursor and its associated collection.

os_cursorAn instance of this class serves to record the state of an iteration by pointing to the current element of an associated collection. A cursor’s associated collection is specified when the cursor is created. The user can position the cursor in a relative fashion (using next( ) and previous( )) or in absolute fashion (using first( ) and last( )). The current element is retrieved using the positioning functions or retrieve( ).

You can allocate a cursor in either transient or persistent memory.

Every cursor has an associated ordering for the elements of its associated collection. This ordering can be the order in which elements appear in the collection (for ordered collections), an arbitrary order (for unordered collections), the order in which elements appear in persistent memory (see os_cursor::order_by_address on page 211), or an order based on an attribute or path of the elements. In the last case, the order is specified by an os_index_path supplied when the cursor is created.

Upon creation of a persistent, ordered cursor for which the collection does not have an index on the given path, a write lock is acquired on segment 0 that effectively locks the entire database.

If a cursor is positioned at a collection’s last element (in the cursor’s associated ordering) and next( ) is performed on it, the cursor becomes null. Similarly, if a cursor is positioned at a collection’s first element (in the cursor’s associated ordering) and previous( ) is performed on it, the cursor becomes null. In other words, a cursor becomes null when it is either advanced past the last element or positioned before the first element. The function os_cursor::more( ) returns a nonzero os_int32 (true) if the specified cursor is not null, and returns 0 (false) if it is null.

If a cursor is positioned at an element of a collection, and then that element is removed from the collection, the cursor becomes invalid. Repositioning such a cursor has undefined results. The function os_cursor::valid( ) returns nonzero (true) if the specified cursor is valid, and returns 0 (false) if it is invalid.

Release 6.3 209

Page 210: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_cursor

Valid and invalid cursors

The states null and invalid are mutually exclusive.

os_cursor::first()void* first( );

Locates the specified cursor at the first element of the cursor’s associated collection, according to the cursor’s associated ordering. The first element is returned. If the collection is empty, the cursor is set to null and 0 is returned.

void* first(os_address_space_marker&);

Navigates a collection as described for os_cursor::first() but uses the os_address_space_marker argument to manage address_space_full exceptions while retrieving the element pointer. See Using os_address_space_marker Cursors on page 47.

os_cursor::insert_after()void insert_after(const void *p) const;

Inserts p into the cursor’s associated collection immediately after the cursor’s current location. If performed on a null cursor, err_coll_null_cursor is signaled. If the collection is an array, all elements after this one being inserted are pushed down.

os_cursor::insert_before()void insert_before(const void *p) const;

Inserts p into the cursor’s associated collection immediately before the cursor’s current location. If performed on a null cursor, err_coll_null_cursor is signaled. If the collection is an array, all elements after this element are pushed down.

os_cursor::last()void* last( );

Locates the specified cursor at the last element of the cursor’s associated collection, according to the cursor’s associated ordering. The last element is returned. If the collection is empty, the cursor is set to null and 0 is returned.

null invalid valid

collection element

removed from collection

null

a cursor

Key:

validvalid

210 C++ Collections Guide and Reference

Page 211: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

void* last(os_address_space_marker&);

Navigates a collection as described for os_cursor::last() but uses the os_address_space_marker argument to manage address_space_full exceptions while retrieving the element pointer. See Using os_address_space_marker Cursors on page 47.

os_cursor::more()os_int32 more( );

Returns a nonzero os_int32 (true) if the specified cursor is not null, that is, if the cursor is located at an element of the specified set or is invalid. The function returns 0 (false) otherwise.

os_cursor::next()void* next( );

Advances the specified cursor to the immediate next element of the cursor’s associated collection, according to the cursor’s associated ordering. The next element is returned. If there is no next element, or if the set is empty, the cursor is set to null and 0 is returned. If the cursor is null, a run-time error is signaled.

void* next(os_address_space_marker&);

Navigates a collection as described for os_cursor::next() but uses the os_address_space_marker argument to manage address_space_full exceptions while retrieving the element pointer. See Using os_address_space_marker Cursors on page 47.

os_cursor::null()os_int32 null( );

Returns a nonzero os_int32 (true) if the specified cursor is null. The function returns 0 (false) if the cursor is located at an element of the specified set or is invalid.

os_cursor::order_by_addressPossible argument to os_cursor or os_Cursor constructor, indicating that the cursor’s associated ordering is the order in which elements appear in persistent memory.

If you dereference each collection element as you retrieve it, and the objects pointed to by collection elements do not all fit in the client cache at once, this order can dramatically reduce paging overhead. An order-by-address cursor is update insensitive.

Because the ordering is in address order, the handling of address_space_full exceptions is not possible when creating and sorting the array of pointers. If you receive address_space_full exceptions when creating an order_by_address cursor, use an os_cursor::order_by_DSCO cursor instead. See Address Order Traversal on page 68.

Release 6.3 211

Page 212: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_cursor

os_cursor::order_by_DSCOPossible argument to os_cursor or os_Cursor constructor, where order_by_DSCO should be used instead of os_cursor::order_by_adress to avoid address_space_full exceptions when creating the cursor. The ordering for order_by_DSCO is in address space order unless an address_space_full exception is hit at which time the sorting is done in DSCO order (database/segment/cluster/offset order).

An order_by_DSCO cursor is useful if you dereference each collection element as you retrieve it because the order can dramatically reduce paging overhead. When used for this purpose there is no difference between order_by_DSCO and order_by_address. An order_by_DSCO cursor is update insensitive. See Address Order Traversal on page 68.

os_cursor::os_cursor()os_cursor( const os_collection & coll, os_int32 os_cursor_enums = 0);

Constructs a cursor associated with coll. If the collection is not ordered, the cursor’s associated order is arbitrary, unless os_cursor_enums is os_cursor::order_by_address, in which case the cursor’s associated order is the order in which elements appear in persistent memory. If the collection is ordered and os_cursor_enums is 0, the cursor’s associated order is the order in which elements appear in the collection.

If you update a collection while traversing it without using an update-insensitive cursor, the results of the traversal are undefined.

If os_cursor_enums is os_cursor::order_by_address, the cursor’s associated order is the order in which elements appear in persistent memory. If you dereference each collection element as you retrieve it, and the objects pointed to by collection elements do not all fit in the client cache at once, this order can dramatically reduce paging overhead. An order-by-address cursor is update insensitive.

If os_cursor_enums is os_cursor::update_insensitive, the collection supports updates to it during traversal. The traversal visits exactly the elements of the collection at the time the cursor was bound. No insertions or removals performed during the traversal are reflected in the traversal.

If os_cursor_enums is 0, the cursor does not support updates to its associated collection during iteration.

os_cursor( const os_collection & coll, const os_index_path &path, os_int32 os_cursor_enums = 0);

Constructs a cursor associated with coll. The path specifies the cursor’s associated order. If the endpoint of the os_index_path is a user class, a rank function must be defined and registered.

The cursor does not support updates to its associated collection during iteration.

212 C++ Collections Guide and Reference

Page 213: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

Upon creation of the first persistent, ordered, or restricted cursor with a particular key type (where the key type is the specified path’s terminal type), ObjectStore performs schema modification, provided the collection does not have an index on the specified path.

os_cursor( const os_collection & coll, const char *typename, os_int32 os_cursor_enums = 0);

Constructs a cursor associated with coll. The typename argument is the name of an element type. Iteration using this cursor follows the order determined by the element type’s rank function. The rank function must be registered with the os_index_key macro. Rank-function-based cursors are update insensitive.

os_cursor( const os_collection & coll, _Rank_fcn rnk, os_int32 os_cursor_enums = 0);

Constructs a cursor associated with coll. An _Rank_fcn is a rank function for the element type of coll. Iteration using this cursor follows the order determined by the specified rank function. The rank function must be registered with the os_index_key macro. Rank-function-based cursors are update insensitive.

os_cursor( const os_collection & coll, const os_index_path &path, const os_coll_range &range, os_int32 os_cursor_enums = 0);

A traversal with this cursor visits only those collection elements that satisfy the cursor’s restriction. An element satisfies the cursor’s restriction if the result of applying path to the element satisfies range. The order of iteration is determined by os_index_path based on the index.

If the index is not present, a transient internal index is created. If this cursor is created persistently and no index exists, an exception occurs. An index is required when you are creating a persistent restricted cursor.

If the index is present, the iteration order is based upon the existing index that relates to the given os_index_path.

Upon creation of a persistent, ordered cursor for which the collection does not have an index on the given path, ObjectStore performs schema modification, which effectively write locks the entire database.

Note that, for this overloading of os_cursor(), if os_cursor::update_insensitive is specified for the os_cursor_enums argument, it is ignored.

os_cursor( const os_dictionary & coll, const os_coll_range &range, os_int32 os_cursor_enums = 0

Release 6.3 213

Page 214: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_cursor

);

Constructs a cursor that can be used to traverse ordered dictionaries. A traversal with this cursor visits only those collection elements whose key satisfies range. The order of iteration is all the elements at a key value, followed by all the elements at the next key value, and so on. The order of the elements at each key value is arbitrary. Note that, for this overloading of os_cursor(), if os_cursor::update_insensitive is specified for the os_cursor_enums argument, it is ignored.

Copying a cursor

os_cursor (const os_cursor &c);

Constructs a new cursor by copying the contents of the cursor specified by c.

os_cursor::owner()const os_collection *owner( ) const;

Returns a pointer to the specified cursor’s associated collection.

os_collection *owner( );

Returns a pointer to the specified cursor’s associated collection.

os_cursor::previous()void* previous( );

Moves the specified cursor to the immediate previous element of the cursor’s associated collection, according to the cursor’s associated ordering. If there is no previous element, or if the collection is empty, the cursor is set to null and 0 is returned. If the cursor is null, a run-time error is signaled.

void* previous(os_address_space_marker&);

Navigates a collection as described for os_cursor::previous() but uses the os_address_space_marker argument to manage address_space_full exceptions while retrieving the element pointer. See Using os_address_space_marker Cursors on page 47.

os_cursor::rebind()void rebind(const os_collection&);

Associates the specified cursor with the specified collection, positioning the cursor at the collection’s first element. If the collection is empty, the cursor is not valid.

void rebind(const os_collection&, _Rank_fcn);

Associates the specified cursor with the specified collection, positioning the cursor at the collection’s first element according to the rank function. If the collection is empty, the cursor is not valid.

os_cursor::remove_at()void remove_at( ) const;

Removes that element of the cursor’s associated collection at which the specified cursor is currently located. If performed on a null or invalid cursor, err_coll_null_

214 C++ Collections Guide and Reference

Page 215: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

cursor is signaled. If the collection is an array, all elements after this element are pushed up.

os_cursor::resolve_all() void os_cursor::resolve_all();

This function enables you to hold a default cursor across transaction boundaries. You must call this function when starting a new transaction in order to reestablish the internal os_cursor pointers.

Only default cursors can be held across transactions. For more information, see os_cursor::os_cursor() on page 212.

os_cursor::retrieve()void* retrieve( );

Returns the element of the specified cursor’s associated collection at which the specified cursor is currently located. A run-time error is signaled if the cursor is not located at an element of the collection.

void* retrieve(os_address_space_marker&);

Returns the element of the specified cursor’s associated collection at which the specified cursor is currently located. A run-time error is signaled if the cursor is not located at an element of the set. The function uses the os_address_space_marker argument to manage address_space_full exceptions while retrieving the element pointer. See Using os_address_space_marker Cursors on page 47.

os_cursor::update_insensitivePossible argument to os_cursor or os_Cursor constructor, indicating that the collection supports updates during traversal of the cursor. The traversal visits exactly the elements of the collection at the time the cursor was bound.

os_cursor::valid()os_int32 valid( );

Returns a nonzero os_int32 (true) if the specified cursor is null or is located at an element of the associated collection. The function returns 0 (false) if the cursor was located at an element that has been removed.

os_cursor::~os_cursor()void ~os_cursor( );

Breaks the association between the cursor and its associated collection.

os_Dictionarytemplate <class K, class E>class os_Dictionary<K, E> : public os_Collection<E>

Release 6.3 215

Page 216: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Dictionary

A dictionary is a collection that can be either ordered or unordered, allows duplicate elements, and associates a key with each element. The key can be a value of any C++ fundamental type or user-defined class. If the key is a pointer, it must be a void*. When you insert an element into a dictionary, you specify the key along with the element. You can retrieve an element with a given key or retrieve those elements whose keys fall within a given range. os_Dictionary inherits from os_collection.

Dictionaries are always implemented as B-trees or hash tables, so look-up of elements based on their keys is efficient.

If you use persistent dictionaries, you must call the macro OS_MARK_DICTIONARY( ) in your source file for each key-type/element-type pair that you use. If you are using only transient dictionaries, call the macro OS_TRANSIENT_DICTIONARY() in your source file.

The element type of any instance of os_Dictionary must be a pointer type.

Required attributes

Requirements for classes used as keys are listed below.

• The class must have a constructor that takes no arguments, and the destructor must be able to handle a class that is constructed with the no-argument constructor.

• The class must have an operator=() defined.

• The class must have a destructor, and the destructor must delete any storage allocated either by the no-argument constructor or by operator=. The destructor must also set any pointers in the object to 0. The destructor should also be prepared to handle the deletion of the object where all the data is zeroed out.

• You must define and register (using os_index_key) rank/hash functions for the class type.

These requirements apply only to default unordered dictionaries. For dictionaries that are ordered, the key is initialized using memcpy().

For integer keys, specify one of the following as the key type:

• os_int32 (a signed 32-bit integer)

• os_unsigned_int32 (an unsigned 32-bit integer)

• os_int16 (a signed 16-bit integer)

• os_unsigned_int16 (an unsigned 16-bit integer)

Use the type void* for pointer keys other than char* keys.

For char[ ] keys, use the parameterized type os_char_array<S>, where the actual parameter is an integer literal indicating the size of the array in bytes.

The key type char* is treated as a class whose rank and hash functions are defined in terms of strcmp( ) or strcoll( ). For example:

a_dictionary.pick("Smith")

returns an element of a_dictionary whose key is the string “Smith” (that is, whose key, k, is such that strcmp(k, "Smith") is 0).

216 C++ Collections Guide and Reference

Page 217: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

If a dictionary’s key type is char* and it is unordered, the dictionary makes its own copies of the character array upon insertion. If the key type is char* and the dictionary has the behavior maintain_key_order, it points to the string rather than makes a copy of it. If the dictionary does not allow duplicate keys, you can significantly improve performance by using the type os_char_star_nocopy as the key type. With this key type, the dictionary copies the pointer to the array and not the array itself. You can freely pass char*s to this type.

Note that you cannot use os_char_star_nocopy with dictionaries that allow duplicate keys.

Required header files

Any program using dictionaries must include the header files <ostore/ostore.hh> followed by <ostore/coll.hh>. In addition, your program will require the inclusion of <ostore/coll/dict_pt.hh> or <ostore/coll/dict_pt.cc>.

If your program instantiates a template, include dict_pt.cc at the point where you instantiate the template. If you are using the template, but not instantiating it, include dict_pt.hh. Since dict_pt.cc includes dict_pt.hh, you do not need both. You have to include dict_pt.cc because it contains the bodies of the functions declared in dict_pt.hh.

Tables of member functions and enumerators

The first of the following tables lists the member functions that can be performed on instances of os_Dictionary. The second table lists the enumerators inherited by os_Dictionary from os_collection. Many functions are also inherited by os_Dictionary from os_Collection or os_collection. The full explanation of each inherited function or enumerator appears in the entry for the class from which it is inherited. The full explanation of each function defined by os_Dictionary appears in this entry, after the tables. In each case, the Defined By column gives the class whose entry contains the full explanation.

Name Arguments Returns Defined By

add_index ( const os_index_path&, os_int32 options, os_database* = 0 )

( const os_index_path&, os_int32 options, os_segment* = 0 )

( const os_index_path&, os_int32 options, os_cluster* = 0 )

( const os_index_path&, os_database* = 0 )

( const os_index_path&, os_segment* = 0 )

( const os_index_path&, os_cluster* = 0 )

void

void

void

void

void

void

os_collection

cardinality ( ) const os_unsigned_int32

os_collection

clear ( ) void os_collection

Release 6.3 217

Page 218: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Dictionary

contains ( const K &key_ref, const E element ) const

( const K *key_ptr, const E element ) const

os_int32

os_int32

os_Dictionary

count ( const E ) const os_int32 os_Collection

count_values ( const K &key_ref ) const

( const K * key_ptr ) const

os_unsigned_int32

os_unsigned_int32

os_Dictionary

default_behavior (static)

( ) os_unsigned_int32

os_Dictionary

drop_index ( const os_index_path& ) void os_collection

empty ( ) os_int32 os_collection

exists ( char *element_type_name, char *query_string, os_database *schema_database = 0, char *filename, os_unsigned_int32 line ) const

( const os_bound_query& ) const

os_int32

os_int32

os_collection

get_behavior ( ) const os_unsigned_int32

os_collection

has_index ( const os_index_path&, os_int32 index_options ) const

os_int32 os_collection

insert ( const K &key_ref, const E element )

( const K *key_ptr, const E element )

void

void

os_Dictionary

only ( ) const E os_Collection

os_Dictionary ( os_unsigned_int32 expected_card = 10, os_unsigned_int32 behavior_enums = 0 )

os_Dictionary

pick ( const os_coll_range& ) const

( const K &key_ref ) const

( const K *key_ptr ) const

( ) const

E

E

E

E

os_Dictionary

Name Arguments Returns Defined By

218 C++ Collections Guide and Reference

Page 219: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

os_Dictionary enumerators

The following table lists enumerators for the os_Dictionary class.

query ( char *element_type_name, char *query_string, os_database *schema_database = 0, char *filename = 0, os_unsigned_int32 line = 0, os_boolean dups ) const

( const os_bound_query&, os_boolean dups ) const

os_Collection<E>&

os_Collection<E>&

os_Collection

query_pick ( char *element_type_name, char *query_string, os_database *schema_database = 0, char* filename = 0, os_unsigned_int32 line = 0 ) const

( const os_bound_query& ) const

E

E

os_Collection

remove ( const K &key_ref, const E element )

( const K *key_ptr, const E element )

( const E element)

void

void

os_int32

os_Dictionary

remove_value ( const K &key_ref, const E os_unsigned_int32 n = 1 )

( const K *key_ptr, os_unsigned_int32 n = 1 )

E

E

os_Dictionary

retrieve ( const os_cursor& ) const E os_Dictionary

retrieve_key ( const os_cursor& ) K* or K os_Dictionary

Name Arguments Returns Defined By

Name Inherited From

allow_duplicates os_collection

allow_nulls os_collection

EQ os_collection

GT os_collection

LT os_collection

maintain_cardinality os_dictionary

maintain_key_order os_dictionary

maintain_order os_collection

no_dup_keys os_dictionary

signal_dup_keys os_dictionary

Release 6.3 219

Page 220: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Dictionary

os_Dictionary::contains()os_boolean contains(const K &key_ref, const E element) const;

Returns nonzero (true) if this contains an entry with the specified element and the key referred to by key_ref. If there is no such entry, 0 (false) is returned. This overloading of contains( ) differs from the next overloading only in that the key is specified with a reference instead of a pointer.

os_boolean contains(const K *key_ptr, const E element) const;

Returns nonzero (true) if this contains an entry with the specified element and the key pointed to by key_ptr. If there is no such entry, 0 (false) is returned. This overloading of contains( ) differs from the previous overloading only in that the key is specified with a pointer instead of a reference.

os_Dictionary::count_values()os_unsigned_int32 count_values(const K &key_ref) const;

Returns the number of entries in this with the key referred to by key_ref. This overloading of count_values( ) differs from the next overloading only in that the key is specified with a reference instead of a pointer.

os_unsigned_int32 count_values(const K *key_ptr) const;

Returns the number of entries in this with the key pointed to by key_ptr. This overloading of count_values( ) differs from the previous overloading only in that the key is specified with a pointer instead of a reference.

os_Dictionary::insert()void insert(const K &key_ref, const E element);

Inserts the specified element with the key referred to by key_ref. This overloading of insert( ) differs from the next overloading only in that the key is specified with a reference instead of a pointer.

Each insertion increases the collection’s cardinality by 1 and increases by 1 the count (or number of occurrences) of the inserted element in the collection, unless the dictionary already contains an entry that matches both the key and the element (in which case the insertion is silently ignored).

If you insert a null pointer (0), the exception err_coll_nulls is signaled.

For dictionaries with signal_dup_keys behavior, if an attempt is made to insert something with a key that already exists, err_am_dup_key is signaled.

void insert(const K *key_ptr, const E element);

Inserts the specified element with the key pointed to by key_ptr. This overloading of insert( ) differs from the previous overloading only in that the key is specified with a pointer instead of a reference.

os_Dictionary::os_Dictionary()os_Dictionary(

220 C++ Collections Guide and Reference

Page 221: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

os_unsigned_int32 expected_cardinality = 10, os_unsigned_int32 behavior_enums = 0);

Creates a new dictionary. The following paragraphs describe the arguments.

Presizing cardinality

By default, dictionaries are presized with an internal structure suitable for cardinality 10. If you want a new dictionary presized for a different cardinality, specify the expected_cardinality argument. Specifying this argument allows the user to incur the cost of growing the internal structure at creation time rather than during the life of the dictionary.

Dictionary properties

Every dictionary has the following properties:

• Duplicate elements are allowed.

• Null pointers cannot be inserted.

• There is no guarantee that an element inserted or removed during a traversal will be visited later in the same traversal.

• Performing pick() on an empty result of querying the dictionary returns 0.

By default, a new dictionary also has the following properties:

• Its elements have no intrinsic order.

• Duplicate keys are allowed; that is, two or more elements can have the same key.

• Range look-ups are not supported; that is, key order is not maintained.

You can enable or disable these last three properties in new dictionaries. To do so, specify the behavior_enums argument with a bit pattern that indicates the collection’s properties. The bit pattern is obtained by forming the bit-wise disjunction (using the bit-wise OR operator) of the following enumerators:

• os_Dictionary::signal_dup_keys: Duplicate keys are not allowed; err_coll_duplicate_key is signaled if an attempt is made to establish two or more elements with the same key.

• os_Dictionary::maintain_key_order: Range look-ups are supported using pick() or restricted cursors. For performance reasons, dictionaries that maintain key order never maintain cardinality. As a result, cardinality() is an O(n) operation.

• os_Dictionary::maintain_cardinality: For dictionaries that maintain key order, the insert() and remove() functions will update cardinality information. This enumerator will improve performance if the cardinality() function is used (which otherwise is an 0(n) operation when cardinality is not maintained. However, maintaining cardinality can also cause contention in the dictionary header that can have an impact on large databases. For dictionaries that do not maintain key order, cardinality is always maintained but is done without causing contention in the dictionary header; in this case setting the maintain_cardinality enumerator is ignored.

These enumerators are instances of an enumeration defined in the scope of os_Dictionary. Each enumerator is associated with a different bit; including an enumerator in the disjunction sets its associated bit.

Release 6.3 221

Page 222: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Dictionary

For more information, see

• os_collection::cardinality_estimate() on page 174

• os_collection::cardinality_is_maintained() on page 174

• os_collection::update_cardinality() on page 191

os_Dictionary<K, E>::os_Dictionary<K, E>( os_unsigned_int32 expected_cardinality = 10, os_unsigned_int32 behavior_enums = 0);

Creates a new dictionary. The key type is specified by the parameter K and the value type by the parameter E. If the key type is a pointer type, the parameter K should be void*. The arguments have the same meaning as for the nonparameterized constructor.

os_Dictionary::pick()E pick(const os_coll_range&) const;

Returns an element of this that satisfies the specified os_coll_range. If there is more than one such element, an arbitrary one is picked and returned. If there is no such element, 0 is returned. If the dictionary is empty, err_coll_empty is signaled.

E pick(const K &key_ref) const;

Returns an element of this that has the value of the key referred to by the value of key_ref. If there is more than one such element, an arbitrary one is picked and returned. If there is no such element, 0 is returned. If the dictionary is empty, returns 0.

E pick(const K *key_ptr) const;

Returns an element of this that has the value of the key pointed to by key_ptr. If there is more than one such element, an arbitrary one is picked and returned. If there is no such element, 0 is returned. If the dictionary is empty, returns 0.

E pick( ) const;

Picks an arbitrary element of this and returns it. If the dictionary is empty, 0 is returned.

os_Dictionary::remove()void remove(const K &key_ref, const E element);

Removes the dictionary entry with the element element at the value of the key referred to by key_ref. This overloading of remove( ) differs from the next overloading only in that the key is specified with a reference instead of a pointer. If removing this element leaves no other elements at this key value, the key is removed and deleted.

If there is no such entry, the dictionary remains unchanged. If there is such an entry, the collection’s cardinality decreases by 1 and the count (or number of occurrences) of the removed element in the collection decreases by 1.

void remove(const K *key_ptr, const E element);

222 C++ Collections Guide and Reference

Page 223: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

Removes the dictionary entry with the element element and the key pointed to by key_ptr. This overloading of remove( ) differs from the previous overloading only in that the key is specified with a pointer instead of a reference. If removing this element leaves no other elements at this key value, the key is removed and deleted.

os_int32 remove(const E element)

Removes one dictionary entry specified by element. The element removed may have any key value. If removing this element leaves no other elements at its corresponding key value, the corresponding key value is removed and deleted.

If there is no such entry, the dictionary remains unchanged. If there is such an entry, the collection's cardinality decreases by 1 and the count (or number of occurrences) of the removed element in the collection decreases by 1.

Returns a nonzero os_int32 if an element was removed, and 0 otherwise.

os_Dictionary::remove_value()E remove_value(const K &key_ref, os_unsigned_int32 n = 1);

Removes n dictionary entries with the value of the key referred to by key_ref. If there are fewer than n, all entries in the dictionary with that key are removed. If there is no such entry, the dictionary remains unchanged.

This overloading of remove_value( ) differs from the next overloading only in that the key is specified with a reference instead of a pointer.

For each entry removed, the collection’s cardinality decreases by 1 and the count (or number of occurrences) of the removed element in the collection decreases by 1. If removing this element leaves no other elements at this key value, the key is removed and deleted.

void remove_value(const K *key_ptr, os_unsigned_int32 n = 1);

Removes n dictionary entries with the value of the key pointed to by key_ptr. This overloading of remove_value( ) differs from the previous overloading only in that the key is specified with a pointer instead of a reference. If removing this element leaves no other elements at this key value, the key is removed and deleted.

os_Dictionary::retrieve()E retrieve(const os_cursor&) const;

Returns the element of this at which the specified cursor is located. If the cursor is null, err_coll_null_cursor is signaled. If the cursor is invalid, err_coll_illegal_cursor is signaled. If the collection maintained internally by the cursor is not the same as the collection maintained by the dictionary, the err_coll_cursor_mismatch exception is signaled.

os_Dictionary::retrieve_key()const K *retrieve_key(const os_cursor&) const;

const K retrieve_key(const os_cursor&) const;

Release 6.3 223

Page 224: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_dynamic_extent

Returns a pointer to a dictionary key unless the key is a char* or void* in which case retrieve_key() returns the key itself. You must not modify this key. Like all collection functions that take cursor arguments, this function works only with vanilla cursors — that is, cursors that were not created with a cursor option, index path, rank function, or an os_coll_range. If the collection maintained internally by the cursor is not the same as the collection maintained by the dictionary, the err_coll_cursor_mismatch exception is signaled.

os_dynamic_extentDerived from os_collection, an instance of this class can be used to create an extended collection of all objects of a particular type, regardless of which segments the objects reside in. All objects are retrieved in an arbitrary order that is stable across traversals of the segments, as long as no objects are created or deleted from the segment, and no reorganization is performed (using schema evolution or compaction).

os_dynamic_extent is useful for joining together multiple collections of the same object type into a new collection. The new collection is created dynamically, which results in no additional storage consumption.

You iterate over the os_dynamic_extent collection by creating an associated instance of os_cursor. Only the os_cursor::more(), os_cursor::first(), and os_cursor::next() functions are supported by os_dynamic_extent. You can create an index for the os_dynamic_extent collection by calling add_index(); however, creating an index requires additional storage.

os_dynamic_extent::insert()void insert(const void*);

Adds the specified void* to the index for the current os_dynamic_extent collection. You must first create an index by calling os_dynamic_extent::add_index(). See os_collection::add_index() on page 171.

os_dynamic_extent::os_dynamic_extent() os_dynamic_extent( os_database * db, os_typespec * typespec);

Constructs an os_dynamic_extent that associates all objects of os_typespec that exist in the specified os_database. This constructor should be used only for transient instances of os_dynamic_extent.

os_dynamic_extent( os_typespec * typespec, os_boolean options = os_dynamic_extent::all_segments);

224 C++ Collections Guide and Reference

Page 225: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

Constructs an os_dynamic_extent that associates all objects of os_typespec. This constructor assumes that the os_dynamic_extent is persistent and searches the database where the os_dynamic_extent resides. If the option is os_dynamic_extent::all_segments, all segments are searched. The alternative option is os_dynamic_extent::of_segment, which searches only the segment in which the os_dynamic_extent is allocated.

os_dynamic_extent( os_database * db, os_typespec* typespec, os_segment* seg);

Constructs an os_dynamic_extent that associates only those objects of os_typespec that exist in the specified os_database and os_segment. This constructor should be used only for transient instances of os_dynamic_extent.

os_dynamic_extent::remove()os_int32 remove(const void*);

Removes the specified void* from the os_dynamic_extent collection index.

If the index is ordered, the first occurrence of the specified void* is removed. Returns a nonzero os_int32 if an element was removed; returns 0 otherwise.

os_index_nameAn instance of this class encapsulates information about a particular index. Functions are provided for retrieving a string representation of the index’s associated path and a bit pattern indicating the index’s associated options. See also os_collection::get_indexes() on page 176, which returns a collection of os_index_names.

os_index_name::get_options()os_int32 get_options( );

Returns a bit pattern indicating the index options associated with the index named by this.

os_index_name::get_path_name()char *get_path_name( );

Returns a string representation of the path associated with the index named by this. The caller is responsible for freeing the memory pointed to by the return value.

Release 6.3 225

Page 226: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_index_path

os_index_pathInstances of the class os_index_path are used in specifying iteration order, as well as in specifying index keys to enable query optimization.

Each path specifies a certain kind of mapping by specifying a sequence of member names. Applying the mapping is equivalent to accessing a data member, applying a member function, or accessing a data member of a data member, and so on.

For example, suppose the type employee defines a data member department, whose values are pointers to instances of a type that defines a data member manager. Then a path might be specified with the path_string "department–>manager". This path maps pointers to instances of employee to the manager of the given employee’s department.

Path expressions have some additional expressive power. They can indicate iterative retrieval of the elements of path results that are collections. For example, consider specifying a key for an index that optimizes look-up of a part based on the emp_id of any of the responsible_engineers for the part (suppose that the member responsible_engineers is collection valued). You can use the path created by the following call:

os_index_path::create( "part*","responsible_engineers[]->emp_id", db1)

Here the data member name "responsible_engineers" is followed by the symbols [ ], indicating that the next component of the path (emp_id) is to be applied to each element of the collection of responsible engineers, rather than to the collection itself.

os_index_path::allow_duplicates Used to form a bit-pattern argument to os_collection::add_index(). Indicates an index that allows duplicate keys. You should use such an index for collections in which two or more elements can share a key value. Specifying both allow_duplicates and no_duplicates for the same index results in a no_duplicates index; see os_index_path::no_duplicates on page 228.

os_index_path::copy_keyUsed to form a bit-pattern argument to os_collection::add_index(). Indicates an index with entries consisting of key-value/element pairs, as opposed to pointer-to-key-value/element pairs; see os_index_path::create() on page 226. For a copy_key index, form an entry by copying the object at the end of the os_index_path that specifies the key. Such an index generally takes up more space than one that points to its keys, but it provides faster access times because of reduced paging costs. Specifying both copy_key and point_to_key for the same index results in a point_to_key index.

os_index_path::create()static os_index_path &create( const char *element_type_string,

226 C++ Collections Guide and Reference

Page 227: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

const char *path_string, const os_database*);

Creates a transient heap-allocated os_index_path.

The element_type_string, known as the path’s type string, is a string consisting of the name of the element type of collections whose elements can serve as path starting points. Names created with a typedef cannot be used.

The path_string consists of a sequence of member names separated by dots or arrows.

Given a path string, path_string, ending in a member function name, you can form a path string whose values are the results of dereferencing the result of path_string this way:

" *(parent-> theChild() ) "

*(path_string)

The parentheses are not necessary if the original path string specifies a single-step path.

You cannot specify a dereferenced data member at the end of a path string. For example, you cannot specify

" *(parent->child) "

or

" * Foo "

A collection-valued path followed by a pair of brackets [ ] forms a multivalued path whose values are the collection’s elements. To indicate element retrieval (using [ ]) from a nonparameterized collection, the part of the path designating the collection must be preceded by a cast to os_Collection<E>, where E is the collection’s element type os_collection.

The value type of a data member referred to in a path expression must be a built-in type, a class, or a pointer to a built-in type or class. The type person**, for example, is not allowed.

If an illegal path_string is supplied, err_illegal_index_path is signaled.

Data members mentioned in the path_string, except const and collection-valued members, must be indexable if there is any possibility of their being updated when participating in an index.

For applications that use member functions, see Calling Functions in Query Strings on page 86. In addition, when you create an index path that ends in a member function, the member function should return something that is either a basic type, a pointer to a persistent object, or a class object that will be copied into the index.

An application must supply a rank function for a class type, T, if the application uses a path ending in T as an index key, or to specify iteration order. An application must supply a hash function for a class, T, if the application uses a path ending in T as a key for an unordered index.

Release 6.3 227

Page 228: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_index_path

The os_database* is a database whose schema contains the classes defining the members mentioned in the path_string.

Once the path generated by create( ) is no longer needed, you should deallocate it with ::operator delete( ) to avoid memory leaks. For information about deleting objects, see ::operator delete() in Chapter 3 of the C++ A P I Reference.

static os_index_path &create( const char *element_type_string, const char *path_string, const os_segment*);

Creates a transient heap-allocated os_index_path. This is the same as the preceding version of create( ), except that the os_segment* indicates a segment in a database whose schema contains the classes defining the members mentioned in the path_string.

static os_index_path &create( const char *element_type_string, const char *path_string, const void*);

Creates a transient heap-allocated os_index_path. This is the same as the preceding version of create( ), except that the void* indicates an object in a database whose schema contains the classes defining the members mentioned in the path_string.

os_index_path::no_duplicates Used to form a bit-pattern argument to os_collection::add_index(). Indicates an index that does not allow duplicate key values. You should use such an index for collections in which no two elements can share a key value. If duplicate key values might accidentally occur, use this enumerator together with signal_duplicates (see the following). If signal_duplicates is not also specified for the index, duplicate keys are not detected, which can produce unpredictable results. Always specify signal_duplicates when you specify no_duplicates; see os_index_path::signal_duplicates on page 229.

os_index_path::ordered Used to form a bit-pattern argument to os_collection::add_index(). Indicates an ordered index, implemented as a B-tree, supporting optimization of range queries; that is, queries involving the comparison operators <, >, <=, and >=. Specifying both ordered and unordered for the same index results in an ordered index; see os_index_path::unordered on page 229.

os_index_path::point_to_key Used to form a bit-pattern argument to os_collection::add_index(). Indicates an index with entries consisting of pointer-to-key-value/element pairs, as opposed to key-value/element pairs. For a point_to_key index, an entry includes a pointer to the object at the end of the os_index_path that specifies the key. Because of increased paging costs, such an index generally provides slower access times than an

228 C++ Collections Guide and Reference

Page 229: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

index that copies its keys; but a point_to_key index takes up less space. Specifying both copy_key and point_to_key for the same index results in a point_to_key index; see os_index_path::copy_key on page 226.

os_index_path::signal_duplicatesUsed to form a bit-pattern argument to os_collection::add_index(). Indicates an index that detects duplicate key values. This enumerator should only be used together with no_duplicates; see os_index_path::no_duplicates on page 228.

If an index that signals duplicates is added to a collection containing two or more elements that share a key value, the exception err_index_duplicate_key is signaled. In addition, for a collection with an index that signals duplicates, inserting an element with the same key value as some other element also provokes an err_index_duplicate_key exception.

os_index_path::unorderedUsed to form a bit-pattern argument to os_collection::add_index(). Indicates an unordered index implemented as a hash table. Such an index does not support optimization of range queries. Specifying both ordered and unordered for the same index results in an ordered index; see os_index_path::ordered on page 228.

os_Ixonly and os_ixonlytemplate <class E>class os_Ixonly : public os_Collection<E>

class os_ixonly : public os_collection

An index-only collection is a collection subtype that supports O(1) element look-up. Operations such as contains() and remove() are O(1) (in the number of elements). Index-only collections allow you to save space by telling ObjectStore to record the membership of the collection in one of the indexes, as opposed to recording the membership in both the index and the collection. In other words, you save space by using an index as a collection’s internal representation.

When creating an index-only collection, you must add an index to the collection before performing any operations on it. You can add additional indexes.

By default, an index-only operation ignores duplicate insertions and allows null insertions.

For large collections subject to contention, index-only collections do not maintain cardinality. Not maintaining cardinality provides better performance for most collections functionality. It will, however, cause a call to cardinality() to be O(N). To determine if a collection maintains cardinality, call the following member of os_collection:

os_int32 cardinality_is_maintained() const;

Release 6.3 229

Page 230: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Ixonly and os_ixonly

This function returns nonzero (true) if the collection maintains cardinality, and 0 (false) otherwise.

The following member of os_collection is an O(1) operation in the size of the collection and returns an estimate of the collection’s cardinality:

os_unsigned_int32 cardinality_estimate() const;

This function returns the cardinality as of the last call to os_collection::update_cardinality() (see below). For collections that maintain cardinality, this function returns the actual cardinality.

Before adding a new index to an index-only collection that does not maintain cardinality, call the following member of os_collection:

os_unsigned_int32 update_cardinality();

If you do not call this function, add_index() will work correctly but less efficiently. update_cardinality() updates the value returned by os_collection::cardinality_estimate() by scanning the collection and computing the actual cardinality.

Note Using index-only collections can save on space overhead at the cost of reduced efficiency of some collection operations. If the only time-critical collection operation is index-based element look-up, an index-only collection is likely to be beneficial.

For cardinalities below 30, an os_List (or os_list) might be a better collection subtype.

The following table illustrates complexities in terms of collection cardinality, represented by n. The complexities reflect the nature of the computational overhead, not overhead owing to disk I/O and network traffic:

os_Ixonly::os_Ixonly() and os_ixonly::os_ixonly() os_Ixonly(os_boolean duplicates = 0, os_boolean maintain_cardinality = 0);

os_ixonly(os_boolean duplicates = 0, os_boolean maintain_cardinality = 0);

Creates a new index-only collection.

Collection Operation Time Complexity

insert() O(1)

remove() O(1)

cardinality(), maintain_cardinality O(1)

cardinality(), !maintain_cardinality O(N)

contains() O(1)

comparisons ( <=, ==, etc. ) O(1)

merges (|, &, -) O(1)

230 C++ Collections Guide and Reference

Page 231: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

If duplicates is nonzero (true), the index-only collection allows duplicate insertions of elements. By default, duplicate insertions are not allowed.

If maintain_cardinality is nonzero (true), the index-only collection maintains the cardinality of the collection, thus making cardinality an O(1) operation but considerably slowing down other collection operations — for example, insert() and contains(). The default is that cardinality is not automatically updated by the collection; insert() and contains() become O(1) operations, and cardinality() becomes an O(N) operation.

os_keyword_argAn instance of this class is used to specify the binding of a free reference in an os_coll_query. An os_keyword_arg or os_keyword_arg_list (see os_keyword_arg_list on page 233) is used together with an os_coll_query to create an os_bound_query. Each os_keyword_arg associates a variable name with a value of the appropriate type.

os_keyword_arg::operator ,()os_keyword_arg_list &operator ,(const os_keyword_arg arg&)const;

Returns a reference to an os_keyword_arg_list whose elements are the instances of os_keyword_arg referred to by this and arg. The comma operator of this class and os_keyword_arg_list is overloaded in such a way that you can designate a keyword_arg_list with an expression of the following form:

( keyword_arg-expr, keyword_arg-expr, ... , keyword_arg-expr )

os_keyword_arg::os_keyword_arg()os_keyword_arg( const char *name, os_signed_int8 value);

Constructs an os_keyword_arg that binds the char-valued variable specified by name to value.

os_keyword_arg( const char *name, unsigned char value);

Constructs an os_keyword_arg that binds the unsigned char-valued variable specified by name to value.

os_keyword_arg(

Release 6.3 231

Page 232: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_keyword_arg

const char *name, short value);

Constructs an os_keyword_arg that binds the short-valued variable specified by name to value.

os_keyword_arg( const char *name, unsigned short value);

Constructs an os_keyword_arg that binds the unsigned short-valued variable specified by name to value.

os_keyword_arg( const char *name, int value);

Constructs an os_keyword_arg that binds the int-valued variable specified by name to value.

os_keyword_arg( const char *name, unsigned int value);

Constructs an os_keyword_arg that binds the unsigned int-valued variable specified by name to value.

os_keyword_arg( const char *name, long value);

Constructs an os_keyword_arg that binds the long-valued variable specified by name to value.

os_keyword_arg( const char *name, unsigned long value);

Constructs an os_keyword_arg that binds the unsigned long-valued variable specified by name to value.

os_keyword_arg( const char *name, float value);

Constructs an os_keyword_arg that binds the float-valued variable specified by name to value.

os_keyword_arg( const char *name, double value);

Constructs an os_keyword_arg that binds the double-valued variable specified by name to value.

232 C++ Collections Guide and Reference

Page 233: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

os_keyword_arg( const char *name, long double value);

Constructs an os_keyword_arg that binds the long double-valued variable specified by name to value.

os_keyword_arg( const char *name, void* value);

Constructs an os_keyword_arg that binds the void*-valued variable specified by name to value and void*.

os_keyword_arg( const char *name, const void* value);

Constructs an os_keyword_arg that binds the const void*-valued variable specified by name to value and void*.

os_keyword_arg_listAn instance of this class is used to specify the binding of free variables in an os_coll_query. An os_keyword_arg_list or os_keyword_arg (see os_keyword_arg on page 231) is used together with an os_coll_query to create an os_bound_query. Each os_keyword_arg_list associates a variable name with a value of the appropriate type.

os_keyword_arg_list::destroy_list() static void destroy_list(os_keyword_arg_list *kal);

This function traverses the list of os_keyword_arg_list elements that kal points to and then deletes the elements. When it is created, the os_keyword_arg_list makes a copy of any os_keyword_arg that is passed to the constructor. The destroy_list() function does not destroy any os_keyword_arg that you dynamically create.

For information about the os_keyword_arg_list() constructor, see os_keyword_arg::os_keyword_arg() on page 231.

os_keyword_arg_list::operator ,()os_keyword_arg_list &operator ,(const os_keyword_arg&);

Returns a reference to an os_keyword_arg_list whose elements are the elements of this together with the specified os_keyword_arg. The comma operator of this class and os_keyword_arg is overloaded in such a way that you can designate an os_keyword_arg_list with an expression of the following form:

( keyword_arg-expr,

Release 6.3 233

Page 234: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_List

keyword_arg-expr, ... , keyword_arg-expr )

os_keyword_arg_list makes its own copy of the specified os_keyword_arg. If os_keyword_arg is created dynamically, it must be explicitly deleted by the user; it is not deleted by the os_keyword_arg_list destructor.

os_keyword_arg_list::os_keyword_arg_list()Creates an instance of an os_keyword_arg_list that contains a single os_keyword_arg.

os_keyword_arg_list( const os_keyword_arg& kwarg, const os_keyword_arg_list* kal = 0);

If the kal argument is not specified, the os_keyword_arg_list constructor constructs an os_keyword_arg_list whose elements are those of the single os_keyword_arg. This constructor makes its own copy of os_keyword_arg. If kwarg is created dynamically, it must be explicitly deleted by the user; it is not deleted by the os_keyword_arg_list destructor.

The kal argument is useful when calling the os_bound_query constructor. For example, consider the following:

os_bound_query bq(my_coll_query, os_keyword_arg_list(age,5));

The kal argument is specified as 5, causing the os_keyword_arg_list() constructor to create an os_keyword_arg_list whose elements are those of the kwarg argument together with a previously created os_keyword_arg_list, kal.

The os_keyword_arg_list() constructor does not destroy the kwarg or kal arguments. If kwarg or kal are created dynamically, you must explicitly destroy them. For convenience, you can call the os_keyword_arg_list::destroy_list() function to destroy the entire os_keyword_arg_list; see os_keyword_arg_list::destroy_list() on page 233.

os_Listtemplate <class E>class os_List : public os_Collection<E>

A list is an ordered collection. As with other ordered collections, list elements can be inserted, removed, replaced, or retrieved based on a specified numerical index or based on the position of a specified cursor.

Lists allow duplicates and disallow null elements.

If an element is inserted or removed from an os_List, all other elements are either pushed up or down with respect to their ordinal index in the list.

234 C++ Collections Guide and Reference

Page 235: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

The class os_List is parameterized, with a parameter for constraining the type of values allowable as elements (for the nonparameterized version of this class, see os_list on page 241). The element type parameter, E, occurs in the signatures of some of the functions described below. The parameter is used by the compiler to detect type errors.

It is possible to optimize os_List for maximum performance, using os_nList; see os_nList and os_nlist on page 246.

The element type of any instance of os_List must be a pointer type.

You must mark parameterized collections types in the schema source file.

Tables of member functions and enumerators

The first of the following tables lists the member functions that can be performed on instances of os_List. The second table lists the enumerators inherited by os_List from os_collection. Many functions are also inherited by os_List from os_Collection or os_collection. The full explanation of each inherited function or enumerator appears in the entry for the class from which it is inherited. The full explanation of each function defined by os_List appears in this entry, after the tables. In each case, the Defined By column gives the class whose entry contains the full explanation.

Name Arguments Returns Defined By

add_index ( const os_index_path&, os_int32 options, os_cluster* = 0 )

( const os_index_path&, os_int32 options, os_segment* = 0 )

( const os_index_path&, os_int32 options, os_database* = 0 )

( const os_index_path&, os_cluster* = 0 )

( const os_index_path&, os_segment* = 0 )

( const os_index_path&, os_database* = 0 )

void

void

void

void

void

void

os_collection

cardinality ( ) const os_int32 os_collection

clear ( ) void os_collection

contains ( const E ) const os_int32 os_Collection

count ( const E ) const os_int32 os_Collection

drop_index ( const os_index_path& ) void os_collection

empty ( ) os_int32 os_collection

Release 6.3 235

Page 236: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_List

exists ( char *element_type_name, char *query_string, os_database *schema_database = 0, char* filename, os_unsigned_int32 line ) const

( const os_bound_query& ) const

os_int32

os_int32

os_collection

get_behavior ( ) const os_unsigned_int32

os_collection

has_index ( const os_index_path&, os_int32 index_options = unordered ) const

os_int32 os_collection

insert ( const E ) void os_Collection

insert_after ( const E, const os_Cursor<E>& )

( const E, os_unsigned_int32 )

void

void

os_Collection

os_Collection

insert_before ( const E, const os_Cursor<E>& )

( const E, os_unsigned_int32 )

void

void

os_Collection

insert_first ( const E ) void os_Collection

insert_last ( const E ) void os_Collection

only ( ) const E os_Collection

operator os_Array<E>&

( ) os_Collection

operator const os_Array<E>&

( ) const os_Collection

operator os_array&

( ) os_collection

operator const os_array&

( ) const os_collection

operator os_Bag<E>&

( ) os_Collection

operator const os_Bag<E>&

( ) const os_Collection

operator os_bag&

( ) os_collection

operator const os_bag&

( ) const os_collection

Name Arguments Returns Defined By

236 C++ Collections Guide and Reference

Page 237: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

operator os_list&

( ) os_collection

operator const os_list&

( ) const os_collection

operator os_Set<E>&

( ) os_Collection

operator const os_Set<E>&

( ) const os_Collection

operator os_set&

( ) os_collection

operator const os_set&

( ) const os_collection

operator == ( const os_Collection<E>& ) const

( const E ) const

os_int32

os_int32

os_Collection

operator != ( const os_Collection<E>& ) const

( const E ) const

os_int32

os_int32

os_Collection

operator < ( const os_Collection<E>& ) const

( const E ) const

os_int32

os_int32

os_Collection

operator <= ( const os_Collection<E>& ) const

( const E ) const

os_int32

os_int32

os_Collection

operator > ( const os_Collection<E>& ) const

( const E ) const

os_int32

os_int32

os_Collection

operator >= ( const os_Collection<E>& ) const

( const E ) const

os_int32

os_int32

os_Collection

operator = ( const os_List<E>& ) const

( const os_Collection<E>& ) const

( const E ) const

os_List<E>&

os_List<E>&

os_List<E>&

os_List

operator |= ( const os_Collection<E>& ) const

( const E ) const

os_List<E>&

os_List<E>&

os_List

operator | ( const os_Collection<E>& ) const

( const E ) const

os_Collection<E>&

os_Collection<E>&

os_Collection

operator &= ( const os_Collection<E>& ) const

( const E ) const

os_List<E>&

os_List<E>&

os_List

operator & ( const os_Collection<E>& ) const

( const E ) const

os_Collection<E>&

os_Collection<E>&

os_Collection

Name Arguments Returns Defined By

Release 6.3 237

Page 238: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_List

operator –= ( const os_Collection<E>& ) const

( const E ) const

os_List<E>&

os_List<E>&

os_List

operator - ( const os_Collection<E>& ) const

( const E ) const

os_Collection<E>&

os_Collection<E>&

os_Collection

os_List ( )

( os_int32 expected_size )

( const os_List<E>& )

( const os_Collection<E>& )

os_List

pick ( ) const

( const os_index_path&, const os_coll_range& ) const

E

E

os_Collection

query ( char *element_type_name, char *query_string, os_database *schema_database = 0, char* filename = 0, os_unsigned_int32 line, os_boolean dups ) const

( const os_bound_query&, os_boolean dups ) const

os_Collection<E>&

os_Collection<E>&

os_Collection

query_pick ( char *element_type_name, char *query_string, os_database *schema_database = 0, char* filename, os_unsigned_int32 line ) const

( const os_bound_query& ) const

E

E

os_Collection

remove ( const E ) os_int32 os_Collection

remove_at ( const os_Cursor<E>& )

( os_unsigned_int32 )

void

void

os_Collection

remove_first ( const E& )

( )

os_int32

E

os_Collection

remove_last ( const E& )

( )

os_int32

E

os_Collection

replace_at ( const E, const os_Cursor<E>& )

( const E, os_unsigned_int32 )

E

E

os_Collection

retrieve ( os_unsigned_int32 ) const

( const os_Cursor<E>& ) const

E

E

os_Collection

Name Arguments Returns Defined By

238 C++ Collections Guide and Reference

Page 239: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

os_List enumerators

The following table lists the enumerators inherited by os_List from os_collection.

Assignment Operator SemanticsAssignment operator semantics are described for the following functions in terms of insert operations into the target collection. The actual implementation of the assignment might be different, while still maintaining the associated semantics.

os_List::operator =()os_List<E> &operator =(const os_List<E> &s);

Copies the contents of the collection s into the target collection and returns the target collection. The copy is performed by effectively clearing the target, iterating over the source collection (in order), and inserting each element into the target collection. The target collection semantics are enforced as usual during the insertion process.

os_List<E> &operator =(const os_Collection<E> &s);

Copies the contents of the collection s into the target collection and returns the target collection. The copy is performed by effectively clearing the target, iterating over the source collection (in order), and inserting each element into the target collection. The target collection semantics are enforced as usual during the insertion process.

os_List<E> &operator =( const E e);

Clears the target collection, inserts the element e into the target collection, and returns the target collection.

os_List::operator |=()os_List<E> &operator |=(const os_Collection<E> &s);

retrieve_first

( ) const

( const E& ) const

E

os_int32

os_Collection

retrieve_last ( ) const

( const E& ) const

E

os_int32

os_Collection

Name Arguments Returns Defined By

Name Inherited From

allow_duplicates os_collection

allow_nulls os_collection

EQ os_collection

GT os_collection

LT os_collection

maintain_order os_collection

optimized_list os_collection

Release 6.3 239

Page 240: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_List

Inserts the elements contained in s into the target collection and returns the target collection.

os_List<E> &operator |=(const E e);

Inserts the element e into the target collection and returns the target collection.

os_List::operator &=()os_List<E> &operator &=(const os_Collection<E> &s);

For each element in the target collection, reduces the count of the element in the target to the minimum of the counts in the source and target collections. It does so by retaining the appropriate number of leading elements. It returns the target collection.

os_List<E> &operator &=(const E e);

If e is present in the target, converts the target into a collection containing just the element e. Otherwise, it clears the target collection. It returns the target collection.

os_List::operator –=()os_List<E> &operator –=(const os_Collection<E> &s);

For each element in the collection s, removes s.count(e) occurrences of the element from the target collection. The first s.count(e) elements are removed. It returns the target collection.

os_List<E> &operator –=(const E e);

Removes the element e from the target collection. The first occurrence of the element is removed from the target collection. It returns the target collection.

os_List::os_List()os_List( );

Returns an empty list.

os_List(os_int32 expected_size, os_int32 behavior = 0);

Returns an empty list whose initial implementation is based on the expectation that the expected_size argument approximates the usual cardinality of the list, once the list has been loaded with elements. If you are constructing a transient list that will hold persistent element pointers, specify the os_collection::optimized_list option for the behavior argument. This option will increase performance by creating a hard-pointer-based list.

os_List(const os_List<E> &coll);

Returns a list that results from assigning the specified list to an empty list.

os_List(const os_Collection<E> &coll);

Returns a list that results from assigning the specified collection to an empty list.

240 C++ Collections Guide and Reference

Page 241: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

os_listclass os_list : public os_collection

A list is an ordered collection. As with other ordered collections, list elements can be inserted, removed, replaced, or retrieved based on a specified numerical index or based on the position of a specified cursor.

The class os_list is nonparameterized. For the parameterized version of this class, see os_List on page 234.

Lists allow duplicates and disallow null elements.

If an element is inserted or removed from an os_list, all other elements are either pushed up or down with respect to their ordinal index in the list.

It is possible to optimize os_list for maximum performance, using os_nlist; see os_nList and os_nlist on page 246.

The element type of any instance of os_list must be a pointer type.

Tables of member functions and enumerators

The first of the following tables lists the member functions that can be performed on instances of os_list. The second table lists the enumerators inherited by os_list from os_collection. The full explanation of each inherited function or enumerator appears in the entry for the class from which it is inherited. The full explanation of each function defined by os_list appears in this entry, after the tables. In each case, the Defined By column gives the class whose entry contains the full explanation.

Name Arguments Returns Defined By

add_index ( const os_index_path&, os_int32 options, os_cluster* = 0 )

( const os_index_path&, os_int32 options, os_segment* = 0 )

( const os_index_path&, os_int32 options, os_database* = 0 )

( const os_index_path&, os_cluster* = 0 )

( const os_index_path&, os_segment* = 0 )

( const os_index_path&, os_database* = 0 )

void

void

void

void

void

void

os_collection

cardinality ( ) const os_int32 os_collection

clear ( ) void os_collection

contains ( const void* ) const os_collection

count ( const void* ) const os_int32

drop_index ( const os_index_path& ) void os_collection

Release 6.3 241

Page 242: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_list

empty ( ) os_int32 os_collection

exists ( char *element_type_name, char *query_string, os_database *schema_database = 0, char* filename, os_unsigned_int32 line ) const

( const os_bound_query& ) const

os_int32

os_int32

os_collection

get_behavior ( ) const os_unsigned_int32

os_collection

has_index ( const os_index_path&, os_int32 index_options = unordered ) const

os_int32 os_collection

insert ( const void* ) void os_collection

insert_after ( const void*, const os_cursor& )

( const void*, os_unsigned_int32 )

void

void

os_collection

insert_before ( const void*, const os_cursor& )

( const void*, os_unsigned_int32 )

void

void

os_collection

insert_first ( const void* ) void os_collection

insert_last ( const void* ) void os_collection

only ( ) const void* os_collection

operator os_bag&

( ) os_collection

operator const os_bag&

( ) const os_collection

operator os_set&

( ) os_collection

operator const os_set&

( ) const os_collection

operator == ( const os_collection& ) const

( const void* ) const

os_int32

os_int32

os_collection

operator != ( const os_collection& ) const

( const void* ) const

os_int32

os_int32

os_collection

operator < ( const os_collection& ) const

( const void* ) const

os_int32

os_int32

os_collection

operator <= ( const os_collection& ) const

( const void* ) const

os_int32

os_int32

os_collection

operator > ( const os_collection& ) const

( const void* ) const

os_int32

os_int32

os_collection

Name Arguments Returns Defined By

242 C++ Collections Guide and Reference

Page 243: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

operator >= ( const os_collection& ) const

( const void* ) const

os_int32

os_int32

os_collection

operator = ( const os_list& ) const

( const os_collection& ) const

( const void* ) const

os_list&

os_list&

os_list&

os_list

operator |= ( const os_collection& ) const

( const void* ) const

os_list&

os_list&

os_list

operator | ( const os_collection& ) const

( const void* ) const

os_collection

os_collection

os_collection

operator &= ( const os_collection& ) const

(const void*) const

os_list&

os_list&

os_list

operator & ( const os_collection& ) const

( const void* ) const

os_collection

os_collection

os_collection

operator –= ( const os_collection& ) const

( const void* ) const

os_list&

os_list&

os_list

operator - ( const os_collection& ) const

( const void* ) const

os_collection

os_collection

os_collection

os_list ( )

( os_int32 expected_size )

( const os_list& )

( const os_collection& )

os_list

pick ( ) const

( const os_index_path&, const os_coll_range& ) const

void*

void*

os_collection

query ( char *element_type_name, char *query_string, os_database *schema_database = 0, char* filename = 0, os_unsigned_int32 line, os_boolean dups ) const

( const os_bound_query&, os_boolean dups ) const

os_collection&

os_collection&

os_collection

query_pick ( char *element_type_name, char *query_string, os_database *schema_database = 0, char* filename, os_unsigned_int32 line ) const

( const os_bound_query& ) const

void*

void*

os_collection

remove ( const void* ) os_int32 os_collection

remove_at ( const os_cursor& )

( os_unsigned_int32 )

void

void

os_collection

Name Arguments Returns Defined By

Release 6.3 243

Page 244: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_list

os_list enumerators

The following table lists the enumerators inherited by os_list from os_collection.

Assignment Operator SemanticsAssignment operator semantics are described for the following functions in terms of insert operations into the target collection. The actual implementation of the assignment might be different, while still maintaining the associated semantics.

os_list::operator =()os_list &operator =(const os_collection &s);

Copies the contents of the collection s into the target collection and returns the target collection. The copy is performed by effectively clearing the target, iterating over the source collection, and inserting each element into the target collection. The iteration is ordered if the source collection is ordered. The target collection semantics are enforced as usual during the insertion process.

os_list &operator =(const void *e);

remove_first ( const void*& )

( )

os_int32

void*

os_collection

remove_last ( const void*& )

( )

os_int32

void*

os_collection

replace_at ( const void*, const os_cursor& )

( const void*, os_unsigned_int32 )

void*

void*

os_collection

retrieve ( os_unsigned_int32 ) const

( const os_cursor& ) const

void*

void*

os_collection

retrieve_first ( ) const

( const void*& ) const

void*

os_int32

os_collection

retrieve_last ( ) const

( const void*& ) const

void*

os_int32

os_collection

Name Arguments Returns Defined By

Name Inherited From

allow_duplicates os_collection

allow_nulls os_collection

EQ os_collection

GT os_collection

LT os_collection

maintain_order os_collection

optimized_list os_collection

244 C++ Collections Guide and Reference

Page 245: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

Clears the target collection, inserts the element e into the target collection, and returns the target collection.

os_list::operator |=()os_list &operator |=(const os_collection &s);

Inserts the elements contained in s into the target collection and returns the target collection.

os_list &operator |=(const void *e);

Inserts the element e into the target collection and returns the target collection.

os_list::operator &=()os_list &operator &=(const os_collection &s);

For each element in the target collection, reduces the count of the element in the target to the minimum of the counts in the source and target collections. It does so by retaining the appropriate number of leading elements. It returns the target collection.

os_list &operator &=(const void *e);

If e is present in the target, converts the target into a collection containing just the element e. Otherwise, it clears the target collection. It returns the target collection.

os_list::operator –=()os_list &operator –=(const os_collection &s);

For each element in the collection s, removes s.count(e) occurrences of the element from the target collection. The first s.count(e) elements are removed. It returns the target collection.

os_list &operator –=(const void *e);

Removes the element e from the target collection. The first occurrence of the element is removed from the target collection. It returns the target collection.

os_list::os_list()os_list( );

Returns an empty list.

os_list(os_int32 expected_size, os_int32 behavior = 0);

Returns an empty list whose initial implementation is based on the expectation that the expected_size argument approximates the usual cardinality of the list, once the list has been loaded with elements. If you are constructing a transient list that will hold persistent element pointers, specify the os_collection::optimized_list option for the behavior argument. This option will increase performance by creating a hard-pointer-based list.

os_list(const os_list &coll);

Returns a list that results from assigning the specified list to an empty list.

Release 6.3 245

Page 246: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_nList and os_nlist

os_list(const os_collection &coll);

Returns a list that results from assigning the specified collection to an empty list.

os_nList and os_nlisttemplate <class E>class os_nList : public os_List<E, NUM_PTRS_IN_HEAD, NUM_PTRS_IN_BLOCK>

class os_nlist : public os_list< NUM_PTRS_IN_HEAD, NUM_PTRS_IN_BLOCK>

The os_nList and os_nlist classes are parameterized forms of the os_List and os_list classes. Use the os_nList and os_nlist classes to tune the internal list structures for better performance.

If you use os_nList or os_nlist persistently, you must call the macro OS_MARK_NLIST_PT or OS_MARK_NLIST, respectively, in your schema source file for each os_nList or os_nlist that you use. If you are only using os_nList and os_nlist transiently, call the macro OS_TRANSIENT_NLIST in your source file. OS_TRANSIENT_NLIST will define the required stub functions. OS_TRANSIENT_NLIST_NO_BLOCK must be used if you have more than one os_Nlist or os_nlist with the same number of pointers in a block.

For more informations about these macros, see:

• OS_MARK_NLIST() on page 260

• OS_MARK_NLIST_PT() on page 261

• OS_TRANSIENT_NLIST() on page 263

• OS_TRANSIENT_NLIST_NO_BLOCK() on page 264

This section discusses the parameters you can specify for the os_nList and os_nlist classes. For all other API information, see os_List on page 234 and os_list on page 241.

A basic internal structure of an os_list consists of blocks of arrays. Each slot in the array contains a soft pointer to a collection element. When an application creates a list, ObjectStore defines an initial array of slots in the header. The size of this array is determined by NUM_PTRS_IN_HEAD. ObjectStore uses this array to store the initial elements inserted into the collection. When this array becomes full, ObjectStore allocates additional blocks of slots. The size of each block is determined by NUM_PTRS_IN_BLOCKS.

When ObjectStore allocates instances of os_list and os_List, NUM_PTRS_IN_HEAD is set to 4 and NUM_PTRS_IN_BLOCK is set to 8. To perform numerical positional operations on a list, ObjectStore iterates over the blocks to find the block that contains the position. After that, ObjectStore uses simple math to index the correct slot.

246 C++ Collections Guide and Reference

Page 247: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

To tune a list for faster positional operations, use os_nlist or os_nList. In general, modify NUM_PTRS_IN_BLOCK when you want to tune a collection. Modify NUM_PTRS_IN_HEAD only when you want to tune a very small collection (12 elements or less).

If you create a block or header with too large a number of slots, it has a negative effect during update operations. This can happen when the slots need to be moved up or down, depending on the type of operation.

For example, iteration over blocks for large collections is time consuming. To improve performance, set NUM_PTRS_IN_BLOCKS to a number that is larger than 8. This increases the array size for each block. Consequently, there are fewer blocks to iterate over.

Modification of the NUM_PTRS_IN_HEAD parameter is more suitable for small collections. You can create the actual list directly in the header, which eliminates additional paging. Technical Support recommends that you never set the NUM_PTRS_IN_HEAD parameter to a value larger than 12. A larger value for this parameter defeats its purpose.

Required header file

To use either os_nList or os_nlist, your application must include the header file:

<ostore/coll/nlist.cc>

os_Settemplate <class E>class os_Set : public os_Collection<E>

A set is an unordered collection that does not allow duplicate element occurrences. The count of a value in a given set is the number of times it occurs in the set — either 0 or 1.

The class os_Set is parameterized, with a parameter for constraining the type of values allowable as elements (for the nonparameterized version of this class, see os_set on page 254). The element type parameter, E, occurs in the signatures of some of the functions described here. The parameter is used by the compiler to detect type errors.

The element type of any instance of os_Set must be a pointer type.

You must mark parameterized collection types in the schema source file.

Tables of member functions and enumerators

The first of the following tables lists the member functions that can be performed on instances of os_Set. The second table lists the enumerators inherited by os_Set from os_collection. Many functions are also inherited by os_Set from os_Collection or os_collection. The full explanation of each inherited function or enumerator appears in the entry for the class from which it is inherited. The full explanation of each function defined by os_Set appears in this entry, after the tables. In each case, the Defined By column gives the class whose entry contains the full explanation.

Release 6.3 247

Page 248: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Set

Name Arguments Returns Defined By

add_index ( const os_index_path&, os_int32 options, os_cluster* = 0 )

( const os_index_path&, os_int32 options, os_segment* = 0 )

( const os_index_path&, os_int32 options, os_database* = 0 )

( const os_index_path&, os_cluster* = 0 )

( const os_index_path&, os_segment* = 0 )

( const os_index_path&, os_database* = 0 )

void

void

void

void

void

void

os_collection

cardinality ( ) const os_int32 os_collection

clear ( ) void os_collection

contains ( const E ) const os_int32 os_Collection

count ( const E ) const os_int32 os_Collection

drop_index ( const os_index_path& ) void os_collection

empty ( ) os_int32 os_collection

exists ( char *element_type_name, char *query_string, os_database *schema_database = 0, char* filename, os_unsigned_int32 line ) const

( const os_bound_query& ) const

os_int32

os_int32

os_collection

get_behavior ( ) const os_unsigned_int32

os_collection

has_index ( const os_index_path&, os_int32 index_options = unordered ) const

os_int32 os_collection

insert ( const E ) void os_Collection

only ( ) const E os_Collection

operator os_Array<E>&

( ) os_Collection

operator const os_Array<E>&

( ) const os_Collection

operator os_array&

( ) os_collection

248 C++ Collections Guide and Reference

Page 249: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

operator const os_array&

( ) const os_collection

operator os_Bag<E>&

( ) os_Collection

operator const os_Bag<E>&

( ) const os_Collection

operator os_bag&

( ) os_collection

operator const os_bag&

( ) const os_collection

operator os_List<E>&

( ) os_Collection

operator const os_List<E>&

( ) const os_Collection

operator os_list&

( ) os_collection

operator const os_list&

( ) const os_collection

operator os_set&

( ) os_collection

operator const os_set&

( ) const os_collection

operator == ( const os_Collection<E>& ) const

( E ) const

os_int32

os_int32

os_Collection

operator != ( const os_Collection<E>& ) const

( E ) const

os_int32

os_int32

os_Collection

operator < ( const os_Collection<E>& ) const

( E ) const

os_int32

os_int32

os_Collection

operator <= ( const os_Collection<E>& ) const

( E ) const

os_int32

os_int32

os_Collection

operator > ( const os_Collection<E>& ) const

( E ) const

os_int32

os_int32

os_Collection

operator >= ( const os_Collection<E>& ) const

( E ) const

os_int32

os_int32

os_Collection

operator = ( const os_Set<E>& ) const

( const os_Collection<E>& ) const

( E ) const

os_Set<E>&

os_Set<E>&

os_Set<E>&

os_Set

Name Arguments Returns Defined By

Release 6.3 249

Page 250: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Set

operator |= ( const os_Collection<E>& ) const

( E ) const

os_Set<E>&

os_Set<E>&

os_Set

operator | ( const os_Collection<E>& ) const

( E ) const

os_Collection<E>&

os_Collection<E>&

os_Collection

operator &= ( const os_Collection<E>& ) const

( E ) const

os_Set<E>&

os_Set<E>&

os_Set

operator & ( const os_Collection<E>& ) const

( E ) const

os_Collection<E>&

os_Collection<E>&

os_Collection

operator –= ( const os_Collection<E>& ) const

( E ) const

os_Set<E>&

os_Set<E>&

os_Set

operator - ( const os_Collection<E>& ) const

( E ) const

os_Collection<E>&

os_Collection<E>&

os_Collection

os_Set ( )

( os_int32 )

( const os_Set<E>& )

( const os_Collection<E>& )

os_Set

pick ( ) const

( const os_index_path&, const os_coll_range& ) const

E

E

os_Collection

query ( char *element_type_name, char *query_string, os_database *schema_database = 0, char* filename, os_unsigned_int32 line ) const

( const os_bound_query& ) const

os_Collection<E>&

os_Collection<E>&

os_Collection

query_pick ( char *element_type_name, char *query_string, os_database *schema_database = 0, char* filename, os_unsigned_int32 line ) const

( const os_bound_query& ) const

E

E

os_Collection

remove ( const E ) os_int32 os_Collection

remove_at ( const os_Cursor<E>& ) void os_Collection

Name Arguments Returns Defined By

250 C++ Collections Guide and Reference

Page 251: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

os_Set enumerators

The following table lists the enumerators inherited by os_Set from os_collection.

os_Set::default_behavior()static os_unsigned_int32 default_behavior( );

Returns a bit pattern indicating this type’s default behavior.

Assignment Operator SemanticsAssignment operator semantics are described for the following functions in terms of insert operations into the target collection. The actual implementation of the assignment might be different, while still maintaining the associated semantics.

os_Set::operator =()os_Set<E> &operator =(const os_Collection<const E> &s);

Copies the contents of the collection s into the target collection and returns the target collection. The copy is performed by effectively clearing the target, iterating over the source collection, and inserting each element into the target collection. The iteration is ordered if the source collection is ordered. The target collection semantics are enforced as usual during the insertion process.

os_Set<E> &operator =(E e);

Clears the target collection, inserts the element e into the target collection, and returns the target collection.

os_Set::operator |=()os_Set<E> &operator |=(const os_Collection<E> &s);

Inserts the elements contained in s into the target collection and returns the target collection.

os_Set<E> &operator |=(E e);

replace_at ( const E, const os_Cursor<E>& )

E os_Collection

retrieve ( const os_Cursor<E>& ) const E os_Collection

Name Arguments Returns Defined By

Name Inherited From

allow_nulls os_collection

EQ os_collection

GT os_collection

LT os_collection

maintain_order os_collection

order_by_address os_collection

unordered os_collection

Release 6.3 251

Page 252: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_Set

Inserts the element e into the target collection and returns the target collection.

os_Set::operator &=()os_Set<E> &operator &=(const os_Collection<E> &s);

For each element in the target collection, reduces the count of the element in the target to the minimum of the counts in the source and target collections. It returns the target collection.

os_Set<E> &operator &=(E e);

If e is present in the target, converts the target into a collection containing just the element e. Otherwise, it clears the target collection. It returns the target collection.

os_Set::operator –=()os_Set<E> &operator –=(const os_Collection<E> &s);

For each element in the collection s, removes s.count(e) occurrences of the element from the target collection. It returns the target collection.

os_Set<E> &operator –=(E e);

Removes the element e from the target collection. It returns the target collection.

252 C++ Collections Guide and Reference

Page 253: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

os_Set::os_Set()os_Set( );

Returns an empty set.

os_Set(os_int32 size);

Returns an empty set whose initial implementation is based on the expectation that the size argument indicates the approximate usual cardinality of the set, once the set has been loaded with elements.

os_Set(const os_Set<E>&);

Returns a set that results from assigning the specified set to an empty set.

os_Set(const os_Collection<E>&);

Returns a set that results from assigning the specified collection to an empty set.

Release 6.3 253

Page 254: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_set

os_setclass os_set : public os_collection

A set is an unordered collection that does not allow duplicate element occurrences. The count of a value in a given set is the number of times it occurs in the set — either 0 or 1.

The class os_set is nonparameterized. For the parameterized version of this class, see os_Set on page 247.

Tables of member functions and enumerators

The first of the following tables lists the member functions that can be performed on instances of os_set. The second table lists the enumerators inherited by os_set from os_collection. Many functions are also inherited by os_set from os_collection. The full explanation of each inherited function or enumerator appears in the entry for the class from which it is inherited. The full explanation of each function defined by os_set appears in this entry, after the tables. In each case, the Defined By column gives the class whose entry contains the full explanation.

Name Arguments Returns Defined By

add_index ( const os_index_path&, os_int32 options, os_cluster* = 0 )

( const os_index_path&, os_int32 options, os_segment* = 0 )

( const os_index_path&, os_int32 options, os_database* = 0 )

( const os_index_path&, os_cluster* = 0 )

( const os_index_path&, os_segment* = 0 )

( const os_index_path&, os_database* = 0 )

void

void

void

void

void

void

os_collection

cardinality ( ) const os_int32 os_collection

clear ( ) void os_collection

contains ( const void* ) const os_collection

count ( const void* ) const os_int32

default_behavior (static)

( ) os_unsigned_int32

os_set

drop_index ( const os_index_path& ) void os_collection

empty ( ) os_int32 os_collection

254 C++ Collections Guide and Reference

Page 255: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

exists ( char *element_type_name, char *query_string, os_database *schema_database = 0, char* filename, os_unsigned_int32 line ) const

( const os_bound_query& ) const

os_int32

os_int32

os_collection

get_behavior ( ) const os_unsigned_int32

os_collection

has_index ( const os_index_path&, os_int32 index_options = unordered ) const

os_int32 os_collection

insert ( const void* ) void os_collection

only ( ) const void* os_collection

operator os_array&

( ) os_collection

operator const os_array&

( ) const os_collection

operator os_bag&

( ) os_collection

operator const os_bag&

( ) const os_collection

operator os_list&

( ) os_collection

operator const os_list&

( ) const os_collection

operator == ( const os_collection& ) const

( const void* ) const

os_int32

os_int32

os_collection

operator != ( const os_collection& ) const

( const void* ) const

os_int32

os_int32

os_collection

operator < ( const os_collection& ) const

( const void* ) const

os_int32

os_int32

os_collection

operator <= ( const os_collection& ) const

( const void* ) const

os_int32

os_int32

os_collection

operator > ( const os_collection& ) const

( const void* ) const

os_int32

os_int32

os_collection

operator >= ( const os_collection& ) const

( const void* ) const

os_int32

os_int32

os_collection

operator = ( const os_set& ) const

( const os_collection& ) const

( const void* ) const

os_set&

os_set&

os_set

os_set

Name Arguments Returns Defined By

Release 6.3 255

Page 256: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_set

operator |= ( const os_collection& ) const

( const void* ) const

os_set&

os_set&

os_set

operator | ( const os_collection& ) const

( const void* ) const

os_set&

os_set&

os_collection

operator &= ( const os_collection& ) const

(const void*) const

os_set&

os_set&

os_set

operator & ( const os_collection& ) const

( const void* ) const

os_set&

os_set&

os_collection

operator –= ( const os_collection& ) const

( const void* ) const

os_set&

os_set&

os_set

operator - ( const os_collection& ) const

( const void* ) const

os_set&

os_set&

os_collection

os_set ( )

( os_int32 )

( const os_set& )

( const os_collection& )

os_set

pick ( ) const

( const os_index_path&, const os_coll_range& ) const

void*

void*

os_collection

query ( char *element_type_name, char *query_string, os_database *schema_database = 0, char* filename, os_unsigned_int32 line ) const

( const os_bound_query& ) const

os_collection&

os_collection&

os_collection

query_pick ( char *element_type_name, char *query_string, os_database *schema_database = 0, char* filename, os_unsigned_int32 line ) const

( const os_bound_query& ) const

void*

void*

os_collection

remove ( const void* ) os_int32 os_collection

remove_at ( const os_cursor& ) void os_collection

replace_at ( const void*, const os_cursor& )

void* os_collection

retrieve ( const os_cursor& ) const void* os_collection

Name Arguments Returns Defined By

256 C++ Collections Guide and Reference

Page 257: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 8: Class Reference

os_set enumerators

The following table lists the enumerators inherited by os_set from os_collection.

Assignment Operator SemanticsAssignment operator semantics are described for the following functions in terms of insert operations into the target collection. The actual implementation of the assignment might be different, while still maintaining the associated semantics.

os_set::operator =()os_set &operator =(const os_set &s);

Copies the contents of the collection s into the target collection and returns the target collection. The copy is performed by effectively clearing the target, iterating over the source collection, and inserting each element into the target collection. The iteration is ordered if the source collection is ordered. The target collection semantics are enforced as usual during the insertion process.

os_set &operator =(const void *e);

Clears the target collection, inserts the element e into the target collection, and returns the target collection.

os_set::operator |=()os_set &operator |=(const os_set &s);

Inserts the elements contained in s into the target collection and returns the target collection.

os_set &operator |=(const void *e);

Inserts the element e into the target collection and returns the target collection.

os_set::operator &=()os_set &operator &=(const os_set &s);

For each element in the target collection, reduces the count of the element in the target to the minimum of the counts in the source and target collections. If the collection is ordered and contains duplicates, it does so by retaining the appropriate number of leading elements. It returns the target collection.

os_set &operator &=(const void *e);

Name Inherited From

allow_duplicates os_collection

allow_nulls os_collection

EQ os_collection

GT os_collection

LT os_collection

maintain_order os_collection

Release 6.3 257

Page 258: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_set

If e is present in the target, converts the target into a collection containing just the element e. Otherwise, it clears the target collection. It returns the target collection.

os_set::operator –=()os_set &operator –=(const os_set &s);

For each element in the collection s, removes s.count(e) occurrences of the element from the target collection. If the collection is ordered, it is the first s.count(e) elements that are removed. It returns the target collection.

os_set &operator –=(const void *e);

Removes the element e from the target collection. If the collection is ordered, it is the first occurrence of the element that is removed from the target collection. It returns the target collection.

os_set::optimized_set Possible argument to the os_set constructor. This option should be used when the set is transient and is expected to hold persistent element pointers. This option will increase performance by creating a hard-pointer-based set.

You can also set this flag from the command line you use to compile your application. For more information, see Compiling for Collections Optimization on page 39.

os_set::os_set()os_set( );

Returns an empty set.

os_set(os_int32 size);

Returns an empty set whose initial implementation is based on the expectation that the size argument indicates the approximate usual cardinality of the set, once the set has been loaded with elements.

os_set(os_int32 size, os_set_type option);

Use this overloading if you are constructing a transient set that will hold persistent element pointers; specify os_set::optimized_set for the option argument. This option will increase performance by creating a hard-pointer-based set.

The size argument has the same meaning as for the previous overloading of os_set().

os_set(const os_set&);

Returns a set that results from assigning the specified set to an empty set.

os_set(const os_collection&);

Returns a set that results from assigning the specified collection to an empty set.

258 C++ Collections Guide and Reference

Page 259: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 9Macros and User-Defined Functions Reference

Dictionary macros

OS_MARK_DICTIONARY() 260

OS_MARK_NLIST() 260

OS_MARK_NLIST_PT() 261

OS_MARK_QUERY_FUNCTION() 261

OS_MARK_QUERY_FUNCTION_WITH_NAMESPACE() 262

OS_TRANSIENT_DICTIONARY() 262

OS_TRANSIENT_DICTIONARY_NOKEY() 263

OS_TRANSIENT_NLIST() 263

OS_TRANSIENT_NLIST_NO_BLOCK() 264

os_assign_function() 265

os_assign_function_body() 265

Index and query macros

os_index() 265

os_index_key() 266

os_index_key_hash_function() 266

os_index_key_rank_function() 267

os_indexable_body() 267

OS_INDEXABLE_LINKAGE() 268

os_indexable_member() 268

os_query_function() 269

os_query_function_body() 270

os_query_function_body_returning_ref() 270

os_query_function_body_with_namespace() 270

os_query_function_returning_ref() 271

Relationship macros

os_rel_1_1_body() 271

os_rel_1_m_body() 272

os_rel_m_1_body() 273

os_rel_m_m_body() 274

os_rel_1_1_body_options() 275

os_rel_1_m_body_options() 276

Release 6.3 259

Page 260: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

OS_MARK_DICTIONARY()

os_rel_m_1_body_options() 277

os_rel_m_m_body_options() 278

os_relationship_1_1() 280

os_relationship_1_m() 281

OS_RELATIONSHIP_LINKAGE() 282

os_relationship_m_1() 282

os_relationship_m_m() 283

OS_MARK_DICTIONARY()If you use persistent dictionaries, or any combination of persistent and transient dictionaries, you must call the macro OS_MARK_DICTIONARY() for each key-type/element-type pair that you use.

Form of the call OS_MARK_DICTIONARY(key_type, element_type)

Put these calls in the same function with your calls to OS_MARK_SCHEMA_TYPE(). For example:

/*** schema.cc ***/

#include <ostore/ostore.hh>#include <ostore/coll.hh>#include <ostore/coll/dict_pt.hh>#include <ostore/manschem.hh>#include "dnary.hh"

OS_MARK_DICTIONARY(void*,Course*); OS_MARK_DICTIONARY(int,Employee**); OS_MARK_SCHEMA_TYPE(Course); OS_MARK_SCHEMA_TYPE(Employee); OS_MARK_SCHEMA_TYPE(Department);

For pointer keys, specify void* as the key_type.

For class keys, the class must have a destructor, and you must register rank and hash functions for the class.

If you use transient dictionaries, you must call the macro OS_TRANSIENT_DICTIONARY(). The arguments are the same as for OS_MARK_DICTIONARY(), but you call OS_TRANSIENT_DICTIONARY() at file scope in an application source file, rather than at function scope in a schema source file.

OS_MARK_NLIST()If you use a persistent os_nlist, you must call the macro OS_MARK_NLIST for each set of os_nlist parameters that you use.

Form of the call OS_MARK_NLIST(num_ptrs_in_head,num_ptrs_in_block)

260 C++ Collections Guide and Reference

Page 261: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 9: Macros and User-Defined Functions Reference

Put these calls in the same function with your calls to OS_MARK_SCHEMA_TYPE(). You must include the header file <ostore/coll/nlist.hh>. For example:

/*** schema.cc ***/OS_MARK_NLIST(8,16);OS_MARK_NLIST(4,20);

If you use os_nlist transiently, you must call the macro OS_TRANSIENT_NLIST(). If you use a combination of persistent and transient os_nlists, it is sufficient to just call OS_MARK_NLIST() for each unique set of template parameters.

OS_MARK_NLIST_PT()If you use a persistent os_nList, you must call the macro OS_MARK_NLIST_PT for each set of os_nList parameters that you use.

Form of the call OS_MARK_NLIST_PT(E,num_ptrs_in_head,num_ptrs_in_block)

Put these calls in the same function with your calls to OS_MARK_SCHEMA_TYPE(). You must include the header file <ostore/coll/nlist.hh>. For example:

/*** schema.cc ***/OS_MARK_NLIST_PT(Object*,8,16);OS_MARK_NLIST_PT(Object*,4,20);OS_MARK_NLIST_PT(X*,4,20);

If you use os_nList transiently, you must call the macro OS_TRANSIENT_NLIST(). If you use a combination of persistent and transient os_nLists, it is sufficient to just call OS_MARK_NLIST_PT() for each unique set of template parameters.

OS_MARK_QUERY_FUNCTION()Applications that use a member function in a query or path string must call this macro.

Form of the call OS_MARK_QUERY_FUNCTION(class,func)

class is the name of the class that defines the member function.

func is the name of the member function.

The OS_MARK_QUERY_FUNCTION() and OS_MARK_SCHEMA_TYPE() macros must be invoked in the schema source file. No white space must appear in the argument list of OS_MARK_QUERY_FUNCTION().

Note If the member function is defined by a class that is declared in a namespace, you must use the OS_MARK_QUERY_FUNCTION_WITH_NAMESPACE() macro, as described below.

Release 6.3 261

Page 262: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

OS_TRANSIENT_DICTIONARY()

OS_MARK_QUERY_FUNCTION_WITH_NAMESPACE()

Applications that use a member function in a query or path string must call this macro instead of the OS_MARK_QUERY_FUNCTION() macro if the function is defined by a class that is declared within a namespace.

Form of the call OS_MARK_QUERY_FUNCTION_WITH_NAMESPACE(namespace,class,func)

namespace is the name of the namespace in which class is declared.

class is the name of the class that defines func.

func is the name of the member function.

The OS_MARK_QUERY_FUNCTION_WITH_NAMESPACE() and OS_MARK_SCHEMA_TYPE() macros must be invoked in the schema source file outside any namespace.

As an example, consider the class A, which defines the function get_x(). A is declared in a namespace called theNamespace, and get_x() is used in a query. The schema source file must contain the following lines:

OS_MARK_SCHEMA_TYPE(theNamespace::A) OS_MARK_QUERY_FUNCTION_WITH_NAMESPACE(theNamespace,A,get_x)

As shown in the example, no white space must appear in the argument list of OS_MARK_QUERY_FUNCTION_WITH_NAMESPACE().

Note If the defining class is not declared in a namespace, you can use the OS_MARK_QUERY_FUNCTION() macro; see OS_MARK_QUERY_FUNCTION() on page 261.

OS_TRANSIENT_DICTIONARY()If you use only transient dictionaries, you must call the macro OS_TRANSIENT_DICTIONARY() for each key-type/element-type pair that you use.

Note Do not call OS_TRANSIENT_DICTIONARY() for dictionaries with the same key marked persistently. Calling the macro in this case produces error messages at link time.

Form of the call OS_TRANSIENT_DICTIONARY(key_type, element_type)

Here are some examples:

OS_TRANSIENT_DICTIONARY(void*,Course*);

OS_TRANSIENT_DICTIONARY(int,Employee**);

Put these calls at file scope in an application source file.

For pointer keys, specify void* as the key_type.

For class keys, the class must have an operator= and a destructor that zeroes out any pointers in the key object.

262 C++ Collections Guide and Reference

Page 263: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 9: Macros and User-Defined Functions Reference

If a transient os_Dictionary is instantiated and OS_TRANSIENT_DICTIONARY() is missing, _Rhash_pt<KEYTYPE>::get_os_typespec() and _Dict_pt_slot<KEYTYPE>::get_os_typespec() are undefined at link time.

Using user-defined classes

In order to use a user-defined class as a key, you must have get_os_typespec() declared and defined as follows, where KEYTYPE is the name of the user-defined class:

{ return new os_typespec("KEYTYPE"); }

OS_TRANSIENT_DICTIONARY_NOKEY()If you use only transient dictionaries, you must call the macro OS_TRANSIENT_DICTIONARY_NOKEY() in certain cases where you have more than one dictionary defined with the same key type.

Form of the call OS_TRANSIENT_DICTIONARY_NOKEY(key_type)

OS_TRANSIENT_DICTIONARY() defines stubs for get_os_typespec() member functions of internal data structures parameterized by either the key type and the value type, or by just the key type. If you have in your application more than one dictionary with the same key type, specifying OS_TRANSIENT_DICTIONARY() multiple times will result in multiply-defined symbols at link time. Instead, use OS_TRANSIENT_DICTIONARY_NOKEY(), which defines just the get_os_typespec() functions for internal data structures parameterized by both the key and value type.

For example, if you had

os_Dictionary<int, Object1*> d1;

os_Dictionary<int, Object2*> d2;

You would use

OS_TRANSIENT_DICTIONARY(int, Object1*);OS_TRANSIENT_DICTIONARY_NOKEY(int, Object2*);

Put these calls at file scope in an application source file.

For pointer keys, specify void* as key_type.

For class keys, the class must have a destructor.

The user-defined class that is used as a key must have get_os_typespec() declared and defined. get_os_typespec() should be defined as follows, where KEYTYPE is the name of the user-defined class:

{ return new os_typespec("KEYTYPE"); }

OS_TRANSIENT_NLIST()If you use only transient os_nlist and os_nList, you must call the macro OS_TRANSIENT_NLIST() for each unique set of template parameters given to your os_

Release 6.3 263

Page 264: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

OS_TRANSIENT_NLIST_NO_BLOCK()

nlist or os_nList. This is true unless there is a persistent os_nlist or os_nList with the same template parameters and for which you have called OS_MARK_NLIST or OS_MARK_NLIST_PT in your schema source file. In this case, the macro is not needed and will produce an error message at link time.

Form of the call OS_TRANSIENT_NLIST(num_ptrs_in_head,num_ptrs_in_block)

Here are some examples:

os_nlist(8,16) nl1;os_nList(Object*,8,20) nl2;...OS_TRANSIENT_NLIST(8,16)OS_TRANSIENT_NLIST(8,20)

Put the calls to OS_TRANSIENT_NLIST at file scope in an application source file.

If a transient os_nlist or os_nList is instantiated and OS_TRANSIENT_NLIST() is missing, os_nlist<num_ptrs_in_head,num_ptrs_in_block>::get_os_typespec() and os_chained_list_block_pt<num_ptrs_in_block>::get_os_typespec() are undefined at link time.

OS_TRANSIENT_NLIST_NO_BLOCK()If you use a transient os_nlist or os_nList, you must call the macro OS_TRANSIENT_NLIST_NO_BLOCK in certain cases where you have more than one os_nlist or os_nList with the same num_ptrs_in_block template parameter.

Form of the call OS_TRANSIENT_NLIST_NO_BLOCK(num_ptrs_in_head)

OS_TRANSIENT_NLIST defines stubs for get_os_typespec() member functions of internal data structures parameterized by either the num_ptrs_in_head and num_ptrs_in_block arguments, or by just the num_ptrs_in_block argument. If you have in your application more than one os_nlist or os_nList with the same num_ptrs_in_block argument, specifying OS_TRANSIENT_NLIST multiple times will result in multiply defined symbols at link time. Instead, use OS_TRANSIENT_NLIST for one set of parameters, and use OS_TRANSIENT_NLIST_NO_BLOCK for any others with the same value for num_ptrs_in_block.

Here are some examples:

os_nlist(8,16) nl1;os_nlist(8,16) nl2;os_nlist(4,16) nl3;...OS_TRANSIENT_NLIST(8,16)OS_TRANSIENT_NLIST_NO_BLOCK(4)

Put the calls to OS_TRANSIENT_NLIST_NO_BLOCK at file scope in an application source file.

264 C++ Collections Guide and Reference

Page 265: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 9: Macros and User-Defined Functions Reference

os_assign_function()This macro is used to register an assignment function for an ordered os_Dictionary key class or for an ordered or unordered index key class. Use this macro to make it possible to use a key class that contains a soft pointer or to use an assignment operator instead of memcpy when inserting or reorganizing objects in the dictionary or index.

Use this macro in conjunction with the macro os_assign_function_body() on page 265. This function must be called after os_collection::initialize().

To use the collections facility, you must include the file <ostore/coll.hh> after including <ostore/ostore.hh>.

Form of the call os_assign_function(class)

class is the class used as a key.

The os_assign_function() macro should be invoked before creating the ordered os_Dictionary or adding the index.

os_assign_function_body()This macro is used to create an assignment function body for an ordered os_Dictionary key class or for an ordered or unordered index key class. The function body consists of an operator= statement. This macro makes it possible to use a key class that contains a soft pointer or to use an assignment operator instead of memcpy when inserting or reorganizing objects in the dictionary or index.

Use this macro in conjunction with the macro os_assign_function() on page 265.

To use the collections facility, you must include the file <ostore/coll.hh> after including <ostore/ostore.hh>.

Form of the call os_assign_function_body(class)

class is the class used as a key.

The os_assign_function_body() macro should be invoked at module level in a source file (for example, the file containing the definition of the member function).

os_index()This macro is used to designate a class’s os_backptr-valued member when you call make_link() and break_link() or define indexable members. The os_backptr member is used to establish other members of the class as indexable. Bit-field members cannot be indexable.

To use the collections facility, you must include the file <ostore/coll.hh> after including <ostore/ostore.hh>.

Release 6.3 265

Page 266: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_index_key()

Form of the call os_index(class,member)

class is the class defining the os_backptr data member.

member is the name of the os_backptr member.

Caution The macro arguments are used (among other things) to concatenate unique names. The details of macro preprocessing differ from compiler to compiler, and in some cases it is necessary to enter these macro arguments without white space to ensure that the argument concatenation will work correctly.

os_index_key()This macro is used to register user-defined rank and hash functions with ObjectStore.

To use the collections facility, you must include the file <ostore/coll.hh> after including <ostore/ostore.hh>. This function must be called after os_collection::initialize().

Form of the call os_index_key(class,rank_function,hash_function)

class is the class whose instances are ranked or hashed by the specified functions.

rank_function is a user-defined function that, for any pair of instances of class, provides an ordering indicator for the instances, much as strcmp() does for arrays of characters. You must supply this function. The rank function should return one of os_collection::LT, os_collection::GT, or os_collection::EQ. See Supplying Rank and Hash Functions on page 78.

hash_function is a user-defined function that, for each instance of class, returns an os_unsigned_int32 value that can be used as a key in a hash table. Supplying this function is optional. If you do not supply a hash function for the class, specify 0 as the hash function argument.

Caution The macro arguments are used (among other things) to concatenate unique names. The details of macro preprocessing differ from compiler to compiler, and in some cases it is necessary to enter these macro arguments without white space to ensure that the argument concatenation will work correctly.

os_index_key_hash_function()This macro is used to register user-defined hash functions with ObjectStore. Use it only to replace a hash function registered previously.

To use the collections facility, you must include the file <ostore/coll.hh> after including <ostore/ostore.hh>. This function must be called after os_collection::initialize().

Form of the call os_index_key_hash_function(class,hash_function)

class is the class whose instances are hashed by the specified function.

266 C++ Collections Guide and Reference

Page 267: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 9: Macros and User-Defined Functions Reference

hash_function is a user-defined function that, for each instance of class, returns an os_unsigned_int32 value that can be used as a key in a hash table.

Caution The macro arguments are used (among other things) to concatenate unique names. The details of macro preprocessing differ from compiler to compiler, and in some cases it is necessary to enter these macro arguments without white space to ensure that the argument concatenation will work correctly.

os_index_key_rank_function()This macro is used to register user-defined rank functions with ObjectStore. Use it only to replace a rank function registered previously.

To use the collections facility, you must include the file <ostore/coll.hh> after including <ostore/ostore.hh>. This function must be called after os_collection::initialize().

Form of the call os_index_key_rank_function(class,rank_function)

class is the class whose instances are ranked by the specified function. class can also be char* when you register os_strcoll_for_char_pointer(), and char[] when you register os_strcoll_for_char_array(). These versions of strcoll(), provided by ObjectStore, will be used, if registered, instead of strcmp() to support indexes keyed by char* or char[].

rank_function is a user-defined function that, for any pair of instances of class, provides an ordering indicator for the instances, much as strcmp() does for arrays of characters. The rank function should return one of os_collection::LT, os_collection::GT, or os_collection::EQ. See Supplying Rank and Hash Functions on page 78.

Caution The macro arguments are used (among other things) to concatenate unique names. The details of macro preprocessing differ from compiler to compiler, and in some cases it is necessary to enter these macro arguments without white space to ensure that the argument concatenation will work correctly.

os_indexable_body()This macro is used to instantiate accessor functions for an indexable data member. Calls to this macro should appear at the top level in the source file associated with the class defining the member.

To use this macro, you must include the file <ostore/coll.hh> after including <ostore/ostore.hh>.

The actual value type of an indexable data member is a special class whose instances encapsulate the member’s apparent value. This implicitly defined class defines operator =() (for setting the apparent value) and a conversion operator for converting its instances to instances of the apparent value type (for getting the

Release 6.3 267

Page 268: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

OS_INDEXABLE_LINKAGE()

apparent value). Under most circumstances, these operators make the encapsulating objects transparent.

The implicitly defined class also defines the member functions getvalue(), which returns a const reference to the apparent value, and setvalue(), which takes an instance of the apparent value type as argument. These functions can always be used to set and get the indexable member’s apparent value explicitly.

Form of the call os_indexable_body(class,member,value_type,index)

class is the class defining the data member being declared.

member is the name of the member being declared.

value_type is the (apparent) value type of the indexable member.

index is a call to the macro os_index(), indicating the name of the defining class’s os_backptr member.

Caution The first three macro arguments are used (among other things) to concatenate unique names for the encapsulating class and its accessor functions. The details of macro preprocessing differ from compiler to compiler, and in some cases it is necessary to enter these macro arguments without white space to ensure that the argument concatenation will work correctly.

OS_INDEXABLE_LINKAGE() Note This macro is for use on Windows platforms only.

Specifies the linkage for classes generated by the os_indexable_xxx macros. This macro can be used with component schemas on Windows platforms. For example, you could define the macro as Microsoft's __declspec (dllexport) to allow one DLL to create a subclass of a class defined in another DLL when there are relationship members.

You must define OS_INDEXABLE_LINKAGE() before including <ostore/coll.hh>. For example:

...#define OS_INDEXABLE_LINKAGE __declspec(dllexport)#include <ostore/coll.hh>

If the macro is not defined, the default is blank.

os_indexable_member()This macro is used to establish a data member as indexable in order to perform automatic index maintenance. Field members cannot be indexable.

To use the collections facility, you must include the file <ostore/coll.hh> after including <ostore/ostore.hh>.

268 C++ Collections Guide and Reference

Page 269: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 9: Macros and User-Defined Functions Reference

The macro call is used instead of the value type in the member declaration.

class class-name { ... macro-call member-name; ...};

The actual value type of an indexable data member is a special class whose instances encapsulate the member’s apparent value. This implicitly defined class defines operator =() (for setting the apparent value) and a conversion operator for converting its instances to instances of the apparent value type (for getting the apparent value). Under most circumstances, these operators make the encapsulating objects transparent.

The implicitly defined class also defines the member functions getvalue(), which returns a const reference to the apparent value, and setvalue(), which takes an instance of the apparent value type as argument. These functions can always be used to set and get the indexable member’s apparent value explicitly.

Form of the call os_indexable_member(class,member,value_type)

class is the class defining the data member being declared.

member is the name of the member being declared.

value_type is the (apparent) value type of the member being declared.

Caution The first two macro arguments are used (among other things) to concatenate unique names for the encapsulating class and its accessor functions. The details of macro preprocessing differ from compiler to compiler, and in some cases it is necessary to enter these macro arguments without white space to ensure that the argument concatenation will work correctly.

os_query_function()Applications that use a member function (which does or does not return a reference) in a query or path string must call this macro.

Form of the call os_query_function(class,func,return_type)

class is the name of the class defining the member function.

func is the name of the member function itself.

return_type names the type of value returned by the member function.

The os_query_function() macro should be invoked at module level in a header file (for example, the file containing the definition of the class that declares the member function). No white space should appear in the argument list.

Release 6.3 269

Page 270: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_query_function_body()

os_query_function_body()Applications that use a member function in a query or path string must call this macro.

Form of the call os_query_function_body(class,func,return_type,bpname)

class is the name of the class that defines the member function.

func is the name of the member function itself.

return_type names the type of value returned by the member function.

bpname is the name of the os_backptr-valued member of class.

The os_query_function_body() macro should be invoked at module level in a source file (for example, the file containing the definition of the member function). No white space should appear in the argument list.

os_query_function_body_returning_ref()This macro enables users to register a query function that returns a reference. The application that uses this member function in a query must call os_query_function_body_returning_ref().

Form of the call os_query_function_body_returning_ref(class,func,return_type, bpname)

class is the name of the class defining the member function.

func is the name of the member function itself.

return_type names the type of value returned by the member function. The way to use this is to pass just return_type, not return_type&, to the return_type arguments of the macro.

bpname is the name of the os_backptr-valued member of class.

os_query_function_body_with_namespace()Applications that use a member function in a query or path string, where the function is a member of a class encapsulated within a namespace, must call this macro.

Form of the call os_query_function_body_with_namespace( class,qualified_class,return_type,bpname)

class is the name of the class that defines the member function

qualified_class is the name of the class, qualified with its namespace, for example. NameSpace::class_name, that defines the member function

270 C++ Collections Guide and Reference

Page 271: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 9: Macros and User-Defined Functions Reference

return_type names the type of value returned by the member function

bpname is the name of the os_backptr-valued member of class

The os_query_function_body_with_namespace() macro should be invoked at module level in a source file (for example, the file containing the definition of the member function). No white space should appear in the argument list.

os_query_function_returning_ref()The application that uses this member function, returning a reference, in a query must call os_query_function_returning_ref(). A call to this macro has the form

Form of the call os_query_function_returning_ref(class,func,return_type)

class is the name of the class defining the member function.

func is the name of the member function itself.

return_type names the type of value returned by the member function. The way to use this is to pass just return_type, not return_type&, to the macro return_type arguments.

os_rel_1_1_body()ObjectStore allows the user to model binary relationships with pointer-valued (or collection-of-pointer-valued) data members that maintain the referential integrity of their inverse data members. You implement this inverse maintenance by defining an embedded relationship class that encapsulates the pointer (or collection-of-pointer) so that it can intercept updates to the encapsulated value and perform the necessary inverse maintenance tasks. The encapsulated-pointer values are stored as soft pointers so as to maintain the values across address space release and transactions.

Required include files

To use this macro, you must include the file <ostore/relat.hh> after including <ostore/ostore.hh>. If you also include <ostore/coll.hh>, include <ostore/relat.hh> after both <ostore/ostore.hh> and <ostore/coll.hh>.

The actual value type of a data member with an inverse is a special class whose instances encapsulate the member’s apparent value. This implicitly defined class defines operator =() (for setting the apparent value), as well as operator ->(), operator *(), and a conversion operator for converting its instances to instances of the apparent value type (for getting the apparent value). Under most circumstances, these operators make the encapsulating objects transparent.

The implicitly defined class also defines the member functions getvalue(), which returns the apparent value, and setvalue(), which takes an instance of the apparent value type as argument. These functions can always be used to set and get the member’s apparent value explicitly.

Release 6.3 271

Page 272: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_rel_1_m_body()

This macro is used to instantiate accessor functions for a single-valued data member with a single-valued inverse data member. Calls to this macro should appear at the top level in a source file associated with the class defining the member.

Form of the call os_rel_1_1_body(class,member,inv_class,inv_mem)

class is the class defining the data member being declared.

member is the name of the member being declared.

inv_class is the name of the class that defines the inverse member.

inv_mem is the name of the inverse member.

Caution The macro arguments are used (among other things) to concatenate unique names for the encapsulating relationship class and its accessor functions. The details of macro preprocessing differ from compiler to compiler, and in some cases it is necessary to enter these macro arguments without white space to ensure that the argument concatenation will work correctly.

os_rel_1_m_body()ObjectStore allows the user to model binary relationships with pointer-valued (or collection-of-pointer-valued) data members that maintain the referential integrity of their inverse data members. You implement this inverse maintenance by defining an embedded relationship class, which encapsulates the pointer (or collection-of-pointer) so that it can intercept updates to the encapsulated value and perform the necessary inverse maintenance tasks. The encapsulated-pointer values are stored as soft pointers so as to maintain the values across address space release and transactions.

Required include files

To use this macro, you must include the file <ostore/relat.hh> after including <ostore/ostore.hh> and <ostore/coll.hh>.

The actual value type of a data member with an inverse is a special class whose instances encapsulate the member’s apparent value. This implicitly defined class defines operator =() (for setting the apparent value), as well as operator ->(), operator *(), and a conversion operator for converting its instances to instances of the apparent value type (for getting the apparent value). Under most circumstances, these operators make the encapsulating objects transparent.

The implicitly defined class also defines the member functions getvalue(), which returns the apparent value, and setvalue(), which takes an instance of the apparent value type as argument. These functions can always be used to set and get the member’s apparent value explicitly.

This macro is used to instantiate accessor functions for a single-valued data member with a many-valued inverse data member. Calls to this macro should appear at the top level in the source file associated with the class defining the member.

Form of the call os_rel_1_m_body(class,member,inv_class,inv_mem)

class is the class defining the data member being declared.

272 C++ Collections Guide and Reference

Page 273: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 9: Macros and User-Defined Functions Reference

member is the name of the member being declared.

inv_class is the name of the class that defines the inverse member.

inv_mem is the name of the inverse member.

Caution The macro arguments are used (among other things) to concatenate unique names for the embedded relationship class and its accessor functions. The details of macro preprocessing differ from compiler to compiler, and in some cases it is necessary to enter these macro arguments without white space to ensure that the argument concatenation will work correctly.

os_rel_m_1_body()ObjectStore allows the user to model binary relationships with pointer-valued (or collection-of-pointer-valued) data members that maintain the referential integrity of their inverse data members. You implement this inverse maintenance by defining an embedded relationship class, which encapsulates the pointer (or collection-of-pointer) so that it can intercept updates to the encapsulated value and perform the necessary inverse maintenance tasks. The encapsulated-pointer values are stored as soft pointers so as to maintain the values across address space release and transactions.

Required include files

To use this macro, you must include the file <ostore/relat.hh> after including <ostore/ostore.hh> and <ostore/coll.hh>.

The actual value type of a data member with an inverse is a special class whose instances encapsulate the member’s apparent value. This implicitly defined class defines operator =() (for setting the apparent value), as well as operator ->(), operator *(), and a conversion operator for converting its instances to instances of the apparent value type (for getting the apparent value). Under most circumstances, these operators make the encapsulating objects transparent.

The implicitly defined class also defines the member functions getvalue(), which returns the apparent value, and setvalue(), which takes an instance of the apparent value type as argument. These functions can always be used to set and get the member’s apparent value explicitly.

This macro is used to instantiate accessor functions for a many-valued data member with a single-valued inverse data member. Calls to this macro should appear at the top level in the source file associated with the class defining the member.

Form of the call os_rel_m_1_body(class,member,inv_class,inv_mem)

class is the class defining the data member being declared.

member is the name of the member being declared.

inv_class is the name of the class that defines the inverse member.

inv_mem is the name of the inverse member.

Release 6.3 273

Page 274: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_rel_m_m_body()

Caution The macro arguments are used (among other things) to concatenate unique names for the embedded relationship class and its accessor functions. The details of macro preprocessing differ from compiler to compiler, and in some cases it is necessary to enter these macro arguments without white space to ensure that the argument concatenation will work correctly.

os_rel_m_m_body()ObjectStore allows the user to model binary relationships with pointer-valued (or collection-of-pointer-valued) data members that maintain the referential integrity of their inverse data members. You implement this inverse maintenance by defining an embedded relationship class, which encapsulates the pointer (or collection-of-pointer) so that it can intercept updates to the encapsulated value and perform the necessary inverse maintenance tasks. The encapsulated-pointer values are stored as soft pointers so as to maintain the values across address space release and transactions.

Required include files

To use this macro, you must include the file <ostore/relat.hh> after including <ostore/ostore.hh> and <ostore/coll.hh>.

The actual value type of a data member with an inverse is a special class whose instances encapsulate the member’s apparent value. This implicitly defined class defines operator =() (for setting the apparent value), as well as operator ->(), operator *(), and a conversion operator for converting its instances to instances of the apparent value type (for getting the apparent value). Under most circumstances, these operators make the encapsulating objects transparent.

The implicitly defined class also defines the member functions getvalue(), which returns the apparent value, and setvalue(), which takes an instance of the apparent value type as argument. These functions can always be used to set and get the member’s apparent value explicitly.

This macro is used to instantiate accessor functions for a many-valued data member with a many-valued inverse data member. Calls to this macro should appear at the top level in the source file associated with the class defining the member.

Form of the call os_rel_m_m_body(class,member,inv_class,inv_mem)

class is the class defining the data member being declared.

member is the name of the member being declared.

inv_class is the name of the class that defines the inverse member.

inv_mem is the name of the inverse member.

Caution The macro arguments are used (among other things) to concatenate unique names for the encapsulating relationship class and its accessor functions. The details of macro preprocessing differ from compiler to compiler, and in some cases it is necessary to enter these macro arguments without white space to ensure that the argument concatenation will work correctly.

274 C++ Collections Guide and Reference

Page 275: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 9: Macros and User-Defined Functions Reference

os_rel_1_1_body_options()ObjectStore allows the user to model binary relationships with pointer-valued (or collection-of-pointer-valued) data members that maintain the referential integrity of their inverse data members. You implement this inverse maintenance by defining an embedded relationship class, which encapsulates the pointer (or collection-of-pointer) so that it can intercept updates to the encapsulated value and perform the necessary inverse maintenance tasks. The encapsulated-pointer values are stored as soft pointers so as to maintain the values across address space release and transactions.

Required include files

To use this macro, you must include the file <ostore/relat.hh> after including <ostore/ostore.hh>. If you also include <ostore/coll.hh>, include <ostore/relat.hh> after both <ostore/ostore.hh> and <ostore/coll.hh>.

The actual value type of a data member with an inverse is a special class whose instances encapsulate the member’s apparent value. This implicitly defined class defines operator =() (for setting the apparent value), as well as operator ->(), operator *(), and a conversion operator for converting its instances to instances of the apparent value type (for getting the apparent value). Under most circumstances, these operators make the encapsulating objects transparent.

The implicitly defined class also defines the member functions getvalue(), which returns the apparent value, and setvalue(), which takes an instance of the apparent value type as argument. These functions can always be used to set and get the member’s apparent value explicitly.

This macro is used to instantiate accessor functions for a single-valued data member with a single-valued inverse data member, when deletion propagation is desired or when either member is indexable. Calls to this macro should appear at the top level in the source file associated with the class defining the member.

Form of the call os_rel_1_1_body_options(class,member,inv_class,inv_mem, deletion, index, inv_index)

class is the class defining the data member being declared.

member is the name of the member being declared.

inv_class is the name of the class that defines the inverse member.

inv_mem is the name of the inverse member.

deletion is either os_rel_propagate_delete or os_rel_dont_propagate_delete. By default, deleting an object that participates in a relationship automatically updates the other side of the relationship so that there are no dangling pointers to the deleted object. In some cases, however, the desired behavior is actually to delete the object on the other side of the relationship (for example, for subsidiary component objects). This behavior is specified with os_rel_propagate_delete.

Release 6.3 275

Page 276: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_rel_1_m_body_options()

index specifies whether the current member is indexable. For nonindexable members, use os_no_index. For indexable members, use a call to the macro os_index(), indicating the name of the defining class’s os_backptr member.

inv_index specifies whether the inverse member is indexable. For nonindexable members, use os_no_index. For indexable members, use a call to the macro os_index(), indicating the name of the defining class’s os_backptr member.

Caution The first four macro arguments are used (among other things) to concatenate unique names for the encapsulating relationship class and its accessor functions. The details of macro preprocessing differ from compiler to compiler, and in some cases it is necessary to enter these macro arguments without white space to ensure that the argument concatenation will work correctly. There should be no white space in the argument list between the opening parenthesis and the comma separating the fourth and fifth arguments.

os_rel_1_m_body_options()ObjectStore allows the user to model binary relationships with pointer-valued (or collection-of-pointer-valued) data members that maintain the referential integrity of their inverse data members. You implement this inverse maintenance by defining an embedded relationship class, which encapsulates the pointer (or collection-of-pointer) so that it can intercept updates to the encapsulated value and perform the necessary inverse maintenance tasks. The encapsulated-pointer values are stored as soft pointers so as to maintain the values across address space release and transactions.

Required include files

To use this macro, you must include the file <ostore/relat.hh> after including <ostore/ostore.hh> and <ostore/coll.hh>.

The actual value type of a data member with an inverse is a special class whose instances encapsulate the member’s apparent value. This implicitly defined class defines operator =() (for setting the apparent value), as well as operator ->(), operator *(), and a conversion operator for converting its instances to instances of the apparent value type (for getting the apparent value). Under most circumstances, these operators make the encapsulating objects transparent.

The implicitly defined class also defines the member functions getvalue(), which returns the apparent value, and setvalue(), which takes an instance of the apparent value type as argument. These functions can always be used to set and get the member’s apparent value explicitly.

This macro is used to instantiate accessor functions for a single-valued data member with a many-valued inverse data member, when deletion propagation is desired or when either member is indexable. Calls to this macro should appear at the top level in the source file associated with the class defining the member.

Form of the call os_rel_1_m_body_options(class,member,inv_class,inv_mem, deletion, index, inv_index)

class is the class defining the data member being declared.

276 C++ Collections Guide and Reference

Page 277: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 9: Macros and User-Defined Functions Reference

member is the name of the member being declared.

inv_class is the name of the class that defines the inverse member.

inv_mem is the name of the inverse member.

deletion is either os_rel_propagate_delete or os_rel_dont_propagate_delete. By default, deleting an object that participates in a relationship automatically updates the other side of the relationship so that there are no dangling pointers to the deleted object. In some cases, however, the desired behavior is actually to delete the object on the other side of the relationship (for example, for subsidiary component objects). This behavior is specified with os_rel_propagate_delete.

index specifies whether the current member is indexable. For nonindexable members, use os_no_index. For indexable members, use a call to the macro os_index(), indicating the name of the defining class’s os_backptr member.

inv_index specifies whether the inverse member is indexable. For nonindexable members, use os_no_index. For indexable members, use a call to the macro os_index(), indicating the name of the defining class’s os_backptr member. PSE Pro does not support indexable members.

Caution The first four macro arguments are used (among other things) to concatenate unique names for the encapsulating relationship class and its accessor functions. The details of macro preprocessing differ from compiler to compiler, and in some cases it is necessary to enter these macro arguments without white space to ensure that the argument concatenation will work correctly. There should be no white space in the argument list between the opening parenthesis and the comma separating the fourth and fifth arguments.

os_rel_m_1_body_options()ObjectStore allows the user to model binary relationships with pointer-valued (or collection-of-pointer-valued) data members that maintain the referential integrity of their inverse data members. You implement this inverse maintenance by defining an embedded relationship class, which encapsulates the pointer (or collection-of-pointer) so that it can intercept updates to the encapsulated value and perform the necessary inverse maintenance tasks. The encapsulated-pointer values are stored as soft pointers so as to maintain the values across address space release and transactions.

Required include files

To use this macro, you must include the file <ostore/relat.hh> after including <ostore/ostore.hh> and <ostore/coll.hh>.

The actual value type of a data member with an inverse is a special class whose instances encapsulate the member’s apparent value. This implicitly defined class defines operator =() (for setting the apparent value), as well as operator ->(), operator *(), and a conversion operator for converting its instances to instances of

Release 6.3 277

Page 278: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_rel_m_m_body_options()

the apparent value type (for getting the apparent value). Under most circumstances, these operators make the encapsulating objects transparent.

The implicitly defined class also defines the member functions getvalue(), which returns the apparent value, and setvalue(), which takes an instance of the apparent value type as argument. These functions can always be used to set and get the member’s apparent value explicitly.

This macro is used to instantiate accessor functions for a many-valued data member with a single-valued inverse data member, when deletion propagation is desired. Calls to this macro should appear at the top level in the source file associated with the class defining the member.

Form of the call os_rel_m_1_body_options(class,member,inv_class,inv_mem, deletion, index, inv_index)

class is the class defining the data member being declared.

member is the name of the member being declared.

inv_class is the name of the class that defines the inverse member.

inv_mem is the name of the inverse member.

deletion is either os_rel_propagate_delete or os_rel_dont_propagate_delete. By default, deleting an object that participates in a relationship automatically updates the other side of the relationship so that there are no dangling pointers to the deleted object. In some cases, however, the desired behavior is actually to delete the object on the other side of the relationship (for example, for subsidiary component objects). This behavior is specified with os_rel_propagate_delete.

index specifies whether the current member is indexable. For nonindexable members, use os_no_index.

inv_index specifies whether the inverse member is indexable. For nonindexable members, use os_no_index. For indexable members, use a call to the macro os_index(), indicating the name of the defining class’s os_backptr member.

Caution The first four macro arguments are used (among other things) to concatenate unique names for the encapsulating relationship class and its accessor functions. The details of macro preprocessing differ from compiler to compiler, and in some cases it is necessary to enter these macro arguments without white space to ensure that the argument concatenation will work correctly. There should be no white space in the argument list between the opening parenthesis and the comma separating the fourth and fifth arguments.

os_rel_m_m_body_options()ObjectStore allows the user to model binary relationships with pointer-valued (or collection-of-pointer-valued) data members that maintain the referential integrity of their inverse data members. You implement this inverse maintenance by defining an

278 C++ Collections Guide and Reference

Page 279: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 9: Macros and User-Defined Functions Reference

embedded relationship class, which encapsulates the pointer (or collection-of-pointer) so that it can intercept updates to the encapsulated value and perform the necessary inverse maintenance tasks. The encapsulated-pointer values are stored as soft pointers so as to maintain the values across address space release and transactions.

Required include files

To use this macro, you must include the file <ostore/relat.hh> after including <ostore/ostore.hh> and <ostore/coll.hh>.

The actual value type of a data member with an inverse is a special class whose instances encapsulate the member’s apparent value. This implicitly defined class defines operator =() (for setting the apparent value), as well as operator ->(), operator *(), and a conversion operator for converting its instances to instances of the apparent value type (for getting the apparent value). Under most circumstances, these operators make the encapsulating objects transparent.

The implicitly defined class also defines the member functions getvalue(), which returns the apparent value, and setvalue(), which takes an instance of the apparent value type as argument. These functions can always be used to set and get the member’s apparent value explicitly.

This macro is used to instantiate accessor functions for a many-valued data member with a many-valued inverse data member, when deletion propagation is desired or when either member is indexable. Calls to this macro should appear at the top level in the source file associated with the class defining the member.

Form of the call os_rel_m_m_body_options(class,member,inv_class,inv_mem, deletion, index, inv_index)

class is the class defining the data member being declared.

member is the name of the member being declared.

inv_class is the name of the class that defines the inverse member.

inv_mem is the name of the inverse member.

deletion is either os_rel_propagate_delete or os_rel_dont_propagate_delete. By default, deleting an object that participates in a relationship automatically updates the other side of the relationship so that there are no dangling pointers to the deleted object. In some cases, however, the desired behavior is actually to delete the object on the other side of the relationship (for example, for subsidiary component objects). This behavior is specified with os_rel_propagate_delete.

index specifies whether the current member is indexable. For nonindexable members, use os_no_index. For indexable members, use a call to the macro os_index(), indicating the name of the defining class’s os_backptr member, or use os_auto_index.

inv_index specifies whether the inverse member is indexable. For nonindexable members, use os_no_index.

Caution The first four macro arguments are used (among other things) to concatenate unique names for the encapsulating relationship class and its accessor functions. The details

Release 6.3 279

Page 280: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_relationship_1_1()

of macro preprocessing differ from compiler to compiler, and in some cases it is necessary to enter these macro arguments without white space to ensure that the argument concatenation will work correctly. There should be no white space in the argument list between the opening parenthesis and the comma separating the fourth and fifth arguments.

os_relationship_1_1()ObjectStore allows the user to model binary relationships with pointer-valued (or collection-of-pointer-valued) data members that maintain the referential integrity of their inverse data members. You implement this inverse maintenance by defining an embedded relationship class, which encapsulates the pointer (or collection-of-pointer) so that it can intercept updates to the encapsulated value and perform the necessary inverse maintenance tasks. The encapsulated-pointer values are stored as soft pointers so as to maintain the values across address space release and transactions.

Required include files

To use this macro, you must include the file <ostore/relat.hh> after including <ostore/ostore.hh>. If you also include <ostore/coll.hh>, include <ostore/relat.hh> after both <ostore/ostore.hh> and <ostore/coll.hh>.

The actual value type of a data member with an inverse is a special class whose instances encapsulate the member’s apparent value. This implicitly defined class defines operator =() (for setting the apparent value), as well as operator ->(), operator *(), and a conversion operator for converting its instances to instances of the apparent value type (for getting the apparent value). Under most circumstances, these operators make the encapsulating objects transparent.

The implicitly defined class also defines the member functions getvalue(), which returns the apparent value, and setvalue(), which takes an instance of the apparent value type as argument. These functions can always be used to set and get the member’s apparent value explicitly.

This macro is used to declare a single-valued data member with a single-valued inverse data member. The macro call is used instead of the value type in the member declaration.

class class-name { ... macro-call member-name; ...};

Form of the call os_relationship_1_1(class,member,inv_class,inv_mem,value_type)

class is the class defining the data member being declared.

member is the name of the member being declared.

inv_class is the name of the class that defines the inverse member.

inv_mem is the name of the inverse member.

280 C++ Collections Guide and Reference

Page 281: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 9: Macros and User-Defined Functions Reference

value_type is the value type of the member being declared.

Caution The first four macro arguments are used (among other things) to concatenate unique names for the encapsulating relationship class and its accessor functions. The details of macro preprocessing differ from compiler to compiler, and in some cases it is necessary to enter these macro arguments without white space to ensure that the argument concatenation will work correctly. There should be no white space in the argument list between the opening parenthesis and the comma separating the fourth and fifth arguments.

os_relationship_1_m()ObjectStore allows the user to model binary relationships with pointer-valued (or collection-of-pointer-valued) data members that maintain the referential integrity of their inverse data members. You implement this inverse maintenance by defining an embedded relationship class, which encapsulates the pointer (or collection-of-pointer) so that it can intercept updates to the encapsulated value and perform the necessary inverse maintenance tasks. The encapsulated-pointer values are stored as soft pointers so as to maintain the values across address space release and transactions.

Required include files

To use this macro, you must include the file <ostore/relat.hh> after including <ostore/ostore.hh> and <ostore/coll.hh>.

The actual value type of a data member with an inverse is a special class whose instances encapsulate the member’s apparent value. This implicitly defined class defines operator =() (for setting the apparent value), as well as operator ->(), operator *(), and a conversion operator for converting its instances to instances of the apparent value type (for getting the apparent value). Under most circumstances, these operators make the encapsulating objects transparent.

The implicitly defined class also defines the member functions getvalue(), which returns the apparent value, and setvalue(), which takes an instance of the apparent value type as argument. These functions can always be used to set and get the member’s apparent value explicitly.

This macro is used to declare a single-valued data member with a many-valued inverse data member. The macro call is used instead of the value type in the member declaration.

class class-name { ... macro-call member-name; ...};

Form of the call os_relationship_1_m(class,member,inv_class,inv_mem,value_type)

class is the class defining the data member being declared.

member is the name of the member being declared.

Release 6.3 281

Page 282: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

OS_RELATIONSHIP_LINKAGE()

inv_class is the name of the class that defines the inverse member.

inv_mem is the name of the inverse member.

value_type is the value type of the member being declared.

Caution The first four macro arguments are used (among other things) to concatenate unique names for the encapsulating relationship class and its accessor functions. The details of macro preprocessing differ from compiler to compiler, and in some cases it is necessary to enter these macro arguments without white space to ensure that the argument concatenation will work correctly. There should be no white space in the argument list between the opening parenthesis and the comma separating the fourth and fifth arguments.

OS_RELATIONSHIP_LINKAGE()Windows platforms

Specifies the linkage for classes generated by the os_relationship_xxx macros. This macro can be used with component schemas on Windows platforms. For example, you could define the macro as Microsoft’s __declspec(dllexport), which allows one DLL to create a subclass of a class defined in another DLL when there are relationship members.

You must define OS_RELATIONSHIP_LINKAGE() before including <ostore/relat.hh>. For example:

...#define OS_RELATIONSHIP_LINKAGE __declspec(dllexport)#include <ostore/relat.hh>

If the macro is not defined, the default is blank.

os_relationship_m_1()ObjectStore allows the user to model binary relationships with pointer-valued (or collection-of-pointer-valued) data members that maintain the referential integrity of their inverse data members. You implement this inverse maintenance by defining an embedded relationship class, which encapsulates the pointer (or collection-of-pointer) so that it can intercept updates to the encapsulated value and perform the necessary inverse maintenance tasks. The encapsulated-pointer values are stored as soft pointers so as to maintain the values across address space release and transactions.

Required include files

To use this macro, you must include the file <ostore/relat.hh> after including <ostore/ostore.hh> and <ostore/coll.hh>.

The actual value type of a data member with an inverse is a special class whose instances encapsulate the member’s apparent value. This implicitly defined class defines operator =() (for setting the apparent value), as well as operator ->(), operator *(), and a conversion operator for converting its instances to instances of

282 C++ Collections Guide and Reference

Page 283: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 9: Macros and User-Defined Functions Reference

the apparent value type (for getting the apparent value). Under most circumstances, these operators make the encapsulating objects transparent.

The implicitly defined class also defines the member functions getvalue(), which returns the apparent value, and setvalue(), which takes an instance of the apparent value type as argument. These functions can always be used to set and get the member’s apparent value explicitly.

This macro is used to declare a many-valued data member with a single-valued inverse data member. The macro call is used instead of the value type in the member declaration.

class class-name { ... macro-call member-name; ...};

Form of the call os_relationship_m_1(class,member,inv_class,inv_mem,value_type)

class is the class defining the data member being declared.

member is the name of the member being declared.

inv_class is the name of the class that defines the inverse member.

inv_mem is the name of the inverse member.

value_type is the value type of the member being declared.

Caution The first four macro arguments are used (among other things) to concatenate unique names for the encapsulating relationship class and its accessor functions. The details of macro preprocessing differ from compiler to compiler, and in some cases it is necessary to enter these macro arguments without white space to ensure that the argument concatenation will work correctly. There should be no white space in the argument list between the opening parenthesis and the comma separating the fourth and fifth arguments.

os_relationship_m_m()ObjectStore allows the user to model binary relationships with pointer-valued (or collection-of-pointer-valued) data members that maintain the referential integrity of their inverse data members. You implement this inverse maintenance by defining an embedded relationship class, which encapsulates the pointer (or collection-of-pointer) so that it can intercept updates to the encapsulated value and perform the necessary inverse maintenance tasks. The encapsulated-pointer values are stored as soft pointers so as to maintain the values across address space release and transactions.

Required include files

To use this macro, you must include the file <ostore/relat.hh> after including <ostore/ostore.hh> and <ostore/coll.hh>.

Release 6.3 283

Page 284: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

os_relationship_m_m()

The actual value type of a data member with an inverse is a special class whose instances encapsulate the member’s apparent value. This implicitly defined class defines operator =() (for setting the apparent value), as well as operator ->(), operator *(), and a conversion operator for converting its instances to instances of the apparent value type (for getting the apparent value). Under most circumstances, these operators make the encapsulating objects transparent.

The implicitly defined class also defines the member functions getvalue(), which returns the apparent value, and setvalue(), which takes an instance of the apparent value type as argument. These functions can always be used to set and get the member’s apparent value explicitly.

This macro is used to declare a many-valued data member with a many-valued inverse data member. The macro call is used instead of the value type in the member declaration.

class class-name { ... macro-call member-name; ...};

Form of the call os_relationship_m_m(class,member,inv_class,inv_mem,value_type)

class is the class defining the data member being declared.

member is the name of the member being declared.

inv_class is the name of the class that defines the inverse member.

inv_mem is the name of the inverse member.

value_type is the value type of the member being declared.

Caution The first four macro arguments are used (among other things) to concatenate unique names for the encapsulating relationship class and its accessor functions. The details of macro preprocessing differ from compiler to compiler, and in some cases it is necessary to enter these macro arguments without white space to ensure that the argument concatenation will work correctly. There should be no white space in the argument list between the opening parenthesis and the comma separating the fourth and fifth arguments.

284 C++ Collections Guide and Reference

Page 285: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 10Predefined TIX Exceptions

This section contains information on significant predefined exceptions. These exceptions are defined in client.hh and ostore.hh, so they are automatically available to your programs.

Contents Parent Exceptions 286

Predefined Exceptions 287

Release 6.3 285

Page 286: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Parent Exceptions

Parent ExceptionsThe following are parents in the exceptions object tree hierarchy. They are never signaled directly, but it can be useful to set up handlers for them in order to catch an entire set of errors.

ObjectStore exception inheritance hierarchy

The hierarchy is arranged as follows:

• Every TIX exception is a descendant of all_exceptions.

• Every TIX exception that is signaled by ObjectStore itself is a child of err_objectstore, which is a child of all_exceptions.

• Every TIX exception signaled from the remote procedure call (RPC) mechanism (which ObjectStore uses for all its network communications) is a child of err_rpc, which is a child of err_objectstore.

For more information about TIX exceptions, see Chapter 5, Predefined TIX Exceptions, in the C++ A P I Reference.

all_exceptions

err_objectstore

err_rpc

General exceptions err_coll

err_mop

err_schema_evolution

err_osbr

err_allocator_framework

all_exceptions

err_objectstore

err_rpc

General exceptions err_coll

err_osbr

err_allocator_framework

err_mop

286 C++ Collections Guide and Reference

Page 287: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 10: Predefined TIX Exceptions

Predefined ExceptionsCollection Exceptions

The following exceptions descend from err_coll, which is a descendent of err_objectstore.

err_am — Error using indexes, for example, an attempt to add an index where a class mentioned in the path serving as index key cannot be found in the schema of the database containing the index (or the application schema, if the index is transient).

Can be signaled by

• os_collection::add_index()

• os_coll_range::os_coll_range()

err_coll — The parent of all collection exceptions.

err_coll_behavior_inconsistency — The representation policy was semantically inconsistent with regard to the collection object.

Not found in coll_class.

err_coll_cannot_grow_collection — An attempt was made to grow a collection that could not be grown, usually because the grow_by or the grow_at parameter to collection creation specified no growth.

err_coll_cannot_mutate_collection — A collection could not be mutated into an alternate representation.

err_coll_cursor_mismatch — The collection maintained internally by a cursor passed as an argument to a function is not the same as the collection maintained by the collection or dictionary.

err_coll_dangling_pointer — A dangling pointer from a collection to a deleted object was detected, due to the presence of os_backptr during deletion of the containing object.

err_coll_duplicates — An attempt was made to duplicate an element in a collection.

err_coll_empty — The protocol expected a nonempty set, but was used on an empty set instead.

err_coll_evolve — The root exception for collection evolution.

err_coll_evolve_not_implemented_yet — The unimplemented part of collection evolution.

err_coll_illegal_arg — An actual argument used in the collection protocol failed validation. The text of the report contains details regarding the specific argument.

err_coll_illegal_cast — An illegal cast operation was attempted.

err_coll_illegal_query_expression — Syntax/semantic analysis of the query text resulted in an error.

Release 6.3 287

Page 288: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Predefined Exceptions

err_coll_illegal_update — An attempt was made to update a const collection through a cursor.

err_coll_internal — This exception is used to signal internal collection errors.

err_coll_internal_list — An error occurred in an internal list.

err_coll_none_qualifying — An error occurred in index look-up during scan.

err_coll_not_implemented_yet — For as-yet-unimplemented collection features.

err_coll_not_ordered — The operation required that the collection be ordered, but it was not.

err_coll_not_singleton — os_collection::only expected a singleton set, but the cardinality() != 1.

err_coll_not_supported — An attempt was made to use a collection subtype-specific protocol that was not supported by this particular subtype.

err_coll_null_cursor — The protocol expected a nonnull cursor for the particular operation.

err_coll_nulls — An attempt was made to insert a null element into a collection.

err_coll_out_of_range — A collection was accessed using an out-of-bounds array subscript.

err_coll_path_interp — An error in path interpretation occurred.

err_coll_query_bind — The query had free references, but these references were not bound at the * of the query. The report identifies the unbound variables.

err_coll_query_evaluate — An error occurred during evaluation of a query.

err_coll_scan — An error in scan occurred.

err_cursor — An error was made in cursor maintenance.

err_cursor_ambiguous — An error was made in cursor order specification.

err_cursor_internal — An error in ordered iteration occurred.

err_cursor_not_implemented_yet — Unimplemented feature.

err_illegal_index_path — An error occurred during translation of an index path expression.

err_index — An error occurred in an index.

err_index_duplicate_key — The uniqueness constraint on an index was violated.

err_index_evolve — An error occurred during the evolution of an index.

err_index_invalid_ordering — An index was ordered in an invalid way.

err_index_not_implemented_yet — For as-yet-unimplemented index evolution features.

err_index_wrong_kind — An unordered index was used for ordered iteration.

288 C++ Collections Guide and Reference

Page 289: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Chapter 10: Predefined TIX Exceptions

err_null_cursor — An attempt was made to operate on a null cursor.

err_object_init — Derived from err_objectstore, this exception can be caught by the application (as err_objectstore). This is the exception generated by all the error conditions that

• Are not in a transaction

• Have no type_name provided with a transient instance

• Have a type_name mismatch with a persistent instance

• Could not find schema information for type

• Are called with an embedded object (persistent only)

err_open_iteration — An iteration open on mapping being deleted.

err_pset_no_cursor — Error in _Pset iteration.

Release 6.3 289

Page 290: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Predefined Exceptions

290 C++ Collections Guide and Reference

Page 291: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Release 6.3

Index

Aadd_index()

os_collection, defined bydescription 171usage 96

allow_duplicates

os_collection, defined by 173os_index_path, defined by 226

allow_nulls

os_collection, defined by 173arrays

description 25associative access

defined 81

Bbags

compared to sets 144description 24iterating over 42

bound queriesos_bound_query 93os_keyword_arg 94os_keyword_arg_list 93

break_link()

os_backptr, defined bydescribed 136index maintenance 109usage 105

B-treeas ordered index 101

Ccardinality

os_collection, defined by 173cardinality()

finding the size of a collection 37

os_collection, defined by 173cardinality_estimate()

os_collection, defined by 174cardinality_is_maintained()

os_collection, defined by 174classes, system-supplied

nonparameterizedos_array 129os_bag 144os_collection 166os_cursor 209os_ixonly 229os_list 241os_set 254

os_Array 122os_array 129os_backptr 135os_Bag 138os_bag 144os_bound_query 149os_coll_query 192os_coll_range 199os_Collection 149os_collection 166os_Cursor 203os_cursor 209os_Dictionary 215os_dynamic_extent 224os_index_name 225os_index_path 226os_Ixonly 229os_keyword_arg 231os_keyword_arg_list 233os_List 234os_list 241os_nList 246os_nlist 246os_Set 247os_set 254

291

Page 292: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

D

parameterizedos_Array 122os_Bag 138os_Collection 149os_Cursor 203os_Dictionary 215os_Ixonly 229os_List 234os_nList 246os_nlist 246os_Set 247

clear()

os_collection, defined by 174collections

array 25bag 24choosing a type 24combining 37comparing 37consolidating duplicates 77copying 37decision tree 26defined 19determining cardinality of 37dictionary 25element type parameter 29index 95initializing the collections facility 22inserting elements into 34iteration 43library interface 185list 25loading phase 80parameterized and nonparameterized 31range 71removing elements from 35set 24testing to see if empty 37traversal 43

contains()

os_Collection, defined by 154os_collection, defined by 174os_Dictionary, defined by 220

copy_key

os_index_path, defined by 226count()

os_Collection, defined by 154os_collection, defined by 174

count_values()

os_Dictionary, defined by 220create()

os_coll_query, defined bydescribed 192usage 92

os_index_path, defined bydescribed 226usage 62

create_exists()

os_coll_query, defined bydescribed 195usage 92

create_pick()

os_coll_query, defined bydescribed 197usage 92

cursorsdefault 43restricted 73

Ddata members

declaring indexable 135making indexable 268

default cursor 43default_behavior()

os_Set, defined by 251defines

_OS_COLL_LIST_OPTIMIZE 39_OS_COLL_SET_OPTIMIZE 39

destroy()

os_coll_query, defined by 198destroy_list()

os_keyword_arg_list, defined by 233dictionaries

definition 25example 55header files required 49removing elements from 36retrieving by key 76specifying keys 52

drop_index()

os_collection, defined by 97

Eelement

in collections 150element type 150

292 C++ Collections Guide and Reference

Page 293: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Index

element type parameter 29empty()

os_collection, defined by 174EQ

os_collection, defined by 175returned by rank functions 266

err_am exception 287err_coll exception 287err_coll_behavior_inconsistency

exception 287err_coll_cannot_grow_collection

exception 287err_coll_cannot_mutate_collection

exception 287err_coll_cursor_mismatch exception 287err_coll_dangling_pointer exception 287err_coll_duplicates exception 287err_coll_empty exception 287err_coll_evolve exception 287err_coll_evolve_not_implemented_yet

exception 287err_coll_illegal_arg exception 287err_coll_illegal_cast exception 287err_coll_illegal_cursor exception

nonnull cursors 74err_coll_illegal_query_expression

exception 287err_coll_illegal_update exception 288err_coll_internal exception 288err_coll_internal_list exception 288err_coll_none_qualifying exception 288err_coll_not_implemented_yet exception 288err_coll_not_ordered exception 288err_coll_not_singleton exception 288

more than one element 75err_coll_not_supported exception 288

operations on unordered collections 46unordered collection 75

err_coll_null_cursor exception 288retrieve() function 74

err_coll_nulls exception 288err_coll_out_of_range exception 288

retrieve() function 75err_coll_path_interp exception 288err_coll_query_bind exception 288err_coll_query_evaluate exception 288err_coll_scan exception 288err_cursor exception 288

err_cursor_ambiguous exception 288err_cursor_internal exception 288err_cursor_not_implemented_yet exception 288err_illegal_index_path exception 288err_index exception 288err_index_duplicate_key exception 288err_index_evolve exception 288err_index_invalid_ordering exception 288err_index_not_implemented_yet exception 288err_index_wrong_kind exception 288err_no_such_index exception 98err_null_cursor exception 289err_object_init exception 289err_open_iteration exception 289err_pset_no_cursor exception 289exceptions

collection 287err_am 287err_coll 287err_coll_behavior_inconsistency 287err_coll_cannot_grow_collection 287err_coll_cannot_mutate_collection 287err_coll_cursor_mismatch 287err_coll_dangling_pointer 287err_coll_duplicates 287err_coll_empty 287err_coll_evolve 287err_coll_evolve_not_implemented_yet 287err_coll_illegal_arg 287err_coll_illegal_cast 287err_coll_illegal_query_expression 287err_coll_illegal_update 288err_coll_internal 288err_coll_internal_list 288err_coll_none_qualifying 288err_coll_not_implemented_yet 288err_coll_not_ordered 288err_coll_not_singleton 288err_coll_not_supported 288err_coll_null_cursor 288err_coll_nulls 288err_coll_out_of_range 288err_coll_path_interp 288err_coll_query_bind 288err_coll_query_evaluate 288err_coll_scan 288err_cursor 288err_cursor_ambiguous 288

Release 6.3 293

Page 294: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

F

err_cursor_internal 288err_cursor_not_implemented_yet 288err_illegal_index_path 288err_index 288err_index_duplicate_key 288err_index_evolve 288err_index_invalid_ordering 288err_index_not_implemented_yet 288err_index_wrong_kind 288err_null_cursor 289err_object_init 289err_open_iteration 289err_pset_no_cursor 289predefined 285

exists()

os_Collection, defined by 89, 154os_collection, defined by 175

Ffirst()

os_Cursor, defined by 204os_cursor, defined by 210returning collection’s first element 44

GGE

os_collection, defined by 176get_behavior()

os_collection, defined by 176get_element_type()

os_coll_query, defined by 198get_file_name()

os_coll_query, defined by 199get_line_number()

os_coll_query, defined by 199get_options()

os_index_name, defined by 225get_path_name()

os_index_name, defined by 225get_query_string()

os_coll_query, defined by 198GT

os_collection, defined by 176return value of os_index-key() 266returned by rank functions 267

Hhas_index()

os_collection, defined by 176testing for presence of index 98

hash functionsiteration order 78registering 266replacing 266

Iindex keys 226index maintenance

and member functionsos_backptr::break_link() 137os_backptr::make_link() 137

os_index() macro 107os_indexable_body() macro 107os_indexable_member() macro 107pointer-valued members 105

index paths 62indexable data members

instantiating accessor functions for 267indexes

adding 96key 96monitoring use 99optimizing queries 95ordered 101and performance 97removing 97testing for presence of 98trace_index_usage() function 99unordered 101

initialize()

objectstore, defined by 22os_collection, defined by 177

insert()

os_Collection, defined by 155os_collection, defined by 177os_Dictionary, defined by 220os_dynamic_extent, defined by 224

insert_after()

os_Collection, defined by 155os_collection, defined by 177os_Cursor, defined by 204os_cursor, defined by 210

insert_before()

294 C++ Collections Guide and Reference

Page 295: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Index

os_Collection, defined by 155os_collection, defined by 178os_Cursor, defined by 204os_cursor, defined by 210

insert_first()

os_Collection, defined by 156os_collection, defined by 178

insert_last()

os_Collection, defined by 156os_collection, defined by 179

iterationcontrolling order 78order 226traversing a collection with cursor 43

Llast()

os_Cursor, defined by 205os_cursor, defined by 210

LE

os_collection, defined by 179lists 234

description 25LT

os_collection, defined by 179return value of os_index_key() 266returned by rank functions 267

Mmacro arguments

entering correctly 107macros, system-supplied

os_assign_function() 265os_assign_function_body() 265os_index() 265os_index_key() 266os_index_key_hash_function() 266os_index_key_rank_function() 267os_indexable_body() 267OS_INDEXABLE_LINKAGE() 268os_indexable_member() 268OS_MARK_DICTIONARY() 260OS_MARK_NLIST() 260OS_MARK_NLIST_PT() 261OS_MARK_QUERY_FUNCTION() 261OS_MARK_QUERY_FUNCTION_WITH_

NAMESPACE() 262

os_query_function() 269os_query_function_body() 270os_query_function_body_with_

namespace()() 270os_rel_1_1_body() 271os_rel_1_1_body_options() 275os_rel_1_m_body() 272os_rel_1_m_body_options() 276os_rel_m_1_body() 273os_rel_m_1_body_options() 277os_rel_m_m_body() 274os_rel_m_m_body_options() 278os_relationship_1_1() 280os_relationship_1_m() 281OS_RELATIONSHIP_LINKAGE() 282os_relationship_m_1() 282os_relationship_m_m() 283OS_TRANSIENT_DICTIONARY() 262OS_TRANSIENT_DICTIONARY_NOKEY() 263OS_TRANSIENT_NLIST() 263OS_TRANSIENT_NLIST_NO_BLOCK() 264

maintain_order

os_collection, defined by 179make_link()

os_backptr, defined bydescribed 137usage 105

matching patterns in queries 84more()

os_Cursor, defined by 205os_cursor, defined by 211

multitrans_add_index()

os_collection, defined by 179multitrans_drop_index()

os_collection, defined by 180

NNE

os_collection, defined by 180nested queries 87next()

os_Cursor, defined by 205os_cursor, defined by 211positioning cursor at next element 44

no_duplicates

os_index_path, defined by 228null()

os_Cursor, defined by 205

Release 6.3 295

Page 296: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

O

os_cursor, defined by 211

Oobjectstore, the class

initialize() 22only()

os_Collection, defined by 157os_collection, defined by 180retrieving only element of a collection 74

operator !=()

os_Collection, defined by 158os_collection, defined by 182

operator &()

os_Collection, defined by 160os_collection, defined by 184

operator &=()

os_Array, defined by 128os_array, defined by 134os_Bag, defined by 143os_bag, defined by 148os_Collection, defined by 160os_collection, defined by 184os_List, defined by 240os_list, defined by 245os_Set, defined by 252os_set, defined by 257

operator –()

os_Collection, defined by 161os_collection, defined by 185

operator ,()

os_keyword_arg, defined by 231os_keyword_arg_list, defined by 233

operator <()

os_Collection, defined by 158os_collection, defined by 182

operator <=()

os_Collection, defined by 159os_collection, defined by 182

operator -=()

os_Array, defined by 128os_array, defined by 134os_Bag, defined by 144os_bag, defined by 148os_Collection, defined by 160os_collection, defined by 184os_List, defined by 240os_list, defined by 245os_Set, defined by 252

os_set, defined by 258operator =()

os_Array, defined by 127os_array, defined by 133os_Bag, defined by 143os_bag, defined by 148os_Collection, defined by 159os_collection, defined by 183os_List, defined by 239os_list, defined by 244os_Set, defined by 251os_set, defined by 257

operator ==()

os_Collection, defined by 158os_collection, defined by 182

operator >()

os_Collection, defined by 159os_collection, defined by 183

operator >=()

os_Collection, defined by 159os_collection, defined by 183

operator |()

os_Collection, defined by 160os_collection, defined by 184

operator |=()

os_Array, defined by 127os_array, defined by 134os_Bag, defined by 143os_bag, defined by 148os_Collection, defined by 160os_collection, defined by 183os_List, defined by 239os_list, defined by 245os_Set, defined by 251os_set, defined by 257

operator const os_array&()

os_collection, defined by 181operator const os_Array()

os_Collection, defined by 157operator const os_bag&()

os_collection, defined by 181operator const os_Bag()

os_Collection, defined by 157operator const os_list&()

os_collection, defined by 181operator const os_List()

os_Collection, defined by 158operator const os_set&()

296 C++ Collections Guide and Reference

Page 297: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Index

os_collection, defined by 182operator const os_Set()

os_Collection, defined by 158operator os_array&()

os_collection, defined by 181operator os_Array()

os_Collection, defined by 157operator os_bag&()

os_collection, defined by 181operator os_Bag()

os_Collection, defined by 157operator os_int32()

os_collection, defined by 181operator os_list&()

os_collection, defined by 181operator os_List()

os_Collection, defined by 157operator os_set&()

os_collection, defined by 182operator os_Set()

os_Collection, defined by 158operators

comparison and assignmentdual purpose of 38

pattern matching 84optimizations

compiling for 39using indexes 95

optimized_list

os_collection, defined by 185optimized_set

os_set, defined by 258order, iteration 226order_by_address

os_cursor, defined by 211order_by_DSCO

os_cursor, defined by 212ordered

os_index_path, defined by 228requesting ordered index 101

os_Array()

os_Array, defined by 128os_array()

os_array, defined by 134os_Array, the class 122

operator &=() 128operator -=() 128operator =() 127

operator |=() 127os_Array() 128set_cardinality() 129

os_array, the class 129operator &=() 134operator -=() 134operator =() 133operator |=() 134os_array() 134set_cardinality() 135

os_assign_function(), the macro 265os_assign_function_body(), the macro 265os_backptr, the class 135

break_link()

described 136index maintenance 109usage 105

declaring member 104designating indexable member 265make_link()

described 137index maintenance 109usage 105

member function in a query or path string 64os_Bag()

os_Bag, defined by 144os_bag()

os_bag, defined by 149os_Bag, the class 138

operator &=() 143operator -=() 144operator =() 143operator |=() 143os_Bag() 144

os_bag, the class 144operator &=() 148operator -=() 148operator =() 148operator |=() 148os_bag() 149

os_bound_query()

os_bound_query, defined by 149os_bound_query, the class 149

os_bound_query() 149_OS_COLL_LIST_OPTIMIZE define 39os_coll_query, the class 192

create()

described 192usage 92

Release 6.3 297

Page 298: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

O

create_exists()

described 195usage 92

create_pick()

described 197usage 92

destroy() 198get_element_type() 198get_file_name() 199get_line_number() 199get_query_string() 198

os_coll_range()

os_coll_range, defined by 199os_coll_range, the class 199

objects representing a range 71os_coll_range() 199

_OS_COLL_SET_OPTIMIZE define 39os_Collection, the class 149

contains() 154count() 154exists() 89, 154insert() 155insert_after() 155insert_before() 155insert_first() 156insert_last() 156only() 157operator !=() 158operator &() 160operator &=() 160operator –() 161operator <() 158operator <=() 159operator -=() 160operator =() 159operator ==() 158operator >() 159operator >=() 159operator |() 160operator |=() 160operator const os_Array() 157operator const os_Bag() 157operator const os_List() 158operator const os_Set() 158operator os_Array() 157operator os_Bag() 157operator os_List() 157operator os_Set() 158pick() 161

query() 161query_pick() 162remove() 163remove_first() 163remove_last() 164replace_at() 164retrieve() 164retrieve_first() 165retrieve_last() 165

os_collection, the class 166add_index()

description 171usage 96

allow_duplicates 173allow_nulls 173cardinality 173cardinality() 173cardinality_estimate() 174cardinality_is_maintained() 174clear() 174contains() 174count() 174drop_index() 97empty() 174EQ 175exists() 175GE 176get_behavior() 176GT 176has_index() 176initialize() 177insert() 177insert_after() 177insert_before() 178insert_first() 178insert_last() 179LE 179LT 179maintain_order 179multi_trans_add_index() 179multi_trans_drop_index() 180NE 180only() 180operator !=() 182operator &() 184operator &=() 184operator –() 185operator <() 182

298 C++ Collections Guide and Reference

Page 299: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Index

operator <=() 182operator -=() 184operator =() 183operator ==() 182operator >() 183operator >=() 183operator |() 184operator |=() 183operator const os_array&() 181operator const os_bag&() 181operator const os_list&() 181operator const os_set&() 182operator os_array&() 181operator os_bag&() 181operator os_int32() 181operator os_list&() 181operator os_set&() 182optimized_list 185pick() 185query() 185query_pick() 187remove() 188remove_at() 188remove_first() 188remove_last() 189replace_at() 189retrieve() 189retrieve_first() 190retrieve_last() 190trace_index_usage() 191update_cardinality() 191

OS_COLLECTION_TRACE_INDEX_USAGE environment variable 99

~os_Cursor()

os_Cursor, defined by 209os_Cursor()

os_Cursor, defined by 205~os_cursor()

os_cursor, defined by 215os_cursor()

os_cursor, defined by 212os_Cursor, the class 203

first() 204insert_after() 204insert_before() 204last() 205more() 205

nonnull element 44

next() 205null() 205~os_Cursor() 209os_Cursor() 205owner() 207previous() 207rebind() 208remove_at() 208resolve_all() 208retrieve() 208traversing a collection 43valid() 209

os_cursor, the class 209first() 210insert_after() 210insert_before() 210last() 210more() 211next() 211null() 211order_by_address 211order_by_DSCO 212~os_cursor() 215os_cursor() 212owner() 214previous() 214rebind() 214remove_at() 214resolve_all() 215retrieve() 215update_insensitive 215valid() 215

os_Dictionary()

os_Dictionary, defined by 220os_Dictionary, the class 215

contains() 220count_values() 220insert() 220os_Dictionary() 220pick() 222remove() 222remove_value() 223retrieve() 223retrieve_key() 223

os_dynamic_extent()

os_dynamic_extent, defined by 224os_dynamic_extent, the class 224

insert() 224

Release 6.3 299

Page 300: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

O

os_dynamic_extent() 224remove() 225

os_index(), the macro 265os_index_key(), the macro 266

rank and hash functions 78os_index_key_hash_function(), the macro 266os_index_key_rank_function(), the macro 267os_index_name, the class 225

get_options() 225get_path_name() 225

os_index_path, the class 226allow_duplicates 226copy_key 226create()

described 226usage 62

no_duplicates 228ordered 228point_to_key 228signal_duplicates 229specifying member access path 62unordered 229

os_indexable_body(), the macro 267OS_INDEXABLE_LINKAGE(), the macro 268os_indexable_member(), the macro 268os_Ixonly()

os_Ixonly, defined by 230os_ixonly()

os_ixonly, defined by 230os_Ixonly, the class 229

os_Ixonly() 230os_ixonly, the class 229

os_ixonly() 230os_keyword_arg()

os_keyword_arg, defined by 231os_keyword_arg, the class 231

operator ,() 231os_keyword_arg() 231

os_keyword_arg_list()

os_keyword_arg_list, defined by 234os_keyword_arg_list, the class 233

destroy_list() 233operator ,() 233os_keyword_arg_list() 234

os_List()

os_List, defined by 240os_list()

os_list, defined by 245

os_List, the class 234operator &=() 240operator -=() 240operator =() 239operator |=() 239os_List() 240

os_list, the class 241operator &=() 245operator -=() 245operator =() 244operator |=() 245os_list() 245

OS_MARK_DICTIONARY(), the macro 260OS_MARK_NLIST(), the macro 260OS_MARK_NLIST_PT(), the macro 261OS_MARK_QUERY_FUNCTION(), the macro 261OS_MARK_QUERY_FUNCTION_WITH_NAMESPACE(), the

macro 262os_nList, the class 246os_nlist, the class 246os_query_function(), the macro 269os_query_function_body(), the macro 270os_query_function_body_with_namespace()(),

the macro 270os_rel_1_1_body(), the macro 271os_rel_1_1_body_options(), the macro 275os_rel_1_m_body(), the macro 272os_rel_1_m_body_options(), the macro 276os_rel_m_1_body(), the macro 273os_rel_m_1_body_options(), the macro 277os_rel_m_m_body(), the macro 274os_rel_m_m_body_options(), the macro 278os_relationship_1_1(), the macro 280os_relationship_1_m(), the macro 281OS_RELATIONSHIP_LINKAGE(), the macro 282os_relationship_m_1(), the macro 282os_relationship_m_m(), the macro 283os_Set()

os_Set, defined by 253os_set()

os_set, defined by 258os_Set, the class 247

default_behavior() 251operator &=() 252operator -=() 252operator =() 251operator |=() 251os_Set() 253

300 C++ Collections Guide and Reference

Page 301: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

Index

os_set, the class 254operator &=() 257operator -=() 258operator =() 257operator |=() 257optimized_set 258os_set() 258

OS_TRANSIENT_DICTIONARY(), the macro 262OS_TRANSIENT_DICTIONARY_NOKEY(), the

macro 263OS_TRANSIENT_NLIST(), the macro 263OS_TRANSIENT_NLIST_NO_BLOCK(), the macro 264<ostore/coll/dict_pt.hh> header file 49owner()

os_Cursor, defined by 207os_cursor, defined by 214

Pparameter

element type 150path expressions 62path string 62paths 226

specifying traversal order 62pattern-matching queries 84pick()

os_Collection, defined by 161os_collection, defined by 185os_Dictionary, defined by 222

point_to_key

os_index_path, defined by 228previous()

os_Cursor, defined by 207os_cursor, defined by 214

Qqueries

bound 93existential 89library interface 161nested 87, 90nested existential 91optimization 226pattern matching 84performance with index 97preanalyzed 92purpose 81

range 228range, ordered index 101single-element 88

query optimization 226adding index 95defined 81

query string 82query()

os_Collection, defined by 161os_collection, defined by 185

query_pick()

os_Collection, defined by 162os_collection, defined by 187

Rrange queries 228rank functions

possible values returned 78registering 266replacing 267

rebind()

os_Cursor, defined by 208os_cursor, defined by 214

registering rank and hash functions 266remove()

os_Collection, defined by 163os_collection, defined by 188os_Dictionary, defined by 222os_dynamic_extent, defined by 225

remove_at()

os_collection, defined by 188os_Cursor, defined by 208os_cursor, defined by 214

remove_first()

os_Collection, defined by 163os_collection, defined by 188

remove_last()

os_Collection, defined by 164os_collection, defined by 189

remove_value()

os_Dictionary, defined by 223replace_at()

os_Collection, defined by 164os_collection, defined by 189

replacing hash functions 266replacing rank functions 267resolve_all()

os_Cursor, defined by 208

Release 6.3 301

Page 302: C++ Collections Guide and Referencemedia.progress.com/realtime/techsupport/...Contents 4 4 C++ Collections Guide and Reference Templated and Nontemplated Collections. . . . . .

S

os_cursor, defined by 215restricted cursors 73retrieve()

os_Collection, defined by 164os_collection, defined by 189os_Cursor, defined by 208os_cursor, defined by 215os_Dictionary, defined by 223retrieving element with specific cursor

position 74retrieve_first()

os_Collection, defined by 165os_collection, defined by 190retrieving collection’s first element 75

retrieve_key()

os_Dictionary, defined by 223retrieve_last()

os_Collection, defined by 165os_collection, defined by 190retrieving collection’s last element 75

Ssessions

initialization 177set_cardinality()

os_Array, defined by 129os_array, defined by 135

sets 247description 24

signal_duplicates

os_index_path, defined by 229

Ttrace_index_usage()

os_collection, defined by 191trace_index_usage() function 99traversing collections 43

Uunordered

os_index_path, defined by 229update_cardinality()

os_collection, defined by 191update_insensitive

os_cursor, defined by 215

Vvalid()

os_Cursor, defined by 209os_cursor, defined by 215

302 C++ Collections Guide and Reference