Performance Consideration For Lotus Domino
Performance Consideration For Lotus Domino
www.redbooks.ibm.com
SG24-5602-00
SG24-5602-00
xii Lotus Domino Release 5.0: A Developer’s Handbook
SG24-5602-00
International Technical Support Organization
March 2000
Take Note!
Before using this information and the product it supports, be sure to read the general information in
the Special Notices section at the back of this book.
This edition applies to Lotus Domino Release 5.0 and Lotus Domino Release 4.6
Comments may be addressed to: IBM Corporation, International Technical Support Organization
Dept. HYJ Mail Station P099
2455 South Road
Poughkeepsie, NY 12601-5400
When you send information to IBM, you grant IBM a non-exclusive right to use or distribute the
information in any way it believes appropriate without incurring any obligation to you.
Note to U.S. Government Users: Documentation related to restricted rights. Use, duplication or disclosure
is subject to restrictions set forth in GSA ADP Schedule Contract with IBM Corp.
Contents
Contents iii
Similar Number of Users ............ 47 Summary ........................ 86
How to Measure the Results . . . . . . . . . . 48 4 Performance Aspects of
Performance Testing Never Stops . . . . . . . 48 Domino Design Elements . . . . . . . . . 87
Summary . . . . . . . . . . . . . . . . . . . . . . . . 49 The Basics ........................ 87
The Domino Object Model . . . . . . . . . . . . . 69 Combine Field Formulas into Events . . . . 104
Getting the Most from Your Domino Allow Domino to Automatically Redirect
Objects . . . . . . . . . . . . . . . . . ..... 73 URLs . . . . . . . . . . . . . . . . . . . . . . 105
Dynamic Script Library Loading . . . . . . . . . 84 Some Internal Information About Views . 109
Java Agents vs. LotusScript Agents . . . . . 144 Appendix A-1 How Do You Put
8GB of Data in a 4GB Bag? . . . . . . 205
Applets . . . . . . . . . . . . . . . . . . . . . . 146
Servlets . . . . . . . . . . . . . . . . . . . . . . 146
Introduction to the Application ....... 205
Problem Statement . . . . . . . . . . . . . . . . . 206
Other Options . . . . . . . . . . . . . . . . . . 147
Alternative Solutions . . . . . . . . . . . . . . . . 207
Database Performance Techniques . . . . . . . 147
Database Archiving . . . . . . . . . . . . . . . 148
Contents v
Three-Tiered Distributed Data Use @Environment in the Selection
Architecture — MQ on Server ...... 207 Formula . . . . . . . . . . . . . . .
..... 236
Three-Tiered Distributed Data Use @Text in the Selection Formula . . . . . 237
Architecture — MQ on client ....... 208
Creating Time/Date Views Using Agents . . 239
Four-Tiered Distributed Data
Save a DisplayInView Indicator in the
Architecture — MQ on Staging Server . 209
Document . . . . . . . . . . . . . . . .
... 239
The Tiered, Distributed Data Architecture . . 211
Put Documents into a Folder ......... 240
What is the Tiered Architecture? . . . . . . 212
Appendix B-2 Dynamic Script
Data Distribution and Scalability . . . . . . 215 Library Loading . . . . . . . . . . . . . . . . 243
Data Flow Across the Tiers . . . . . . . . . . 217 Background .................... 243
Minimizing Application-Induced Problem . . . . . . . . . . . . . . . . . . . . . . 243
Replication Conflicts . . . . . . ...... 221
Solution . . . . . . . . . . . . . . . . . . . . . . 245
Performance Characteristics . . . . . . . . . . . 222
Usage Example . . . . . . . . . . . . . . . . . 248
Overall Performance Test — Part 1 . . . . . 222
Evaluation . . . . . . . . . . . . . . . . . . . . 249
Overall Performance Test — Part 2 . . . . . 224
Conclusion . . . . . . . . . . . . . . . . . . . . 250
Future Applicability . . . . . . . . . . . . . . . . 225
Appendix B-3 Displaying
Appendix A-2 High Performance
Processing Status . . . . . . . . . . . . . . 251
Reference Databases . . . . . . . . . . . 227
Status Line Messages .............. 251
Appendix A-3 Third-Party Tools
Status Line Progress Bar . . . . . . . . . . . . 251
for Performance Measurements . . 231
How Many Documents Are in That
Monitoring Tools .................. 231
View? . . . . . . . . . . . . . . . . ..... 253
Candle Pinnacle Performance Manager . . 231
Progress Bar Using Undocumented API
Candle ETEWatch . . . . . . . . . . . . . . . . 232 Calls . . . . . . . . . . . . . . . . . . . . .. 256
Tivoli Manager for Domino . . . . . . . . . . 232 Appendix B-4 Sorting . . . . . . . . . . . 257
Coast WebMaster . . . . . . . . . . . . . . . . 232 Sorting Scope and Limitations . . . . . . . . . . 257
Stress Testing and Load Tools . . . . . . . . . . 233 Sorting Algorithms . . . . . . . . . . . . . . . . . 257
Websizr . . . . . . . . . . . . . . . . . . . . . . 233 Where Can You Find Sorting Routines? . . 258
Groupsizr . . . . . . . . . . . . . . . . . . . . . 233 Bubble Sort . . . . . . . . . . . . . . . . . . . . 258
Proactive Assistant . . . . . . . . . . . . . . . 233 Selection Sort . . . . . . . . . . . . . . . . . . . 260
Proactive Load . . . . . . . . . . . . . . . . . . 234 Insertion Sort . . . . . . . . . . . . . . . . . . . 261
Appendix B-1 Time/Date Views . . . 235 Quick Sort . . . . . . . . . . . . . . . . . . . . . 263
Background . . . . . . . . . . . . . . . . . . . . . . 235 Heap Sort . . . . . . . . . . . . . . . . . . . . . 264
Creating Time/Date Views Using Selection Shell Sort . . . . . . . . . . . . . . . . . . . . . 267
Formulas . . . . . . . . . . . . . . . . . .. 236
Pros and Cons . . . . . . . . . . . . . . . . . . . . 268
Use @Today in the Selection Formula ... 236
Bubble Sort . . . . . . . . . . . . . . . . . . . . 268
Workarounds for Two Related Issues: The Appendix C-3 Fast Access to
Performance Hit from @UserRoles and Reader Names Protected
Emulating Local Roles Without Using Documents . . . . . . . . . . . . . . . . . . . . 323
Enforce a Consistent ACL . . . . . . . . . 286
Reader Names and View Performance ..... 323
Appendix B-7 Cascaded A Possible Scenario . . . . . . . . . . . . . . . 323
Deletions Example . . . . . . . . . . . . . 291
Reader Names . . . . . . . . . . . . . . . . . . 323
Cascading the Documents ............ 291
Domino and Views . . . . . . . . . . . . . . . 324
Relational Databases . . . . . . . . . . . . . . 291
An Anatomy of a Client View Request . . . 325
Domino . . . . . . . . . . . . . . . . . . . . . . 292
Some Interesting Observations . . . . . . . . 327
Deleting the Related Documents . . . . . . . . 294
Summary . . . . . . . . . . . . . . . . . . . . . 329
Appendix B-8 Using NRPC
Getting Fast Access to Reader Names
Output . . . . . . . . . . . . . . . . . . . . . . . . 297 Documents . . . . . . . . . . . . ...... 330
Enabling the Output .............. 297 Getting at the Documents ........... 330
Contents vii
Appendix C-4 LotusScript versus Pressing F9 to Refresh Fields While in
Formulas . . . . . . . . . . . . . . . . . . . . . 333 Edit Mode . . . . . . . . . . . . . . . . ... 350
Preface ix
Umasuthan Ramakrishnan is a software engineer for IBM Global Services
in India. He has two years of experience with Lotus Notes and Domino.
Walt Simons is a Senior Architect with IBM Global Services in Sydney,
Australia. He is part of the IBM Notes/Web Application Center of
Competence, and also works with various development teams in Australia
producing global enterprise applications. He specializes in LotusScript, the
C API and the ODS and has developed productivity tools for the
development community. Walt has over 24 years of experience in a variety
of areas in the IT industry.
Chris Thornton is a Field Support Engineer for Lotus Professional Services
in England. He has worked for Lotus for two years and has six years of
experience with Lotus Notes and Domino. Chris has particular expertise in
infrastructure planning, server administration, application design and
troubleshooting.
A number of people have provided support and guidance and we have also
harvested information from a number of resources. Refer to the related
publications appendix for these resources. We would like to thank the
following people:
• Jeff Blaney — Lotus
• Chris Cole — Lotus
• Michael Confoy — Lotus
• Teresa Deane — Iris
• Sunsan Florio — formerly Iris
• Dean Garyet — IBM Netherlands
• Garry Greenwood — G2 Associates, Inc.
• James Grigsby — formerly Iris
• Brendan Hoar — Price Waterhouse Coopers
• Ralph Hueske — IBM USA
• Ryan Jansen — Iris
• Dave Karasic — Lotus
• Brian Kiser — Lotus
• William A. Littlewood — Lotus
• Steve Krantz — IBM USA
• Bill Masek — Lotus
Preface xi
Comments Welcome
Your comments are important to us!
We want our redbooks to be as helpful as possible. Please send us your
comments about this or other redbooks in one of the following ways:
• Fax the evaluation form found at the back of this book to the fax
number shown on the form.
• Use the online evaluation form found at
http://www.redbooks.ibm.com/
With the adoption of Domino worldwide in every industry and for all kinds
of solutions, there is a need among solution architects and developers to
better understand the performance and capacity aspects of Domino
applications.
There are many examples of Domino being used for mission-critical
applications that require performance and scalability. With Domino R5.0,
the potential for superb performance and capacity in Domino applications
is even better than was the case with previous releases.
However, as with any other powerful tool, problems can arise if you don’t
know how to use Domino properly for large applications. That is why we
wrote this book for you as a designer and developer.
If you are an administrator you may also find some helpful information
here, but we focus only on the application aspects of performance in this
book. While we may touch on some general server tuning topics, we will
not cover how to configure your Domino server or the underlying platform
operating system for optimum performance. Check the Related Publications
section for related publications that contain information about performance
in the Domino server.
If you are interested in development methodology, this may not be the
place to go either. We do talk a bit about methodology, but the content in
this book is based on experience and best practices we have gathered from
a number of sources and it can be used with any development method.
Finally, if we haven’t scared you off yet — this is not a book that will teach
you the basics of how to program Domino. We assume that you have
experience with Domino development. If you are new to Domino, you may
want to read one of these redbooks first:
• Lotus Domino R5.0: A Developer’s Handbook, IBM form number
SG24-5331, Lotus part number CC7EDNA
• Developing Web Applications Using Lotus Notes Designer for Domino 4.6,
IBM form number SG24-2183, Lotus part number 12974
• Lotus Notes 4.5: A Developers Handbook, IBM form number SG24-4876,
Lotus part number AA0425
What is Performance?
When talking about performance, people often have different perceptions
of what it is. Here are two ways to look at performance:
• Time aspect — Responsiveness
Performance is a measure of time spent on an individual operation
or job.
• Capacity aspect — Throughput
Capacity or throughput can be another measure of performance.
Performance can be measured in terms of data transfer rates, generally
expressed as transactions per hour. It can also be measured in terms of
resource utilizations such as CPU utilization or disk storage utilization.
It does not make sense to talk about performance without mentioning
throughput capacity or scalability. An application may perform very well
during a pilot deployment, where only a subset of the targeted user
population works with it — and then fail badly when rolled out to all users.
Design
Chapter 2 discusses the overall performance and capacity considerations
you should go through when designing your application. We discuss when
it makes sense to use several databases for your application and how to do
so. For a distributed application you also need to take performance and
capacity restrictions in the infrastructure into account, and we will discuss
different infrastructure scenarios. We will also discuss techniques for
implementing multi-database applications such as seamless switching
between databases, cascaded deletes and so on. Knowing the way that users
work with your application is very important to predict peaks of load and
to identify the most important areas on which to focus. A method to get this
information (a Use Case Model) will be briefly described before we discuss
how you test that your design is valid with regard to performance and
capacity.
Appendices
We have quite a few appendices in this book with specific examples, tools
and techniques, and reference information. The appendices have been split
into three groups:
• Appendices Group A: Application examples and tool descriptions.
• Appendices Group B: Programming Techniques (time views, seamless
switching between databases, cascaded deletes and so on)
• Appendices Group C: How some of the Domino stuff works and some
limits to be aware of.
Note As with many other things in life, the devil is in the details when
looking at performance and capacity in Domino applications. We have tried
to structure the book so you can locate your areas of interest, but often there
may be information in several places relating to a particular issue you are
pondering. We encourage you to read the entire book the first time in order
to get the full benefit.
Summary
In this chapter, we have defined what we mean by performance — both the
responsiveness and capacity of an application. We have discussed ways to
measure performance and identified which parts of a Domino application
affect performance the most. Finally, we have given an overview of what is
covered in the rest of this book.
7
The Best Solution is the Simplest
In general, whenever you add complexity to a solution you also add to the
cost of the solution, so our ideal Domino application is one that is contained
in one Domino database and resides on one server only. Centralization
reduces cost and improves reliability. Fewer servers mean less complex
server topologies and fewer server-to-server activities, less redundant data,
and less replication.
From a programing standpoint, you don’t have to concern yourself with a lot
of setup information about names of other databases and views if all the data
you are interested in resides in the same database.
With the performance and capacity improvements in the Domino R5.0 server
and database structure, you can get quite a lot further along with a single
database application.
However, there will still be situations where the limits are reached and there
may also be other reasons for using several databases for an application. We
discuss these circumstances in the following section.
If your application must support a remote office without any servers, you
must consider how users can access your application over a WAN. Ability to
work on a WAN may be part of the application requirement, but it may also
be a requirement that suddenly appears after the application has been
deployed because of a merger or business expansion.
For applications on a WAN, the network may be the bottleneck before
anything else. Domino uses Notes Remote Procedure Calls (NRPC) to
communicate between the server and the Notes client, and one user action
normally results in many NRPCs going back and forth between the client
These rules are mostly derived from mail users. Remember, the usage pattern
for your application may be very different from mail usage. In addition, it is
very rare for you to get a line to a remote location dedicated to your
application; most likely you will need to share it with other applications.
What if you have more remote users than the current bandwidth can
support?
• Have the network upgraded to support a larger bandwidth.
This comes of the thesis that it is better to have the application on as few
servers as possible when looking at the administration cost.
• If the remote users run Notes, you can replicate some of the application
databases to their local PCs. See the section titled “Application on One
Server in One Location” for pros and cons of this approach.
• Put a Domino server in the remote location to support all users there.
This option will be further discussed in the next section.
Use Deferred Processing to Let the Users Continue with Other Tasks
You may have situations where a transaction is made up of a user entering
or validating some data, followed by some processing of that data where the
processing doesn’t require user interaction but takes up quite some time. In
such situations you should see whether you can do this processing in the
background and let the user continue with their other work.
An example is the deletion of a document that has a lot of related documents
in other databases that must be deleted together with this document to
enforce referential integrity. Instead of doing all the deletions before
returning control to the user, you could instead mark the main document for
deletion and then have a scheduled agent do the actual deletions, including
in related documents, in the background. With this approach the user will
There is a generic use case that describes what is common for all service
requests being submitted, and then there are use cases when the request is
submitted by telephone or the Web. Submitting service requests from the
Web utilizes general functionality described in use cases, Input/Edit Web
form fields, Web site-related attributes, and Send e-mail.
The textual description of a use case includes a use case title, subject area
(for grouping use cases like submitting service requests), the business event
that triggers the use case scenario, actors involved, a brief use case overview,
preconditions, outcome, brief description of events/conversations likely to
occur in the use cases, and related use cases.
The main purpose of the Use Case Model is to establish the boundary of
your application and fully state the functionality that must be delivered to
the users.
Similar Environment
There may be some real-world obstacles that will not allow you to do an ideal
proof-of-concept prototype. The easiest way to run in a similar environment
is to run in the actual production environment. However, most administrators
never allow any testing in their production environment. While you may be
allowed to run your tests through the night shift, remember that this is still
not similar to the environment as it behaves during the daytime with regard
to network activity, load on servers, and so on.
If you need to build your own prototype environment, try to get a server as
close as possible to the servers where the application will be deployed.
Simulating a slow WAN link may be more difficult, depending on which
network systems and protocols you have on your test machines. With TCP/IP
as the protocol you may be able to flood the system with dummy data using
the ping command (see more about ping in Chapter 5, “Troubleshooting an
Existing Application”). However, you will not be able to limit the available
bandwidth to a certain specified size so it is not really of much use. The best
way to see how your design will behave on low bandwidth is to establish a
28.8K dial-up connection to a server with the proof-of-concept prototype and
run through your scenarios over that connection.
Similar Data
It is important that the data be as similar to the real-world data as possible.
The best solution is to get actual data from an existing application, if one
exists. However, Domino applications often hold sensitive data that is
protected by company rules and perhaps also by law, so in some cases you
may not be able to get real-world data for your proof-of-concept prototype.
If you construct the data yourself it is important that it is diversified (to
spread over a lot of categories for categorized views, and so on). It is not
enough to create five different documents and then copy these x number of
times, nor is it enough to fill out the first ten fields of a document if the
document in average will have 20 fields filled out when being deployed.
Choosing a Language
As Domino has evolved, the choice of languages available to build
applications has expanded. Originally only the Lotus Formula language
was available. In Notes R4.0, LotusScript was added; in Domino R4.5,
JavaScript and Java were both added to give you four choices of language.
To add to this, Domino R4.5 also allows the use of HTML in some parts of
forms. Languages external to the Domino database can also be used.
Among the supported languages are C, C++, Perl, CGI, and so on.
So which one should you use? The answer depends on two factors. The first
is whether you can even write the code in the language you choose. In some
cases, only one of the languages will accomplish the task. For example,
when coding the QueryOpen event in a form, you have a choice of using
LotusScript or the Formula language, but for the database Initialize event
you can only use LotusScript. If your application is being used on the Web,
you also have JavaScript and Java as options in certain situations.
The second factor is performance. It turns out that under certain conditions,
accomplishing the same task can take radically different amounts of time
depending on the language you use.
Unfortunately, as with many performance considerations, there are no hard
and fast rules. You need to assess each situation in context.
51
The Lotus Formula Language
The Lotus Formula language has been around for a long time and there are
many professionals adept at using it. However, that doesn’t make it the
correct choice in all cases.
The Formula language is built close to the core of Notes, thus there is little
overhead involved when invoking Formulas. This means that simple tasks
will execute very quickly. However, the Formula language has very limited
capability when it comes to complex logic. There are no loops or
subroutines in Formula, so writing complex logic becomes not only
difficult, but inefficient.
The Formula language is very focused on the user interface. The current
view, selected document or set of unprocessed documents play a very
prominent role in Formulas. Most of the menu functions are available in the
Formula language via @commands. You can use Formulas to access
documents other than the current one, or access documents in another
database, but the functionality in this area is limited.
Formulas can be very compact. It will usually take fewer lines of Formula
than LotusScript to code simple functions. Also, Formulas are stored very
efficiently in the database. When the same piece of code can be written in
both languages with no performance impact, the Formula language is
preferable to LotusScript because the code will take up less space. As we
shall see throughout this book, database size is always a factor when it
comes to application performance.
LotusScript
LotusScript is a full-fledged object-oriented programming language and has
a much greater scope than the Formula language. One of the main
advantages LotusScript offers over the Formula language is that it provides
the means to do sophisticated iteration and branching. Not only can you
include complex logic in your design, but you can use LotusScript to create
libraries of subroutines that contain common code. These subroutines can
be called from any other place in your application that uses LotusScript.
LotusScript lets you work with the object-oriented programming model.
Most things in a Domino database can be accessed via the built-in Domino
classes. These Domino classes are pre-loaded objects that can be
manipulated through their methods, properties, and events.
Your application may be required to reach beyond the Domino sphere (such
as accessing Word Pro, 1-2-3, a relational database, or the file system).
LotusScript has the ability to do this using features which include
LotusScript Extentsions (LSX), OLE-Automation, Domino Enterprise
Connectors, and the C API.
Java
In terms of performance and functionality, Java and LotusScript are
comparable when executing code that is written in the same way. There are
some differences between the two languages in terms of architecture that
may affect the performance of your application, depending on its design.
Using Java with Domino gives you
• Multithreading
• Built-in networking support
• Data access though Java Database Connectivity (JDBC)
• Direct access to the Domino Object Model from a Web browser in
Domino R5.0 using CORBA/IIOP
• Servlets
See the section “Agents and Other Processing” in Chapter 4, “Performance
Aspects of Domino Design Elements,” for more discussion of the Java
functionality in Domino.
JavaScript
JavaScript was introduced as an alternative in Domino R4.5 for use on the
Web client. As of Domino R5.0, it can be used in Notes client events as well.
JavaScript is a good choice for field validations that need to be done on the
Web. The script is embedded as part of the HTML page served to the client,
and the code executes on the client as required. To code the same function-
ality in LotusScript or Formula requires a round trip to the server.
JavaScript can also be used to allow multiple buttons to exist on your Web
page.
In general, a number of very useful Domino features are not available when
the application runs on the Web. JavaScript can be used to fill in the gap by
giving you more control over the appearance and functionality of your Web
user interface.
@Formulas
The following general rules apply when programming with the Lotus
Formula language. Remember that there are no absolutes — everything is a
trade-off.
The table is much as expected; however, there are two interesting things
that can seriously affect your design:
1. The keyword formula for an editable field which uses check boxes or
radio buttons always runs when you open the document. This seems
reasonable because all choices need to be displayed, but at the same time
many users only want to view document contents, not change the data.
2. The keyword formula for an editable field which has data and uses a
dialog box is run when a document opens. This one is less reasonable.
For the many users who only want to view document contents, the data
is already set so why run the keyword formula for choices? These users
are not going to display the dialog box.
The formula for the keyword field is the name of the hidden field:
kwDataHidden
LotusScript
LotusScript is very powerful and can be used to solve complex tasks. With
power comes responsibility: you can easily write code that solves a problem
but does so in a very inefficient manner. The following general rules apply
when programming with LotusScript. These suggested techniques, which
may not be obvious from reading the user guide, will help you create the
most efficient code possible.
Fragment B
Do
z = z+1
y = y+1
Loop While y <= 15000
Simplify If Statements
LotusScript needs to evaluate the entire If statement before action is taken.
Unlike some languages (like C) where evaluation stops as soon as a result is
known, LotusScript will evaluate each condition.
This statement always results in both conditions being evaluated.
If a=x And b=y Then
The following statement runs 40 percent faster than the previous example
because the second condition evaluates only if the first is true.
If a=x Then
If b=y Then
Fragment B
z& = x& / y&
Note For Domino R4.6 and earlier, there is a 64K limit on strings. Reading
the entire file at once can only be done if you know your files are 32,000
characters or less (the 64K limit applies to bytes, and there are 2 bytes per
character).
Note If your files are larger than 32,000 characters, you can still use this
performance advantage by processing the file in large chunks instead of line
by line. Input chunks of 32,000 characters at a time. This does involve
handling a line split across blocks, so it is a bit more code to maintain, but a
500 percent performance gain is worth it for large files.
Fragment B
For i = 1 to 100
t(1) = t(1) + x(i)
Next
Instead, try to create strings from known pieces. In the following examples,
fragment A is 25 percent faster than fragment B:
Fragment A
str$ = stringA$ & stringB$
Fragment B
str$ = stringA$
str$ = str$ & stringB$
When processing a string in pieces, extract the desired data from the middle
of the string and remember your position. This is faster than reducing the
original string each time. In the following example, fragment A is 85
percent faster than fragment B.
Fragment A
strPiece$ = Mid$(str$, startPos%, pieceLength%)
startPos% = startPos% + pieceLength%
Fragment B
strPiece$ = Left$(str$, pieceLength%)
strLength% = strLength% - pieceLength%
str$ = Right$(str$, strLength%)
Fragment B
For i = 1 to 10000
Redim Preserve sArray(1 To i)
sArray(i) = “”
Next
Note In fragment A, when the loop is finished, you may want to Redim the
final array to its actual size. Sometimes that is important in an application.
Fragment B
If (Left$ (x$, 1) = “A”) Then
Fragment D
If (Mid$(x, 1, 1) = “A”) Then
In checking for a null string, code fragment E is 30 percent faster than code
fragment F.
Fragment E
If (Len (x$) = 0) Then
Fragment F
If (x$ = “”) Then
Java
Java has an inherent language overhead caused by the need to load the Java
virtual machine (JVM). This is a piece of software used to drive Java code; it
is loaded the first time Java is run on your machine. Once loaded, the JVM
stays resident for the process that triggered it.
On the server, the JVM is loaded with the HTTP task. As such, the overhead
occurs when the Domino server starts up. For Notes clients, the JVM also
loads with the Notes client. Again, the client opens a bit slower, but the
JVM is available from then on. Lastly, on the Web browser, the JVM is only
loaded when Java is first required, but once loaded, the JVM is available for
the rest of the browser session.
Although there is nothing you can do about the JVM loading overhead, there
are some things you can do to maximize the performance of your Java code:
JavaScript
JavaScript is in a league of its own. You cannot easily compare it to
LotusScript or Java since they don’t operate in the same space. But that’s
not going to stop us from providing some details on using JavaScript to
help performance.
JavaScript is coded into its own section on an HTML document, between
<SCRIPT> tags. Therefore, the size of the data sent to the Web client is a bit
larger when using JavaScript. However, with JavaScript you gain access to
elements of the UI that are not exposed to LotusScript (such as the
background color of the screen and background images). These can be used
in the Notes client as well (for Domino R5.0).
Two key areas in which JavaScript can excel are field validation and field
input translation. For documents that are seen on the Web, field validation
and translation pose a problem for the client. They require a round trip to
the server to be executed. This is where JavaScript can really help.
If JavaScript is used for areas in a form where otherwise a round trip to the
server would be required, then the reduction of network access will
immediately be seen by the user in a positive way. The actual time the CPU
is busy may increase a tiny bit, but the network wait time is drastically
reduced, giving an overall performance benefit.
Lazy Initialization
Many times in your design it will be necessary to have access to a complex
object (for example, a database or view). That database or view may not be
required each time the function is called; its use may depend on various
conditions. In such situations, use lazy initialization to defer the overhead
of opening a database or getting a view until these objects are needed.
If the code is contained within a single module, this can be easily achieved
by not defining the object until the appropriate place in the logic.
If, on the other hand, you have structured code with multiple functions and
are using global variables for shared objects, then the initialization of these
objects is often done by a common initialize function. Usually this means
that all the objects are initialized, even if some of them are never needed.
Object Reuse
In the prior example, you may also notice that once the view has been
retrieved from the database, it becomes available for future requests for that
view. The view is saved in a global variable and is available for later reuse.
This is true within the context of the running code (for example, within the
current document). Once the document closes (if that is your context), then
the objects are destroyed.
Fragment B
Set session = New NotesSession
Set db = session.CurrentDatabase
dbTitle$ = db.Title
After you disable AutoReload, it remains disabled until your script enables
it again using this syntax. To display changes, you also have to reload the
changes to the UI:
source.AutoReload = True
source.Reload
Fragment B
x = doc.fieldname
Note Be sure to allow for columns that can have multiple values in them.
In this case the data type of doc.ColumnValues(0) will be an array, not a
scalar.
Note This does not apply to GetNthDocument in a view. In that case, both
methods are equally fast.
Use GetDocumentByUNID
The NotesDatabase GetDocumentByUNID method is the most efficient
way to access documents. In most situations where you need to access a
document, you know something about the document in order to find it. This
information comes from some common data between related documents.
Design your system such that the document unique ID is used as common
data. If this is available when it is time to locate another document, then
finding that document becomes very easy — and very fast.
Note There are limitations to using document unique ID as a link between
related documents. In particular, when archiving data to another database,
there is no guarantee that unique IDs are maintained during the copy.
Integrity checks will be required to ensure links in the archive database are
maintained.
Fragment B
If (doc.fieldA(0) > 0) then
pSum = pSum + doc.fieldA(0)
else
nSum = nSum - doc.fieldA(0)
End If
Fragment B
fldData = “CN=Walt G Simons/OU=Australia/O=IBM”
For ii = 0 To loopMax-1
’*** Create a single field
If (ii = 0) Then
fldName = “field001”
Set itm = doc.AppendItemValue(fldName, fldData)
Else
Call itm.AppendToTextList(fldData)
End If
Next
The following table shows the savings with different numbers of items in
the list:
loopMax Time ‘A’ Time ‘B’ Doc size ‘A’ Doc size ‘B’
100 0.109 sec 0.476 sec 3,766 3,748
200 0.188 sec 2.396 sec 7,486 7,448
400 0.387 sec 17.028 sec 14,926 14,848
As you can see, with the ‘A’ method execution times go up linearly with the
number of items in the list. With the ‘B’ method there is an exponential
growth of time to add each entry. Although the ‘A’ method makes
documents that are larger, the size difference is almost insignificant.
Fragment B
Call docSource.CopyAllItems(docDest, True)
UnprocessedDocuments
The UnprocessedDocuments property can be effectively used to select a
subset of documents for an agent. Documents which are processed by one
agent do not affect their status as being “unprocessed” for another agent.
Using this property will eliminate the need for other selection criteria for
the agent (for example, it may eliminate the need for a hidden view). Do not
forget to mark the document as processed for your agent by calling the
UpdateProcessedDoc method.
Code Reuse
The reuse of code is not generally seen as a performance improving
technique. Certainly, if you reuse an existing sort routine that is known to
be fast, then your application will not suffer from slow sorts. But in general,
reusing code usually involves a very slight performance degradation. This
degradation occurs because access to the existing code is via an interface
between the application and the reused code. You don’t have the option of
accessing the function directly.
Advantages of reusing code are usually seen in reduced cycle time, not
faster performing applications. However, in this section, we will show how
reusing code can improve Domino application performance.
The only potential performance gain here is when there are multiple
complex actions in the view. In this case, coding the formula in the view
means the entire suite of actions is sent to the client when any action is
taken. When agents are used, only the formula for the single action taken is
loaded to the client.
Script Libraries
Ever since Domino R4.5, script libraries have been available to help a
developer in a variety of ways. By putting common code into script
libraries, it is possible to use this code in forms, view actions, or agents
without the need to duplicate the code. Script libraries can also help
improve performance under some conditions
The code in this agent does not get loaded to the client until the action
button is clicked by the user. At that point the agent code is downloaded to
the client and executed.
%INCLUDE Files
%INCLUDE files are another way to write and maintain code in one place
but use it in many places. Since the introduction of script libraries and the
removal of the 64KB limit in many areas, the need to use include files is not
as great as it once was. However, one may ask the question, “Is it quicker to
load a form that includes %INCLUDE statements for some of the code, or a
form with all its code ‘hard-coded’?” Another question you may ask is,
“Should I convert all my old applications that use include files and put that
code directly into the form (or into a script library)?”
The answer is that you should not convert your %INCLUDE files to
different techniques if you have no other reason to. You may decide to
convert so that the code is all in one place, or for some other reason, but if
you are happy with the current situation — don’t change. The loading
happens only during initial code usage. The savings are small since there is
no optimizing of a repetitive loop, where many performance gains are
made.
There is only one situation where there may be a performance impact. If the
code is large and you have a slow network, then using %INCLUDE files
sends less information on the network than either hard coding in the form
or using a script library. The amount sent relates directly to the size of the
code in the %INCLUDE files, but you need to be aware of this if you are
thinking of changing.
Sorting
Sorting is not a common task for Domino applications. Most often a view is
used to maintain the correct sequence for the data. However, when you are
faced with a situation where you need to sort data and a view cannot be
used, how should you go about it? Neither Formula nor LotusScript
supplies convenient sorting routines for the designer’s use. You will need to
code one yourself.
Asynchronous Processing
Another technique to improve performance is asynchronous processing. In
particular, when dealing with complex processing or multi-database
relations, the user’s perceived response time can be greatly improved when
asynchronous processing is employed.
Summary
After reading this chapter, you should have a better understanding of the
many possibilities available to you when designing a Domino application.
You understand the performance implications of various language
constructs you might use and the relationships among the various Domino
objects. In all, you now should have a good footing to start designing your
application.
The next chapter deals in greater detail with the individual design elements
and how you can get the most from each one.
The Basics
Ever since Domino R4.5, the scope of concerns for designers of Domino
applications has been increasing. You can no longer just worry about how an
application performs in your nice little Notes environment. The Web is out
there and your application should be available to those users too. Add to
that your users who are still on Notes R4.1, and your design choices become
complex. You have to always consider users of your application who have
platforms with limited capability, who are using the Web to access the
application, or who have limited network bandwidth.
87
Ask most Domino designers about the basic design elements for designing a
Domino application and their reply will be “Forms and Views.” The realiza-
tion that Outlines, Frames and Pages are now with us is still filtering down
to the grass roots. These new design features can give us a lot of wonderful
functionality — especially for Web based applications. Unfortunately,
performance-related issues generally become known by fixing applications
that are in trouble. Many aspects of the new Domino R5.0 design elements
are not well understood when it comes to their performance in a real user
community. For these cases, we have done some limited tests and we
provide some advice. Most of this advice has not been field tested; we are
relying on your experiences in that area!
Using Subforms
Subforms are very useful when you are developing an application, in terms
of reuse, consistent look and feel, and design task separation. Loading
subforms, however, requires calculations which slow the opening of
documents to some degree.
As suggested by this data, you should avoid large tables or, when it is
possible, split a large table into several smaller ones.
Using Sections
Sections can be used to display just the major parts of a document, leaving
the details to be examined upon user request. Since a lot less is being
displayed when the document first opens, does this mean we can improve
performance using sections?
After some tests using RPCs, we found that it does not matter if a section is
expanded or collapsed for Notes clients. In other words, all of the design
information is sent to the client when the document is opened, regardless of
whether a section is expanded or collapsed.
However, as with tabbed tables, when a Web client uses sections, only the
information that is being displayed is downloaded. Using sections will
improve the performance for Web browsers.
With this formula Domino presents the NotesMain view to a Notes client,
and presents the WebMain view to a browser client. This technique gives
better performance than multiple Hide When conditions or computed
subforms.
• Combine required data into one column. When you need more than one
column of data from the same @Db lookup, create an extra (hidden)
column in the view that contains all the data you will need. Save the
results in a temporary variable and then parse this variable whenever
lookup data is needed. Use the @Subset function to parse the results.
For example: a help desk application contains two databases. The first
one has the requester file (DB 1) and the second one (DB 2) performs a
lookup on DB 1 to fill up a section of a form:
DB 1 Form:
Field Type Formula
Name Names - Editable
Phone Text - Editable
Address Text - Editable
Other Text - Editable
Lista Text (hidden - allow Translation formula: Phone:Address:Other
multiple values)
DB 1 Lookup view:
Column 1 Formula (Sorted) Column 2 Formula
Field - Name Field - Lista (Phone:Address:Other)
To retrieve the data from DB 1 you can use an action button or hotspot
button with the following formula:
Formula Description Return Value
Lista := Stores the lookup result Phone:Address:
@DbLookup(“Notes”:“Cache”; in a variable (Lista) Other
Server:DB1; “DB 1 lookup
view”; Name; 2);
@SetField(“Phone”; Set the field Phone with Phone
@Subset(Lista; 1)) the first element of the list
(Phone:Address:Other)
@SetField(“Address”; Set the field Address with Address
@Subset(@Subset(Lista; 2); -1)) the last element of the list
(Phone:Address)
@SetField(“Other”; Set the field Other with Other
@Subset(Lista; -1)) the last element of the list
(Phone:Address:Other)
Field Basics
Understanding how the various field types work can suggest ways to
significantly improve performance. In the worst case, each field is calculated
when a document is opened, refreshed, or saved.
By understanding what calculations are performed and when calculations
are evaluated, forms and views can be tuned to maximum performance. This
will impact how long it takes to open, save and work with documents.
Some field basics:
• Fields within a form are evaluated from left to right and top to bottom.
• Formulas within pop-ups and keyword fields are evaluated at document
open.
• Do not use “Computed” fields unless they do need to always be
evaluated at save time. For more information, see “Effects of a
Computed Field” later in this chapter.
• Use “Computed when composed” fields when evaluations are needed
upon demand. For example, if a button is defined to store the results of a
formula, the results should be placed into a “Computed when
composed” field.
• Consider using one event script to evaluate many fields within a form
rather than having each field evaluate results individually.
• By default, fields have a “Summary” attribute (except rich text fields).
Summary data about fields is stored in view indexes and other places in
the database.
Shared Fields
There is overhead required as Domino resolves the format and function of
shared fields within an application. Be sure to define shared fields only
when complex formulas are being shared throughout the database.
In your database design, a shared field and a form are two different design
elements. Domino must make an extra internal function call (a NoteOpen) to
get the design information for the shared field once it is found to exist in a
form. In all, Domino does one NoteOpen call to get the document, one to get
the form as specified in the document, and finally one to get each of the
shared fields specified in the form.
As you can see, the time it takes to compose a document is much more
seriously impacted by the number of matches of each @DbLookup than by the
number of @DbLookup formulas. For example, 20 lookup formulas that match
3 documents each works faster than 10 lookups that returns 15 matches each.
The server recognizes this as an internal redirection URL and the transaction
sequence becomes:
1. The browser submits the HTML form to the Domino server.
2. The server evaluates the $$Return formula or runs the WebQuerySave
agent to produce an internal redirection URL — for example:
[[mydb.nsf/view?OpenView]]
Profile Documents
Profile documents were introduced in Domino R4.5 and are another area to
consider when thinking about performance.
Browser Caching
Different Web browsers cache information in different ways. Most browsers
are designed to hold a list of temporary files, such as images. This will
enable the reloading of the graphical pages to be improved. Cookies can only
hold a limited amount of information. However, there is a technique that can
be used to enable us to store application-related information on the Web
browser and not have to store this temporary information on the server. For
example, if we have a large list of temporary information, such as project
codes that we are going to be referring to in our Web application, we
probably want to send these to our browser only once. In a Notes client we
would often choose to store these as a hidden field in a document or use one
of the caching techniques already discussed. Prior to Domino R5.0, any
hidden fields on a form were not converted to HTML and were not sent to
the client to be referenced. Therefore, the ability to store some information in
a hidden fashion on a Web client was very tricky.
A better method to do this is to use the Frames feature. Here we can
partition the window of the user’s Web browser into different areas. We
have the ability to specify the width or height of a particular frame and also
Views
One of the great features of Notes is its ability to display information in
views: categorized, sorted, totaled, and always available. Views are a feature
of Notes that make it stand out from the rest.
Using views can provide significant user productivity, but you need to be
aware of the potential impacts when views are not designed with
performance in mind.
Type of View
When we design a view, this is the first decision we must make. Is the view
shared, private on first use or private? Many times the answer is
predetermined, but let us examine the performance implications of our
choice.
We can safely rule out private views since as designers we are creating an
application for somebody else’s use. Private views can only be used by their
creator. That only leaves shared and private on first use view types to
consider.
For the applications you will be designing it is highly likely that most views
will be shared by all users. However, there are situations where private on
first use views are desired.
As you can see, there are five types of shared views: standard, two special
types, and two private on first use types. The two special view types —
“Shared, contains documents not in any folder” and “Shared, contains
deleted documents” — were added in Domino R5.0 and will not be
discussed here since they are not generally used as application views.
Prior to Domino R5.0, view type selection was done via check boxes:
When your view is categorized such that the user has access to data in
a single category, this can limit the amount of data that must be sent
to the Web client.
Design Changes
A major problem with private on first use views is that you cannot change
the design of the view easily. If the design changes, it is only the server
version of the design that is altered. Since the user’s version of the view is
private to the user, it is not updated. This private view must be deleted so
that when the user next opens the view, the design is refreshed from the
server version
There are several ways to delete this private view, none of which is ideal.
Private View in User’s desktop.dsk
If the view index is stored in the user’s DESKTOP.DSK, you need to get the
user to manually delete the database icon. When the icon is removed from
the workspace, all private views are also deleted.
For versions of Domino prior to R5.0, deleting a specified database icon can
be done by sending the user mail containing the following code. The code
can be triggered by a button.
@Command([WindowWorkspace]);
@Command([FileOpenDatabase]; "server":"dbName.nsf");
@Command([FileCloseWindow]);
@PostedCommand([EditClear]);
@PostedCommand([FileOpenDatabase];"server":"dbName.nsf")
Note This code will remove not only the user’s private on first use views,
but all the user’s private views for this database (that are stored in the
desktop.dsk).
Since this icon deletion is a UI activity, the user will be prompted via two
message boxes. The first prompt asks the user to confirm that the icon will
be deleted. The second asks the user to confirm that their private views
will be deleted. Make sure your message to the user tells them to accept
both messages.
If userMsg = ”“ Then
Messagebox ”No out-of-date private views were found“
Else
Messagebox ”The following out-of-date private “ & _
”views were removed:“ & _
userMsg & Chr(10) & Chr(10) & _
”Please reopen this database for these views “ & _
”to be updated.“
End If
End Sub
Set db = pView.parent
Dim view As NotesView
Forall v In db.views
’*** Master view has same name
If v.Name = pView.Name Then
’*** Master view is not private
If Not(isPrivateView(v)) Then
Set getmasterView = v
Exit Function
End If
End If
End Forall
End Function
Note This LotusScript code removes only private views that are out-of-date
with respect to the master view. This can be easily modified to behave like
the formula-based code listed earlier, which removes all private views.
Note This code works for Domino R5.0 as well as prior releases of Domino.
Document Types
The types of documents in a view are another thing to be considered in your
view selection. Are the documents Main documents, Response documents or
a combination of both? Do the documents have special fields, such as
readers, authors, encrypted, or signed fields?
As it turns out, the document type does not play a significant role in
determining the size or the efficiency of a given database. Reader names and
encrypted fields, however, should be managed carefully.
Column Design
Many aspects of the view column design have no impact on performance.
These include things like column width, column heading, heading fonts,
data fonts, alternating line color and so on.
There are several things, however, that do have performance implications.
These are categorization and sorting, features often used in views.
Categorization
When a column is defined as a category, Notes needs to store a lot more
information in the view’s index to mange the category. Every aspect of view
index maintenance will be affected since the index is more complex and
bigger. Bigger indexes means a bigger database. This means we have
performance hits, not only in index maintenance, but in other areas where
database size is a factor.
Dynamic Sorting
Using dynamic sorting for a view column can help to reduce the overall
number of views required. However, dynamic sorting has a large impact on
view index size. Every column in a view has a sequence, even if that
sequence is “unsorted.” The amount of space used by the index for a view
that has every column sorted compared to that used for a view that has no
sorted columns is very similar. The extra time required to find the correct
insert point in the index is also a small factor (insertions only happen for
new documents, and they are incremental). The size of the view index,
however, and thus the database size, has a far more noticeable impact on
performance.
When a view has columns that can be dynamically sorted, the view must not
only have an index for the normal view sequence, but also an alternate index
for the other sort sequence. If the dynamic sorting includes both ascending
and descending, then a third index is required. Both of these additional
indexes take up space, and thus time, during the many index operations that
occur during normal operations in a database. If dynamic sorting is included
on several columns, an index for each unique sequence is required. Before
you know it, a view can suddenly grow to the point where index size far
outweighs the data size. It is not uncommon for a database to be three to ten
times larger with all indexes built compared to the size with no indexes.
If you do need dynamic sorting, only use ascending or descending. Don’t
allow both types of dynamic sort.
Note A view index contains more information than just the sequence of the
documents. Summary information is also included in the index. When
alternate sequences are required to satisfy dynamic column sorting, only the
alternate sequence needs to be duplicated. The summary data does not need
to be duplicated. See Appendix C-2, “View Index Comparisons,” for some
test results on view index sizes.
View Actions
View actions can affect performance, especially in a low-bandwidth network
environment. Unlike forms, the design information behind action buttons is
not sent from server to client when a view is opened by the user. Instead, the
design information is sent to the client when an action button is activated by
the user pressing on it. Then we not only get the performance hit of doing
the work of the action, but before we can even start, a potentially large piece
of the view design may need to make its way from server to client.
Tip If there are a number of actions that occur on several views, this
common code might be stored in a script library. If your environment is not
a high-speed LAN, you need to be careful that you don’t make the script
library so big that performance is affected. Break your code up into several
smaller script libraries so that only the required code is loaded.
Pages
Pages have been added to Domino R5.0 to allow more functionality and
flexibility when designing not only Web applications, but applications for
Notes clients as well. Previously, when static information was required to be
published in a Domino database, developers would use a combination of
forms with either fixed text or text stored in fields, and two help documents
(Help Using This Database and Help About This Database). Developers
often created documents that were only used for Web clients, either for
storing HTML or for embedding Web elements.
Pages are Domino design elements and are thus stored as part of the design,
not as data. This means pages are not included in views, and therefore the
indexing of the database is not affected. The performance impact of using
pages has not been determined, but there seems to be no reason that a
negative performance would result from using pages. In fact, as experience
with pages increases, there may be situations where pages provide
performance improvements. Watch this space!
Object Reuse
There has always been a need to compromise between what looks good and
the time it takes to display information. Users like their applications to look
good; this has been a major factor in moving a lot of processing away from
the old “Green screens” that used to dominate corporate computing. We can
now give the users some graphics and helpful tools in different frames,
which do not need to be reloaded every time the user changes pages or
navigates within an application.
Here we see that each database appears simply, like a list of views. We can
split the application by content but allow the user to move between the
information stored with ease. Another example of how this could be useful is
if we split the databases further. For example, each year we might have a
different database to store the transactions for that year. The outline then
might appear like the following:
Performance Considerations
Though the use of outlines itself will not directly improve the performance
of our application, the use of multiple databases can improve performance.
By using outlines we can now connect multiple databases easily in a manner
that is seamless to the user. By being able to split these databases, but still
give the user of the application the illusion of being in only one Domino
database, we aid the developer in building larger, scalable applications that
can use different databases for different content.
Images
One of the most appealing concepts of the original World Wide Web
(WWW) was the ability to add graphics and other types of multi-media to
pages that contain text. If it were not for this, it is unlikely that the WWW
would have become so popular: after all, there was already a widely used
protocol for retrieving text documents (Gopher). Due to this origin, graphics
have become very important in providing applications to users of Web
browsers, who have come to expect highly graphical applications. The same
is true with Domino applications. Desktop computers and the development
of a Graphical User Interface (GUI) have given most computer users the
ability to view elaborate graphics, which give applications a very
professional look and feel.
It has been possible to use graphics in Domino applications for a long time.
Prior to Domino R5.0, when you wanted to use a graphic in a form or in a
Navigator, you had to import it into the form, navigator, or subform. If the
page was to be displayed to the Web, then you also had the option to
reference an image stored elsewhere. This was done using the URL format
and could point to the Domino server file system, a Domino database or
even to a different Web site.
Applets
The integration of Java into Domino has enabled us to develop many more
customized applications for use from both the Notes client and the Web
client. Prior to Domino R5.0, an applet was either embedded into each form
that used the applet, or it was stored elsewhere and referred to with HTML.
Domino R5.0 allows us to store the files that comprise the applet in a
Resource. We can then include this resource in forms and pages. However,
unlike the use of Image resources, the applet actually becomes a part of the
form. This means that if the applet is changed, then it needs to be put back
into the form. In addition, applets are not cached as well as images (though
some browsers cache applets better than others).
Shared Actions
Shared actions are found under Resources - Other. They allow us to create
actions (Simple, Formula, LotusScript or JavaScript) centrally that can be
used in a number of places without having to copy them to other views or
forms. Previously, subforms were often used to include a common set of
action buttons on forms.
Shared actions do not appear to enhance the performance of an application;
however, they do not appear to hinder it either. When tests were done which
examined the remote procedure calls, we found that the amount of
information downloaded to the client is the same regardless of whether it is
for a shared action or a standard action.
As in other areas in Domino where the design is distributed (for example,
using subforms, or shared fields), using shared actions causes a small
performance overhead at the server since it must deal with more than one
design item.
CACHE.DSK
The CACHE.DSK file contains design elements (forms, subforms, and
LotusScript libraries) of databases located on a Domino server, in addition to
cross-replica journaling information. Storing these items in CACHE.DSK
helps improve client performance when accessing databases located on a
Domino server and helps the process of read-mark synchronization.
As user or administrator you can control the following parameters for
CACHE.DSK:
• Size
• Location
As a developer you have no way of tweaking CACHE.DSK directly.
However, with knowledge of how CACHE.DSK works there are a few
things you can do indirectly. We discuss this after showing how to control
the size and location of CACHE.DSK.
InitialCacheQuota in NOTES.INI
To set the maximum size for CACHE.DSK in NOTES.INI, use:
InitialCacheQuota=xxxx
where xxxx is the file size in bytes (specified in increments of 1024 bytes, for
example InitialCacheQuota= 6144.)
Note In some earlier Notes versions this NOTES.INI file setting was not
working correctly. It is working in R4.5.5 and R4.6.2 and a fix is being
researched for Notes R5.x.
Workspace Properties
To set the maximum size for CACHE.DSK via the workspace, double-click
any workspace tab. The workspace properties dialog box appears. On the
Beanie (advanced) tab (the Information tab in Notes R4.x), you can specify the
maximum size of CACHE.DSK in MB (default value is 5MB.) However, this
setting is stored in the CACHE.DSK itself. If this file is deleted, the file will be
recreated the next time Notes starts, with the default size limit of 5MB.
Compacting CACHE.DSK
The CACHE.DSK is actually a Domino database with no built-in forms or views.
Therefore, this file can be compacted to recover unused space. The Compact
option for the CACHE.DSK is found on the same workspace properties tab
where the maximum size is specified. You can click a button to see “% used.” If
the percentage is under 85%, click the button named “Compact.”
Headlines
Domino R5.0 includes a new feature called Headlines. This is an exciting
feature because it allows a user to “Subscribe” to a database and receive
notification when there are updates to that database. This is an end user
feature, but it is important to understand the implications of it from an
application perspective.
When Headlines is enabled, the Notes client will monitor the databases to
which it has subscriptions at a regular interval. This interval is set in the Mail
and News section of the User Preferences dialog. The area at the bottom of
this screen, which says “Check for new mail every xx minutes” also controls
how often the headlines are scanned.
Note Choose File - Preferences - User Preferences to get to the User
Preference dialog.
If your application is one that has a large number of new documents being
created, allowing the monitoring of headlines in it may be placing a
considerable extra load on the client’s computer. The feature is part of the
new On Disk Structure (ODS) that Domino uses and, as such, it can be
disabled under the Database properties Prevent Headline Monitoring
(covered later in this chapter). We recommend that you consider whether it
is appropriate to allow users to monitor the database with the headlines
feature prior to deploying the application.
Domino Images
Graphic images can also be stored apart from the design items that use them.
This is another way we can maximize performance for Web clients.
Servlets
Java servlets, as their name suggests, only run on the server. A servlet is
invoked by a client request and will respond directly to the client. Every time
a Domino agent is run it must be loaded, executed and then removed from
memory. A servlet, once loaded, remains in memory. Typically, a servlet will
be used to provide a high-performance link to a back-end system and format
the results back to the client as an HTML document. However, servlets are
not restricted to serving just HTTP requests and may, in fact, converse
directly with any suitable client application (usually an applet).
• Servlets are not secure or functional as agents.
• Servlets must live in a file system.
• Servlets run with server privileges.
• Servlets can access Domino objects, but have no idea who the Domino
user is.
Access to the servlet can be controlled by file-protection documents in the
Domino Directory. If the servlet accesses Domino through the CORBA
interface, it can specify a Domino user name and Internet password. Domino
security applies to all CORBA operations.
Note In controlled tests, there have been instances when servlets were up to
six times faster than agents.
DSAPI
The Domino Web Server Application Programming Interface (DSAPI) is a C
API for writing your own extensions to the Domino Web Server. A DSAPI
extension, or filter, is a program you create that is notified when certain
events occur on the Web server, such as when a URL request is received or
when a user is about to be authenticated.
For example, you might choose to write a program that performs custom
authentication, which is often one part of implementing single signon within
a corporation. In this scenario, the DSAPI program could be notified when
Domino is about to authenticate a user. The DSAPI program could then
parse the user name, check the user name and password against a legacy
mainframe system, and if successful, notify the Domino Web server that it
has handled the event (authentication). It then could pass Domino the
distinguished name of the user.
For more information, see “DSAPI” in Chapter 6 of Lotus Notes and Domino
R5.0 Security Infrastructure Revealed, order number SG24-5341.
Extension Manager
The Domino extension manager is a facility that allows an executable
program library (for example, a DLL) in an application to work in concert
with Domino. The DLL can register callback routines with Domino for
certain events. When the registered event occurs, the DLL will be called by
Domino (either before the event, after or both).
This facility can be used to allow API applications to perform database
shadowing or add additional access controls, just to name two possibilities.
Database Archiving
As mentioned in Chapter 2, “Design Considerations,” database archiving is
something that must be considered so as to maximize database performance
after an application has been deployed for some time. In all likelihood, your
application will start to fill up with data that is no longer useful, is out of date
or at least not essential. Archiving such data can speed up your application.
The Notes Release 5 facilities for database archiving can help in this situation.
Database Encryption
Depending on your security requirements and the environment in which
your application will be deployed, database encryption is one option that
you may consider.
For Domino databases, there are four levels of data security available. The
following table outlines the security level and performance implications for
each level.
Encryption Description Compression Performance
Level
None No data encryption. Can be used when Yes No effect
the data has no security restriction or if
the environment is already secure.
Simple Minimum level encryption is performed. Yes Very small
Use simple encryption if you want to take effect
advantage of disk compression and when
security needs are not great.
Medium Medium encryption is probably the best No Small effect
choice for most users because it balances
security, strength and fast database access.
Strong Use strong encryption when security No Noticeable
requirements are paramount, and the effect
resulting database access performance is
acceptable. Database access is slower with
strong encryption than with the other
encryption options.
Transaction Logging
This new Domino R5.0 feature allows database transactions to be logged as
they occur. Many of you are now thinking “Oh, more overhead, worse
performance.” Well, in fact, just the opposite is true. Logging means that
Domino can be a lot less conservative about database writes. Prior to Release 5,
Domino had to be very careful about writing to disk to ensure no loss of data.
With transaction logging, Domino is ensured of being able to recover from a
crash in the middle of I/O, so it doesn’t have to “flush to disk” as often.
The end result is far fewer disk I/Os for the Domino code (even though we
add some I/O for the actual logging). In performance measurements, it was
estimated that there is a 10 percent performance gain when you turn on
performance logging.
Note It goes without saying the logging should be to a separate disk.
Messaging
The way Domino works today, there is one database called MAIL.BOX,
where all mail is deposited. This can become a bottleneck, especially if
you’re running a lot of users or if you want to compact the database. With
Notes Release 5 you are allowed to have any number of MAIL.BOX
databases. This allows you to spread the load and the contention over as
many databases as you wish.
Database Size
The new database architecture includes a change in how pointers are stored
inside the database. This will allow individual databases of over one terabyte
in size in the near future. For Release 5.0, databases are certified up to 64GB,
versus the Release 4.0 limit of 4GB.
Advanced Tab
Most of the database performance options are accessed by selecting the
Advanced tab of the Database Properties box:
Summary
There is a lot of choice when designing a Domino application. Many design
elements can be used in a variety of ways to build your solution. It is wise to
have a good understanding of all the facets of the design elements, both for
Notes clients and Web browsers, before committing the details of the design.
Performance is a major concern for application owners and as such, needs to
be considered right from the beginning. The next chapter will help you if
you are in the unfortunate position where the application is already
deployed but performance is not up to standard.
161
Network Performance
There are many different standards for network bandwidths around the
world. They vary from high speed Local Area Networks (LANs) to slow
dial-up Wide Area Networks (WANs), such as the Internet. Often the
development and testing of an application is done in a confined environ-
ment, where the application behaves differently than when it is opened up
to the rest of the user population. For example, the time needed to
download an Applet when testing in an office environment may seem
insignificant, but when a user attempts to download it from a slow dial-up
connection they may give up and choose not to use the application. In short,
a WAN magnifies network-related problems and can highlight areas that
may have been overlooked during prototyping and development.
Network Performance
A number of very basic tools can be used to test network response time.
These tools are very effective, and also have the advantage of being
available on a number of platforms.
Ping
The ping utility is used to test whether TCP/IP connection can be estab-
lished between two computers. This is a generic tool that works on most
platforms; however, the flags below apply specifically to Windows NT.
Netstat
Netstat is a Windows 32-bit utility used to display statistics about the
current network connections and what state they are in. It can be set in a
loop to check for connections every n seconds. This can be very useful in
checking the status of a connection to a server, or on the server it can be
used to see who has a connection to it.
The format is as follows:
netstat 5
Tracert
The tracert command is a Windows 32-bit command that is used to show
the route that a TCP/IP packet takes to reach its destination. This is often
very important in troubleshooting, since two clients will often take different
routes to the server and each may have its own characteristics. For example,
if the number of hops required in the live environment is more than in the
test environment, it is possible that the client will time out and not process a
request. Another potential problem is that the route the client attempts may
not allow the type of traffic that you are sending over it.
The format is as follows:
tracert www.lotus.com
1 1 ms 1 ms 1 ms C1.test.com [92.9.32.9]
2 2 ms 2 ms 1 ms R4.test.com [92.5.4.11]
3 * * * Request timed out.
4 * * * Request timed out.
5 2 ms 3 ms 2 ms www.lotus.com [198.114.66.50]
Trace complete.
Here we can see the route that has been taken from the client to the destina-
tion and the time taken for each hop. This will often provide useful infor-
mation if there is a significantly different response time either between two
servers or between two different clients accessing the same server. If the
routes are different, this could indicate that the difference in the network
is a cause of the problem.
Each operating system has a different set of tools that need to be used to
monitor its performance and limits. A similar set of factors are evaluated on
each platform. These include the following:
• Memory — Has the server got enough spare memory? Have specific
Domino tasks claimed a lot of memory?
• Swap/Virtual Memory — Virtual memory is slower than physical
memory. If a lot of virtual memory is being used it is possible that the
server does not have sufficient memory.
• Disk — Is there enough disk space? Is there a large amount of Disk I/O
activity and a lot of cache being used?
• CPU — If a process is consuming a lot of CPU time, then this is an
indicator that there could be a server issue.
Domino tasks for the Windows 32-bit operating system always start
with an ‘n’ so the update task can be seen in the Task Manager as
‘nupdate.exe’. From the Task Manager output shown, you can see the
percentage of CPU time that is currently being used by each task, the
total amount of CPU time each task has used, and the amount of
memory allocated to it.
You can also use the Task Manager if you suspect that memory leaks
are occurring. Choose View - Select Columns in the Task Manager
menu. Add a check for including column for the virtual memory size in
the processes view. Check the view over time. If a task uses more and
more virtual memory it may have a memory leak problem.
Server.Load
Server.Load has been available for Domino since 4.62. This tool was
primarily developed to stress test Domino servers and provide the
customer with a guide to the number of users and performance level
to expect from a specific hardware configuration. In the 4.6x version
of Server.Load, the basic task of the application was to simulate Notes user
sessions performing operations on the server. These operations can either
be one of three predefined tasks or you can create a custom script to test the
server. Server.Load for R5.01 has been further developed to incorporate
other protocols that Domino supports, including HTTP, SMTP, POP3,
IMAP and LDAP. In addition to these new protocols, the existing NRPC
protocol has been given added functionality.
The 4.6 version of Server.Load provides very little functionality to test
individual application performance, but it still provides some valuable
information. It can test for standard response times from the server before
your application is released, or before an upgrade. Then, once your
application is being used, it can test the response times again and check the
server loading. In the 4.6x version of Server.Load, you can customize scripts
that open databases and views then navigate through the view, opening
documents and so forth. The document creation ability of Server.Load is
similar to creating a simple mail message. Documents can be created, but
the tool enters text into the Subject field and text plus an attachment into the
Body field. This is not appropriate for most applications, since they
generally have a number of fields and require different types of information
to be entered into these fields.
With Server.Load for Domino 5.01 there is enhanced scripting language
capability for the Notes Client Simulation. It is now possible to create
documents in an application with many different types of fields. In
addition, the HTTP protocol is useful in testing Domino Web sites,
including the ability to enter information into a Web-based form and to
activate buttons and other links on the page.
Client Performance
Performance is generally a user perception issue. Even if the application,
server, and network are not the cause of an apparent problem, it may still
be reported that there is a problem with application performance.
Once all server-side issues have been eliminated as the cause, you should
consider the different client hardware configurations that probably exist in
your organization. Individual client circumstances, such as available
memory and processor type, can significantly affect performance. If there
are wide discrepancies in performance from one client to another, these
client-focused issues should be further investigated. Testing the client
performance can be done using a number of benchmark applications. These
applications can be written in Lotus Notes and run on several clients.
The Environment
One of the first steps in application troubleshooting is to set up a test
environment, which should be as similar as possible to the live environment
in which the problems are occurring.
You also need to ensure that view indexes that will be accessed are
either already built (by accessing them prior to the test) or are not built.
To remove view indexes from a database, run the following command:
load compact sales.nsf -d
This example removes all view indexes from the sales.nsf database.
Dial-up Networking
The use of a modem and a dial-up networking application gives you the
ability to test poor bandwidth access and also to record network
throughput. When you configure the modem connection speed you may
also decide to slow the connection speed down.
When you have a slow connection, you may notice things that are not
obvious when you are accessing the application using a LAN connection.
For example, you may notice a long delay when loading an item on a form
or opening a view. This method of using a very slow connection is good for
revealing performance bottlenecks.
Spray Daemon
The “spray” command is a UNIX command which can be used to send
network packets of a specific size between a client and a host. This is a very
useful command if you are working on a “clean” network. Using a spray
type command, we can simulate network load in a controlled manner. The
syntax of the spray command is:
/usr/sbin/spray Host [-c count] [-d delay] [-i] [-l length]
The flags in the square brackets are all optional. An example of this would
be:
/usr/sbin/spray odin -c 1200 -d 2 -l 1000
In this example, 1200 packets of 1000 bytes each will be sent, with a 2
microsecond delay between packets.
IPTrace
The “iptrace” daemon is a tool used to provide packet tracing for Internet
protocols. It is available for both UNIX and OS/2 platforms. It is useful for
collecting network information at a very low level about your environment.
The iptrace tool listens to a particular TCP/IP port on the server. By default
Domino uses port 1352 for sessions with Notes clients and port 80 for HTTP
sessions. Below is an example of the command to collect Notes client traffic
to the server.
iptrace -i en0 -p 1352 /tmp/notes.trace
I
P
T
Client R
A
C
E
Server
Client
Client
/tmp/notes.trace
This information can be read into another application and used to track
what is happening at an RPC level, as well as the amount (quantity in bytes)
of information sent and received by the server.
Note The server_clock setting must be used carefully, as it relates to the
information that is being generated and transmitted by the server. If there
are a number of clients connecting to the server, all client information will
be reported. For information specific to an individual client, use the
“Client_Clock”’ setting described later in this chapter.
Execution Control List
The Execution Control List (ECL) is a security feature built into the Notes client
to prevent unauthorized access to resources. It may also be used to enable the
troubleshooter to monitor some actions, such as @Db commands.
By refining the ECL you will be notified when commands are executed that
fall into a specific category, for example accessing external information,
where you may not have noticed that the application has an @DbLookup
command in a Validation field that is very slow.
Design Synopsis
The synopsis that the Notes client produces is a very useful tool to aid you
in finding particular design elements and references. It allows you to select
one, several, or all design elements, and displays the design details for the
selected items. You can then either scroll through the information that is
collected for you or use the find feature. Synopsis output can also be saved
as a database document.
The R4.x Design Synopsis was very useful for collecting standard
information about applications designed for Notes clients. Unfortunately, it
did not display any LotusScript formulas or events, and various Web
elements such as HTML attributes were not reported.
With the R5.x design client, the Design Synopsis is much more powerful. In
addition to reporting on various new design elements (such as pages and
outlines), it will now display LotusScript, HTML, Javascript and Java code.
The synopsis can also be stored in a database, which can enable you to
compare the design synopsis from different points in time to see design
changes.
The NotesPeek tool is available for download from the Notes Web site at:
http://www.notes.net
Select the downloads area and search for the version of NotesPeek that you
want.
Testing an Application
The methods for testing an application are slightly different for a Notes
client and a Web browser; however, the underlying techniques to perform
the testing are similar. Examine the performance of the application function
by function. This section describes the factors to consider for each function.
Views
Views are a common source of problems in application performance. They
can cause a problem when you attempt to open them, when you are navigat-
ing through them, when you are attempting to refresh them, and when you
are attempting to access information in them, either directly or indirectly.
Often, specific features in a view involve a trade-off between what performs
well (speed of opening) and what works the best (ease of access to correct
information).
The size of a view index is a good gauge of how complex the view is. This
can be collected in three ways:
1. Using a Server Console Command.
2. From the Design tab on the view properties.
3. From the Notes Log.
The following section describes each of these methods individually:
Using a Server Console Command
If you have administration rights to the Domino server, use the remote
console to issue the following Server Console command:
show database walt/redsampx.nsf v
Here we can see the sizes of all of the views in the ‘Redbook Samples’
database. The size of the view index will be dependent on the number of
documents and the design of the view.
Using the Notes Log
If you do not have access to either the Design of the Views or the Remote
Server Console, you can use the Notes log to show you the size of views for
the database. A task called StatLog runs daily on Domino servers. It collects
database information and writes it to the log file. If you go into the
‘LOG.NSF’ database and open the ‘Database\Sizes’ view, you will see a list
of databases in descending order of total database size. If you go down this
list, find your database and open the document, you are presented with a
list of all of the views in the database and the size of each.
Note The log also displays the size of private views stored in the database.
These views are shown with square brackets around them, such as [My
Documents]. If you see a large number of these views in a database, this is a
cause for concern with respect to database indexing.
View Opening
The speed with which a view is opened will depend on the index options
for the database, the amount of information sent to the client, and whether
the view index must be rebuilt prior to the view being opened. In situations
where there is a large amount of information being continuously entered
into the application, the view will take a long time to open.
Agents
Agents can be categorized into three types:
• Interactive Agents
• Background or Server Agents
• Web Agents
Views
Element Comment Alternative
@Today, @Now, and so Will cause the index to be Use techniques in Appendix
forth marked as not up-to-date B-1, “Time/Date Views”
when used in a view
Reader names May cause very slow Use private views or
performance when the navigator
user only has access to a
small percentage of
documents
Complex categorization Will cause a large view Refine view
index
Sorting ‘on the fly’ Will cause a large view Only sort columns that
index require sorting, don’t
duplicate what another view
shows
Unread marks displayed Dramatically slows down Use the
at all levels a view, as unread marks ViewShowOnlyUnread’
are calculated for each @Command
user when they open the
view
Many expandable All information is not Use the view property
documents sent up the network to ‘Collapse all when database
the client when collapsed is first open’
Use of response hierarchy Maintaining a response Use response hierarchy to
hierarchy can slow down link forms together via form
view access times design and not view
Large number of A complex selection Use a carefully constructed
documents in view formula will slow down a selection formula
view, but too simple a
selection formula, such as
SELECT @All, can also
slow a view down if there
are a large number of
documents
continued
Forms
Element Comment Alternative
Large number of This will slow down the load and Create multiple forms or
fields on use of the document use a more interactive
document form with prompts and
dialog boxes to improve
perception
Many @Db. Often the information used for Ensure that the fields are
commands keywords is used multiple times not refreshed unless
throughout the document necessary and try to load
the keyword information
only once at load time
Numerous ‘Hide These are generally used to control a Use dialog boxes to
When’ formulas user’s access throughout the prompt the user for
document information, or use
multiple forms or sub-
forms. Try to use the
‘Hide When’ check boxes
instead of formulas
Large number of The larger the number of tables, and Use tabs in the form
complex tables the more complex these tables are, design when possible;
the slower the load and refresh time minimize the complexity
of the form will be of tables
Auto Refresh The form option to auto refresh Use field events to change
fields fields is often only used to update the required fields or use
fields when based on a particular Hotspots
event
Validation Validating every field on the form Use field events to
formulas in many when saving or refreshing takes validate as the form is
fields time; for the Web it is done on the computed, or a single
server event as the form is
posted (LotusScript or
JavaScript depending on
your client)
Notes Talks
Notes can be very talkative in the network: “chatty” is a term that is often
used. By that we mean that Notes sends many messages between the client
and server to do its tasks. Not only does Notes send many messages, most
of them are small. Remember, the database often resides on the server (and
this includes both the data and design), but when the application runs, the
actual code is run on the client. That means that the code must be sent to the
client for execution. The data must also be sent to the client whenever
necessary. Any results, of course, must be sent back to the server.
A very useful piece of information, then, is to be able to determine what is
happening in the space between the client and server when your
application is running.
Code Profiling
When complex script is used in an application, it is often hard to understand
what is happening, how long it takes and how often it happens for individual
routines or subroutines. Code profiling is a method of logging these actions.
We can use code profiling to get a better understanding of what the code is
doing and how long it is taking. It is helpful to use code profiling in the
development and troubleshooting of LotusScript and Java code.
Prior to any specific operation being called ,we may wish to call the
following subprocedure from our script library:
Sub ProfilerRoutineBegin(strRoutineName As String)
There are also similar subprocedures that are called when you end your
operation:
Sub ProfilerRoutineEnd(strRoutineName As String)
If Not(gLog Is Nothing) Then
nTabs = nTabs - 5
Call gLog.LogAction(Space$(nTabs) & strRoutineName_
& “ END”)
End If
End Sub
Finally, just before you finish the agent, you can call:
Sub ProfilerTerminate()
If Not(gLog Is Nothing) Then
Call gLog.Close()
End If
End Sub
Sub Initialize
’ Profiler_BEGIN
Call ProfilerInit(“Sample Agent”)
Call ProfilerRoutineBegin(“Initialize”)
’ Profiler_END
Set db = session.CurrentDatabase
’PROFILER_BEGIN
Call ProfilerRoutineEnd(“Initialize”)
Call ProfilerTerminate()
’PROFILER_END
End Sub
’Profiler_BEGIN
Call ProfilerRoutineBegin(“CreateNewDocument”)
’Profiler_END
’Profiler_BEGIN
Call ProfilerRoutineEnd(“CreateNewDocument”)
’Profiler_BEGIN
Call ProfilerRoutineEnd(“AppendItemsToDocument”)
’Profiler_END
End Sub
Agent Start
Function Start
Main
Function End
Agent Log
Agent End
ProfileScript
Func 1
Func 2
MyAgent
Summary
In this chapter, we described what elements and features cause an applica-
tion to show poor performance. Once we identified them, we described
some of the tools that are available to help us to find performance hot spots.
We finished by looking at two methods that could help us to review
performance problems. The first method, reviewing RPCs, enabled us to
look at how much communication there was between the client and the
server. The second method, code profiling, allowed us to monitor the
execution of our code.
203
Appendix A-1
How Do You Put 8GB of Data in a 4GB Bag?
205
Problem Statement
We begin with the basic application requirements. In particular, these are:
• Huge database requirements, that exceed 15GB worldwide. Partitioning
this database by geographical region reduces but does not eliminate the
problem. The Americas region (currently 7GB) and the Europe, Middle
East, and Africa regions (currently 6GB) each significantly exceed the
4GB limit within Lotus Notes Release 4.x.
• A user population of over 50,000 worldwide, with approximately
20,000 registered users within the Americas and nearly that number in
Europe, Middle East, and Africa.
• Key user access profiles:
• Users within a given geographical deployment will typically need to
access fewer than 100 documents.
• Any given document will typically need to be accessed by fewer than
12 users within the geography.
• Any given user may be assigned to work with any document;
therefore, it is not possible to determine (a priori) a partitioning
scheme for the user population.
• No user is permitted access to a document unless specifically
assigned as a participant in that document.
• Double Byte Character Set support is required for the Northern
Asia-Pacific region (Japan) as well as key countries within the Southern
Asia-Pacific region (Korea, China, and Taiwan).
• Seamless, “real enough” time (on the order of less than hourly)
coexistence with the legacy application during the gradual migration of
users to Lotus Notes. This migration is anticipated to span two to four
months for each deployment.
The primary reason for the gradual migration requirement was to
ensure that the infrastructure could support the large and active user
population. By allowing as few as one user at a time migration, the
infrastructure could be continually monitored and adjustments made
before the network and servers became overloaded and the application
unusable. Alternatively, a “big bang” approach, where a large user
population is migrated at the same time, would not only make it
difficult to manage the infrastructure, but would make it extremely
difficult, if problems occurred, to determine which infrastructure
component or components were constrained.
Alternative Solutions
In order to meet the requirements and also comply with the internal
standards and guidelines, several architectural solutions were explored.
Lotus Notes 4.x has a size limitation of 4GB, with a performance implication
if the database size grows to more than 3GB. Every architecture solution
was measured against the following five important questions which had to
be addressed.
1. How do we put all of the data (or documents) in a single Lotus Notes
database with a 4GB size limit?
2. How do we manage the large user population or distribute the users to
get optimal performance?
3. How do we achieve participant-level security and keep the database
size small on the users’ workstations?
4. How do we make the application coexist seamlessly in “real enough”
time with the legacy VM-based application?
5. How do we comply with the applicable internal standards and
guidelines?
Appendix A-1: How Do You Put 8GB of Data in a 4GB Bag? 207
Authors and Readers field. All of the participants (their Notes IDs) would
be listed in the Authors/Readers field, and when a user replicated, he or
she would only get those documents in which their own ID is contained in
the Authors/Readers field. This means that when users replicated their
application database with the Application Data Server, they would only
receive those documents in which they were listed as a participant.
Application database agents on these servers would run every 30 minutes
to synchronize the data with DB2/MVS using MQ Series APIs.
VM SQL/DS Tier 3
DB2/MVS
Ev
er
in
y
m
30
30
m
y
in
er
Ev
MQ Series
Tier 2
Data Data
Server Server
Replication
Tier 1
This solution met the first four requirements but failed on the fifth
architecture requirement. The main drawback of this design was that it
violated internal guidelines. Application data servers cannot have agents
running every 30 minutes due to the severe performance impacts on the
user population when attempting to access those servers.
Since one of the main customer requirements was for the Lotus Notes
environment to coexist with the legacy VM application, we needed the data
on Lotus Notes to be synchronized frequently. This would enable the legacy
VM application users to access the updated documents within a reasonable
time (say a few hours). Failure to accomplish this violates our fourth
architecture requirement.
Up
da
VM SQL/DS
te
DB2/MVS
s
DB
2
ni
us
Tier 3 gh
tly
tly
in
gh
g
ni
M
Q
MQ Series
Se
rie
s
AP
Tier 2
Data Data
Is
on
Server Server
th
e
cl
Replication
ie
nt
Tier 1
This design eliminated the problem of running the agents every 30 minutes
on the application data servers, but had some other drawbacks. With this
approach there was more chance of users losing their changes if other users
were going to update the same document. Furthermore, installation of the
application would have required an MQ Series dynamic link library on
every client workstation, making the installation difficult and also requiring
additional software on the client. This was not in compliance with stated
internal workstation standards. Also, users would have to work in connected
mode more often, thereby taking away the Lotus Notes feature of working in
a disconnected mode.
Appendix A-1: How Do You Put 8GB of Data in a 4GB Bag? 209
Since a single Lotus Notes Release 4.x database could not handle the size
requirements for the Americas or Europe, Middle East and Africa, we
decided that no single document will exist on more than one staging server.
Each staging server will contain at most 20,000 base documents (plus all of
their associated response documents), which will keep the database size
optimal without any performance degradation. This allows the total
number of base documents to be distributed among multiple staging
servers and also makes the architecture scalable. If the number of base
documents grows too large, the deploying geographic centers can add
another Staging Server. In order to make sure the documents only end up
on one Staging Server, a pseudo-random algorithm will be used.
Tier 4
DB2/MVS
VM SQL/DS ev
in ery
0m 30
y3 mi
er n
ev
MQ Series
Tier 3
Staging Staging
Server Server
Replication
Replication
Tier 1
In this design (shown in the figure above), Staging Servers will have Lotus
Notes agents running every 30 minutes, sending and receiving new or
modified data to and from DB2/MVS using MQ Series. Each Staging Server
will replicate with all Data Servers using a PULL-PULL replication model.
Each staging server will pull all its documents and the data servers will pull
their documents. Then, when the client replicates its application database, it
will pull down all of the documents in which it is a participant (that is, the
client’s Notes ID is in the Reader Names field) and which contain changes
from the legacy system. The implementation details of this solution are
described in the next section.
Appendix A-1: How Do You Put 8GB of Data in a 4GB Bag? 211
• Data had to be partitioned across multiple replicas of the database since
no single instance of the database could contain all of the data within a
geographical deployment center. This required the introduction of a
scheme to isolate parts of the data onto separate replicas without
permitting all of the data to ever reside on a single replica.
MQ Series
Tier 3
Staging
Server
Replication
Tier 2
Data
Server
Replication
Tier 1
Client
Local
Appendix A-1: How Do You Put 8GB of Data in a 4GB Bag? 213
ASCII to EBCDIC character sets (and vice versa). Once all new and/or
modified information in the Lotus Notes environment is sent, the CICS side
of the interface transmits all new and modified data within DB2/MVS to
Lotus Notes. The messaging interface is a document-oriented data transmis-
sion in both directions, with all fields represented in a generalized data
stream. All transformations required to move the data from the document
model to or from the relational data model is handled by the CICS trans-
action. This includes, but is not limited to, the support for the data denor-
malization required within the Notes documents (for example, the same
field occurring in several different documents) as well as maintaining the
referential integrity required within DB2/MVS. All base documents and
their related response documents reside on this staging server.
MQ Series
Tier 3 Staging
Server
Replication
Replication
Tier 1
Each end user is assigned to a specific application data server based upon
their likelihood of sharing access to any given opportunity. The name of the
assigned data server is stored in an Authorized User Profile maintained by
the application. Whenever a user is granted access to a given base document,
Appendix A-1: How Do You Put 8GB of Data in a 4GB Bag? 215
that document and all of the related response documents that the user
requires will have the end user’s Notes ID and the ID of their assigned
application data server added to the Reader Names field.
This process ensures that all of the documents required by the end users
assigned to an application data server will be replicated to that server.
Furthermore, if there are no end users registered to a particular data server
that require access to a given base document, the name of that application
data server will not appear in the Reader Names field; thus, that document
will not be replicated to that application data server. Hence, we have
distributed the user population across a finite set of application data servers
with only those documents required by the users registered to that
application data server being replicated to that server.
The application data servers can be viewed as holding a distributed subset
of documents based upon the user population assigned to each server.
There is minimal duplication of documents across servers and maximum
sharing of those documents on a single server. Since there is a reasonable
amount of teaming within the application business process, this provides a
suitable way to distribute the data while not precluding cross-teaming
activity where necessary.
MQ Series
Replication
Tier 1
Appendix A-1: How Do You Put 8GB of Data in a 4GB Bag? 217
The process as handled within the application does not vary significantly
whether the individual is working through the legacy VM interface or using
the new Lotus Notes interface. The most significant difference is the
flexibility that is provided for enhancing the data accuracy within Notes
through the use of prompts, pick lists, dialog boxes, and on-the-fly data
validation that cannot be easily done within the legacy environment.
Therefore, we will examine the process from the perspective of an end user
operating within Lotus Notes. We will not dwell on the business data that is
entered, but rather we will focus upon what is done to “move” the
documents through the multiple tiers.
Creating a Document
When an end user wants to create a new base document, that activity can be
performed while totally disconnected from the network. All pertinent
reference information is available on the client workstation in a separate
reference database. The creation process guides the user through the data
entry process, and when complete, it creates a base document along with a
participant (response) document that contains information about the person
creating the base document. At the same time, a randomly selected staging
server is chosen to become the “owning” staging server for these new
documents. There may also be other response documents created,
depending upon the business data that is entered during the creation of the
base document.
Before the creation of the base document is complete, the following Lotus
Notes IDs are added to the Reader Names field in both the base document
and all of the associated response documents:
• ID of the owning staging server — ensures that the owning staging
server will get a copy of the base document and all of its related
response documents.
• Administrator support role — ensures that there will always be
someone who will have access to these documents on the servers.
• ID of the individual creating the base document — ensures that the
creator will have access to the documents that they have just created.
• ID of the application data server where this end user is assigned —
ensures that the intervening application data server will get a copy of
the base document and all of its related response documents.
At this time the only individual (aside from the administrators) who has
access to these documents is the person who created them. However, the
base document and all of its supporting response documents can readily
move throughout the tiered distributed data architecture as illustrated in
the next figure.
DB2/MVS
3
MQ Series
Tier 3
Staging Staging
Server Server
Replication
2
1 Replication
Tier 1
For example, this document and all of its supporting response documents
(or more simply the document set) will be replicated as follows:
1. At the next scheduled (or manually triggered) replication with the
application data server, the document set will be replicated to the
server.
2. At the next scheduled replication between the application data server
and the owning staging server, the document set will be replicated to
the staging server.
3. At the next scheduled DB2/MVS data synchronization with the owning
staging server, the document set will be synchronized with the
DB2/MVS relational database.
Of course it would not contribute to the business process of managing this
document set if there were no other people who had visibility to the set.
Hence, we must now add other people who will participate in the business
process and work with this document set.
Appendix A-1: How Do You Put 8GB of Data in a 4GB Bag? 219
The Participant document contains the information necessary to update the
Reader Names fields within the entire document set; however, the updating
of the Reader Names fields is not permitted by the client workstation. The
only exception is when it is originally being created and the Reader Names
fields must be initialized. All subsequent updating of the Reader Names
fields within the document set are handled by the “owning” staging server
when a new Participant document arrives. This ensures that there are no
replication conflicts created as a result of two existing participants adding
new participants at essentially the same time.
If two or more Participant documents arrive at the owning staging server
and they reference the same individual, all but one of them is deleted. In a
similar vein, participants are removed from a document set by marking
their Participant document “logically” deleted. The unique Participant
documents that are not “logically” deleted are then used to refresh the
contents of the Reader Names fields of the document set.
Participant information is also synchronized with DB2/MVS, thereby
enabling legacy VM users to become participants in the opportunity. In a
similar manner, participants added by the legacy VM user will create
Participant documents when they arrive at the owning staging server.
DB2/MVS
3
MQ Series
Tier 3
Staging Staging
Server Server
Replication
2
4
Data Tier 2 Data
Server Server
1 Replication
5
Tier 1
Appendix A-1: How Do You Put 8GB of Data in a 4GB Bag? 221
Performance Characteristics
The IBM Worldwide Integration Test Center (WWITC) performed a series
of performance tests on the application. The following is the summary of
their environment and test results.
The testing model used consisted of four application data servers and two
staging servers with MQ Series communications channels to a single
DB2/MVS host system. They did not include the legacy VM application as
part of their performance model since it would be phased out as the end
users were migrated onto the Lotus Notes environment.
The modeled workload, in terms of transaction and data volume, was based
on the estimates for North America. The performance test had five test
cycles, the first four of which examined individual components of the
application while the fifth tested the complete application system. While the
first four test cycles are interesting from a micro point of view, they do not
reflect the overall performance of the application since they focus
principally on the client.
110
Client to Working Set Server Staging Server to Working Set Server
100
90
70
60
50
40
30
20
10
CPU Utilization
Working Server 3 & 4
Combined CPU Usage
110 Client to Working Set Server Staging Server to Working Set Server
100
90
CPU Utilization Percentage
80
70 Working Set to Staging
60
50
40
30
20
10
0
Appendix A-1: How Do You Put 8GB of Data in a 4GB Bag? 223
Overall Performance Test — Part 2
The second part of this test cycle was run while some replication was still
occurring between the staging server and the application data servers as a
result of part one. The workload mixture was 90% updates and 10% creates,
which is typical of a production activity mix. The average throughput rate
for the various parts of the replication/synchronization are shown in the
following table. The next two figures show the CPU utilization on the
various application data servers during the two hour test period and
include the client as well as the staging server load.
Solution part Average throughput rate in seconds
per document set
Client to application data server 0.75
Application data server to staging server 0.51
Agent processing on staging server 1.07
MQ Series agent on staging server 1.4
MQ Series and MVS processing time (end-to-end) 1.67
CPU Utilization
Working Set Servers 1 & 2
Benchmark Run 5B
80
Working Set to Staging
70
60
50
40
30
20
10
60
50
40
30
20
10
Based upon the complete test results WWITC has concluded that the
application has passed the WWITC performance test certification and is
ready for deployment.
Future Applicability
In Lotus Notes Release 5, database size limitation is bound only by the
operating system-imposed limits, and is certified for 64GB. Even though
Lotus Notes Release 5 supports a 64GB database size, it is unknown how
the database performs when there are more than 1 million documents.
Tiered data architecture will still be applicable in a Lotus Notes Release 5
environment as it distributes the workload, document, and user population
across multiple servers.
Appendix A-1: How Do You Put 8GB of Data in a 4GB Bag? 225
Appendix A-2
High Performance Reference Databases
227
Based on presentations of how Domino R5.0 would include a mobile light-
weight directory, I wondered if I could create such a version for Notes
release 4. The answer is yes. Here is an example of how my implementation
compares to a traditional implementation of a directory for all IBM
employees:
Characteristic Lightweight directory Traditional directory
Database size 200MB > 1GB
Number of 3,000 400,000
documents
Number of fields 400,000 20,000,000
Number of views One, lookup on name only Many
First open Within 30 seconds (including loading User aborts before
the graphical navigator) completion
Full replication < 1 hour > 10 hours
Data Application field data only All employee data
With the view setting “Show multiple values as separate entries” turned on
for the column showing the “key” field (name and number) you create a
view with all the employees in it. As Notes does not tell you in the line
which entry of the multiple value field is shown, you are restricted to a one
column view.
The user cannot open a document from this view, as the user can in other
Notes applications, because the opened document contains the data for
multiple employees and in the application you cannot determine which
employee is selected in the view. So I created two forms, one to do a lookup
for employee information, and one for selecting names to be inserted in the
addressee fields in a memo.
Here is the formula for looking up employee information:
FIELD AllTExt := AllText;
key:=@PickList([Custom]:[Single];“”;“People”;“People”;“Select
a person”;1);
index:=@DbLookup(“”:“Cache”;“”;“People”;key;“Index”);
item :=
@Replace(@Middle(key;“(”;“)”);@Word(index;“%”;1);@Word(index;“
%”;2));
In the form, the displayed fields are computed from the field “AllText”
which contains all the person information.
Note In the above situation, you have to go to the lightweight directory to
do a lookup. You can also perform the lookup from another database. An
example of this is included, together with a sample lightweight directory
database, in the Web material that supports this redbook. Look in the
appendix “Additional Web material” for instruction on how to get the
sample databases.
The lesson learned here is that it is possible to create a big directory in a
Notes database which:
• Can be accessed reasonably fast (works over the phone for me)
• Replicates easily over the enterprise servers
• Can be replicated to a local workstation (a directory with all employees
of IBM Netherlands is 3.5MB and replicates within 5 minutes)
While a directory has been used in this example, the construction used is
useful for other large reference databases as well.
The maintenance (insertions/deletions) of the data is more complicated
than in other applications. You can no longer delete a record by deleting a
document in the database. Instead you have to process the index or rebuild
the document with all the records within. For an example of how to do this,
check out the Lightweight Name and Address Book template described in
the appendix “Additional Web material.”
Monitoring Tools
The first set of tools that we discuss are tools that are used to monitor the
health of either an application or a server. These tools are often best used to
assist you in troubleshooting your applications.
231
Candle ETEWatch
End-To-End Watch (ETEWatch) is a relatively new product by Candle. It
provides warnings and statistics for application performance. The
difference between this product and the previously described one is that
ETEWatch monitors “round-trip” performance. In other words, it works
from a client and is triggered when the user begins a process and completes
when the server has sent its response back. This is a very useful tool for
finding applications that are not meeting their expected performance.
Information on ETEWatch can also be found on the Candle Web site.
Coast WebMaster
There are a number of excellent tools on the market to monitor Web site
activity. WebMaster from Coast Software Inc. is one. A key feature of this
tool is that it can reassemble the contents of the Domino log of HTTP events
into much more meaningful information, such as the most requested images
or pages. This information can then be used to analyze the usage pattern
and reconstruct the site if required. The Coast Web site can be found at:
www.coast.com
Websizr
Prior to Server.Load for Domino R5, it was not possible to place load on the
HTTP task of Domino using Server.Load. The Websizr tool allows you to
send HTTP requests to a Web server. What this means for Domino is that
the HTTP task can have HTTP requests sent to it. These can be in any URL
formats. Websizr is provided by Technovations. More information can be
found on their Web site at:
www.technovations.com
Groupsizr
The Groupsizr tool, also from Technovations, works in a similar fashion to
Server.Load for Domino R4.6. It simulates Notes Remote Procedure Calls
(NRPC) to a Domino database and server. The tool can simulate a large
number of user and record response times. Information on this tool can be
found at the Technovations Web site.
Proactive Assistant
The Proactive Assistant tool works in a different manner than most tools for
monitoring application performance and placing load on the server. Most
tools send RPCs to the server and do not interact with the Notes client.
Proactive Assistant, on the other hand, simulates a client’s session by
navigating through the fields on a form and filling them in. The time taken
to do this is logged and a report can be produced.
This is very useful to see what effect the actual design of a database has on
performance. The tools that simulate NRPCs all work “behind the scenes”
in Domino, sending the commands that the Notes client would send and
not requiring the client to send these commands. The Proactive Assistant
tool can be used to provide proof that by changing an application’s design
we are improving the performance of the application. In addition, it can
also be used to test the difference in Notes client performance between two
different environments. This can be done by generating a script and using it
in both environments, then checking the difference in the response times.
More information on Proactive Assistant can be found at the G2 Associates
Web site at:
www.g2sys.com
This appendix describes the various options available when creating views
which contain time/date @functions in the selection formula or in a column
formula.
Much of this material is from the Lotus Technical Paper 147114, available in
the Lotus Knowledge Base at
http://support.lotus.com/
Background
Time/Date views in Notes can cause performance problems, yet they are a
very important way to display information to the user.
To appreciate the value of Time/Date views, think about the following
examples:
• A view that displays only Severity One problems that have been entered
today.
• A view that displays only orders placed within the last seven days.
• A view that displays only technotes updated within the last 30 days.
• A column in a mail file that displays either the time or the date a
message was sent. If the message was sent today, it displays just the
time; otherwise, it displays just the date.
Why do these views cause performance problems? The reason is that the
selection formula or column formula contains @functions such as @Today or
@Now and as such, the formula result is never static. Because of the
changing nature of the @function results, the index needs to be updated
every time the view is accessed. Unless you have a small set of data, this is
going to make the view slow to display.
Several techniques have been developed to allow time/date views to have
good performance, even if they contain a large set of data.
235
Creating Time/Date Views Using Selection Formulas
Here we describe three ways to create time/date views using selection
formulas, and we identify the pros and cons of each method.
Selection formula
Select all documents with a DueDate within seven days of today.
SELECT @Adjust(DueDate; 0;0;7;0;0;0) > @Today
Advantages
• This kind of view will always be up to date.
• There are no other tasks to perform.
Disadvantages
• When you open the view the index must be rebuilt. If the number of
documents is more than a handful, there will be a noticeable delay,
perhaps many seconds for large views.
• The view refresh symbol will always display in the top left, indicating
(incorrectly) that the view is out of date. This will encourage the user to
click it (or press F9). Doing so will cause a similar delay to the one
experienced when the view was opened.
• Whenever UPDATE or UPDALL runs against the database, this view
will need to be completely rebuilt.
Selection formula
Select all documents with a DueDate within seven days of an environment
value.
SELECT @Adjust(DueDate; 0;0;7;0;0;0) > @Environment("Today")
• The view index must be rebuilt once per day, after the environment
variable has been set. This can be accomplished using:
UPDALL dbName -r -t viewName
Advantages
• There is no delay when opening the view.
• The view refresh symbol behaves normally. That is, the symbol appears
only if updates occur while the view is open.
• When UPDATE or UPDALL runs against the database, the view will
update very quickly.
Disadvantages
• If the agent fails to run, the view will be out of date.
• If you make a replica copy on a new server and forget to create an agent
on this server, the view will not function properly (in most cases, the
selection formula will return an error and the view will display nothing).
In fact, prior to the first time the agent runs, the view will not function
properly.
• If the program record fails to execute, the view will be out-of-date (until
either the server performs the view rebuild, or a user presses SHIFT+F9
while in the view).
• If you make a replica copy on a new server, and forget to create a
program record for that server, the view will correctly display the first
time it is used, but will thereafter be out-of-date (until either the server
performs the view rebuild, or a user presses SHIFT+F9 while in the
view).
Other tasks
• The view must be updated once per day, after midnight. This can be
accomplished using:
UPDALL dbName -r -t viewName
Advantages
• There is no delay when opening the view.
• The view refresh symbol behaves normally. That is, the symbol appears
only if updates occur while the view is open.
• When UPDATE or UPDALL runs against the database, the view will
update very quickly.
• You do not have to run an agent every night to update an environment
variable.
• The view will never simply “not function properly.” The worst case
scenario is that the view will not be up to date. When it is first created, it
will be up to date automatically.
Disadvantages
• If the program record fails to execute, or if you make a replica copy on a
new server and forget to create the program record for that server, then
the view will be out-of-date (until either the server performs the view
rebuild, or they press SHIFT+F9 while in the view).
Selection formula:
Select all documents with the “DisplayInView” mark set.
SELECT DisplayInView = “1”
Other tasks
• Code is required in the QuerySave event to initialize the DisplayInView
field to “1” during document save. In our example, the setting would be
dependent on the value of DueDate. If DueDate is within seven days of
today, we set the indicator; otherwise we clear it. This QuerySave code
must be in every form that creates documents which will appear in the
view.
• An agent must be run daily to update the DisplayInView field:
'*** Update all ‘DisplayInView’ indicators
Sub Initialize
Dim s As New NotesSession
Dim db As NotesDatabase
Set db = s.CurrentDatabase
Dim dc As NotesDocumentCollection
Dim datetime As New NotesDateTime( "" )
Set dc = db.Search( {@adjust(DueDate; 0;0;7;0;0;0) < _
@Today & DisplayInView = "1"}, datetime, 0 )
Advantages
• There is no delay when opening the view.
• The view refresh symbol behaves normally. That is, the symbol appears
only if updates occur while the view is open.
• When UPDATE or UPDALL runs against the database, the view will
update very quickly.
• There is no need for a program record in the Domino Directory.
Disadvantages
• If the agent is not run, the view will be out-of-date.
• If the database replicates, changes must propagate to other replicas
before the first users enter the database in the morning.
• The database search may be resource intensive for large databases. This
is particularly important if many views require time/date document
updates, either in this database or others on this server.
Selection formula
Not applicable. Folders do not have selection formulas. Documents are
moved in and out of folders under program (or user) control.
Other tasks
• Code is required in the QuerySave event to put the document into the
Most Recent folder. In our example, the action would be dependent on
the value of DueDate. If DueDate is within seven days of today, we put
the document into the folder. If not, we remove it from the folder, if
required. This QuerySave code must be in every form that creates
documents which will appear in the folder.
Advantages
• There is no delay when opening the folder.
• There is no need for a program record in the Domino Directory.
• There are no modifications made to documents (placing a document into
a folder updates the folder, not to the document).
Disadvantages
• If the nightly agent is not run, the folder will be out of date.
• If the database replicates, changes must propagate to other replicas
before the first users enter the database in the morning.
Background
Normally, script libraries are statically bound to design elements, such as forms
or agents. Syntax checking and name resolution occur at compile time.
When a design element is loaded, all the script libraries named in its Use
statements are also loaded.
For applications that are highly object-oriented, it is common for script
libraries to be used to define the object classes. Usually there is one class per
script library. This makes it easier to manage in a team development
environment and avoids any 64K limitations.
Problem
We run into problems, however, when our class library grows. Large class
libraries have many interdependencies among classes.
Many dependencies exist at compile time that aren’t relevant at run time. For
example, only one or two methods of a class might be called during a given
execution. The classes or methods actually used at run time may depend on
the type of data being processed.
Example
Use "Schedule"
Class X
...
Sub y
Dim sched As Schedule ‘<— Only reason Schedule needed
...
End Sub
...
End Class
243
In this example, class X, which might have many methods, uses the Schedule
class in only one of its methods. But any user of the class must deal with the
loading and linking time for the Schedule script library, whether they call the
y method or not.
Example
Use "Tape"
Use "Diskette"
Use "CDROM"
Sub processDoc(doc As NotesDocument)
Dim part As Variant
Select Case doc.ClassName(0)
Case "Tape"
Set part = New Tape
Case "Diskette"
Set part = New Diskette
Case "CDROM"
Set part = New CDROM
End Select
Call part.setDoc( doc )
Call part.doSomething
...
Delete part
End Sub
Circular references
A more serious problem is a common occurrence when dealing with many
interdependent classes: circular references crop up. In this example, class X
has a method, xx, that needs to construct an object of type Y, so it must use
the Y script library. But class Y has a method, yy, that needs to construct an
object of type X, so it must use the X script library. This causes a compilation
error. Of course, this is an overly simplified example; often there are many
more than just two classes involved in the circular reference loop.
Use "Y" Use "X"
Class X Class Y
... ...
Sub xx Sub yy
Dim y As Y Dim x As X
... ...
End Sub End Sub
... ...
End Class End Class
Solution
We need a way to dynamically load script libraries on demand for only those
classes that are needed at runtime for the data being processed. We also
must avoid compilation problems.
The solution is to use the LotusScript Execute statement to execute a Use
statement at runtime for the classes needed at that time. The Execute
You may wonder why we use the Factory classes at all. Script libraries are
cached in the cache.dsk on the client. Is there a difference in caching between
standard linking and dynamic linking? The answer is that Factory classes are
used to minimize the number of times that the Execute script needs to be
compiled when NewObj is repeatedly called for the same class. For example,
look at this code:
Dim doc as NotesDocument
Dim obj as Variant
Set doc = collection.getFirstDocument
While Not doc is Nothing
Set obj = NewObj( "MyClass" )
Call obj.setDocument( doc )
...
Delete obj
Set doc = collection.getNextDocument
Wend
Usage Example
Here we show you how to rewrite the earlier processDoc example to use
NewObj.
Evaluation
Benefits
The key benefit of this approach is that script libraries are only loaded when
needed. Once the library is loaded, there is hardly any further penalty for
using NewObj.
Another major benefit is that compile times are shortened, since all the
classes required for objects constructed at runtime do not have to be loaded
at compile time. Returning to our previous example, here the X script library
doesn’t have to use the Y script library at compile time. Instead, when a Y
object is needed at runtime, the Y script library is loaded dynamically. Of
course, this comes at the price of sacrificing syntax type checking, since
Variants are used.
Also, as in this example, the circular-use problem is solved. Here, X and Y no
longer need to use each other, since they are loaded at runtime as needed.
Use "NewObj" Use "NewObj"
Class X Class Y
... ...
Sub xx Sub yy
Limitations
The limitations imposed by NewObj are minor. As noted before, classes to be
used with NewObj must conform to some conventions. Also, this technique
only works for classes, not script libraries containing only standalone subs or
functions (although standalone subs or functions defined in the same script
library as a class can be called once the script library is loaded via NewObj).
Performance tradeoffs
As with most solutions, this one has its tradeoffs. On the positive side,
NewObj minimizes the amount of code that needs to be compiled during
development and loaded and linked at runtime. Also, script libraries are not
loaded until just before they are needed, so users don’t have to deal with the
performance penalties of waiting for code to be loaded that they may or may
not need.
On the negative side, there is a small performance cost in compiling the
Execute script. There is also a small penalty for using Variants instead of
typed objects, but in many cases where polymorphism is required this
penalty is unavoidable, even without using NewObj. For example, in the two
examples shown earlier, a Variant was required whether using Select Case or
NewObj. Although not a performance consideration, it is also true that using
Variants reduces type safety.
Conclusion
In conclusion, the technique shown here yields big savings in the time
needed to load and link script libraries by loading only those libraries
needed at runtime; it allows script libraries to be structured better for team
development by allowing one class per script library; it results in shorter
compile times during development; and it eliminates circular use errors
during compilation.
When unavoidable processing time occurs, the user will benefit if visual
feedback is provided about the status of the processing.
This appendix contains samples of methods of displaying progress
information to a user during extended processing.
Followed by:
200 documents processed...
Can be an effective and simple way to show the current status to a user.
If the message contains some indication of how much processing is left, then
the user has an even better indication of the current status:
300 documents processed, 1202 left to go...
One problem with this last technique is that sometimes processing is via a
view, and it is not easy to determine how many documents are in a view.
The function “ViewCount” described at the end of this appendix might be
helpful.
251
Dim db As NotesDatabase
Set db = s.CurrentDatabase
Dim dc As NotesDocumentCollection
Set dc = db.AllDocuments
Dim doc As NotesDocument
Dim i As Long
Dim ii As Long
Set doc = dc.GetFirstDocument
i& = 0
While Not doc Is Nothing
’*** Process the document
’<whatever processing required>
’*** Display progress
i& = i& + 1
Call PercentComplete(50 , i& , Clng(dc.Count))
Set doc = dc.GetNextDocument(doc)
Wend
End Sub
Function PercentComplete(barLen As Integer, _
curCnt As Long, _
totCnt As Long) As String
’*** Purpose: Displays a percent complete progress indicator
’*** in the print area at the bottom of users screen.
’*** barLen = The length of the progress bar (# of chars)
’*** curCnt = The current count
’*** totCnt = The total count (this count makes 100%)
Dim curLen As Integer
Dim perComp As Integer
Static svPC As Integer
Static svLen As Integer
’*** Calculate length and percent complete
curLen = (curCnt * barLen) \ totCnt
perComp = (curCnt * 100) \ totCnt
Instead of a text message, the status bar shows an (almost) graphical display
of progress.
ViewCount
The following routine returns the number of documents in any non-categorized
view. It uses a binary chop technique to get to the end of the view very quickly.
For example, in a database of over 43,000 documents, it took only 23 calls to
GetNthDocument to determine the exact number of documents in the view
(which was 43,487). That means that the overhead of getting the total count for
progress bar use was much less than 1/10 of a percent.
Function VwCount(vw As NotesView) As Long
’*** Pass in a NotesView object
’*** Returns the number of docs in the view
’*** Note: If the view is categorized - this function
’*** counts the top-most categories only
Dim docLo As NotesDocument
Dim docHi As NotesDocument
Dim done As Integer
Dim fellOff As Integer
Dim rCtr As Integer
Dim inc As Long
Dim posLo As Long
Dim posHi As Long
’*** Initialise
VwCount& = 0
done% = False
fellOff% = False
rCtr% = 0
If (vw Is Nothing) Then
’*** No view
Exit Function
There is generally not a great need for sorting when building applications
with Domino; however, if you do need to sort, this appendix will help you to
determine the method to use.
Some of the methods used in this appendix have come from Algorithms by
Robert Sedgwick, Addison-Wesley 2nd Edition, April 1988, ISBN
0201066726.
Sorting Algorithms
There are many sorting algorithms documented in many programming
books. We’ve tested various algorithms and have picked out a few for
inclusion here.
The ones we picked are interesting for a number of reasons. Our criteria for
inclusion included the following factors:
y Is the algorithm fast?
y Is the algorithm a common one, but slow?
y Is the algorithm easy to understand?
y Does the algorithm scale well?
y Does the algorithm work well under all conditions?
257
Where Can You Find Sorting Routines?
We have seen a few sorting routines described in the various Domino
forums and picked some of these for testing. We had some interesting results
with the very first one we chose to test:
• Several comments in the forums mentioned that, although there were
few comments in the code, it was not a problem. The routine was a
“library” routine so maintenance would not be required. However, we
found one bug and two performance inhibitors.
• The routine was obviously copied from either a book or another
program (it had wrong syntax). The main looping variables were
declared as:
Dim i, j, k, upper, lower, temp As Integer
As we can see, this means all looping variables are variants, except for
“tmp”. As we also are aware, variants are much slower than integers.
• One part of the code tested against 0, which is fine when your array
bounds start at 0. This code failed for arrays starting at 1 or greater.
• The routine had the option of sorting with or without case sensitivity. It
worked, but the code used a simple “<” for the compare. The
“StrCompare” internal LotusScript function is faster and takes into
consideration the collation table. Actually, for case-sensitive sorting
there was no appreciable difference in speed, but for non-case-sensitive
sorting, the “<” code was twice as slow, since it had to “same-case” each
string before the compare.
Tip Don’t pick an algorithm that doesn’t have credentials.
After our experience with our first sort routine, we decided to do a bit more
investigation, so we used a book called Algorithms by Robert Sedgwick to
give more credibility to this document.
Bubble Sort
We’ll start with the Bubble sort. We can hear some of you say “I knew that
was a good way to sort,” while we can also hear cries of “Why is that one
in here?”
The Bubble sort is described here because most of you have seen it during
your education. Unfortunately, it performs very badly in most cases. There is
one case, however, where the Bubble sort is the fastest type of sort — if the
array is already in order.
End Sub
Selection Sort
This is a very easy sort to understand and is very useful when dealing with
small amounts of data. However, as with Bubble sorting, a lot of data really
slows it down. Selection sorting does have one advantage over other sort
techniques. Although it does many compares, it does the least amount of
data moving. Thus, if your data has small keys but large data area, then
selection sorting may be the quickest.
Below is the code:
Public Sub selectionSort( ar( ) As String )
’*** For i = 1 to N-1
’*** // Find the smallest in the unsorted part of the
’*** // array on each loop and remember its index
’*** Set minimum index iMin to i
’*** For k = i+1 to N
’*** If item at k is less than item at iMin Then
’*** Set iMin to i
’*** Loop
’*** Exchange the item at iMin with entry at i
’*** Loop
End Sub
Insertion Sort
This sort can be useful when adding one or more items to an existing array
which is already in order. The new items are added to the array and the
array is resorted. With small additions, this can be fast, but sorting an entire
array can be very time consuming for large amounts of data.
Below is the code:
Public Sub insertionSort( ar( ) As String )
’*** For i = 1 to N-1
’*** // i is the upper bound of the sorted part
’*** // of the array
’*** // On each main loop, take item at i+1 and see
’*** // where it inserts in the sorted part of the
’*** // array
’*** // As you pass each item > i, move it up one
’*** // slot, making room for i when we get there
’*** newItem = item at i+1
End Sub
Dim i As Integer
Dim k As Integer
Dim s As String
Dim tmp As String
If R% > L% Then
’*** Partition the array into two ’halves’
s$ = ar$( R% )
i% = L% - 1
k% = R%
Do While True
Do
i% = i% + 1
End Sub
Heap Sort
Heap sort is another complex sorting routine. It is based on a “complete
binary tree” algorithm and is well understood; however, the code can be
daunting. It is almost as fast as QuickSort but is also consistent for any initial
data sequence.
Below is the code:
Sub heapSort( ar() As String )
’*** 1. Reorder the array so that it is a “complete
Upper% = Ubound(ar)
Lower% = Lbound(ar)
If (Lower% = Upper%) Then Exit Sub
End Sub
Shell Sort
Here it is — the final routine in a long list of sort methods. Does that mean
it’s the best? Well, in our opinion, yes, the shell sort seems to be the best
general purpose sort routine to use.
Shell sort is almost as fast as QuickSort, has similar speed regardless of the
starting sequence of the data, and is very simple. Its only negative aspect is
that no one can explain why Shell sort works this well.
Below is the code:
Public Sub shellSort( ar( ) As String )
’*** Do a shell sort
’*** Notice the lack of other comments
’*** - I’m not sure how it works !
’*** Routine taken from Sedgewick
h% = 1
Do
’*** Determine starting ’h’
h% = (3*h%) + 1
Loop Until h% > Upper%-Lower%+1
End Sub
Bubble Sort
Pros:
• Easy to understand and code.
Cons:
• Only works at a reasonable speed with small data.
Selection Sort
Pros:
• Easy to understand and code.
Insertion Sort
Pros:
• Can be used to add to existing sorted arrays.
Cons:
• When sorting an entire array, it is slow with large data.
Quick Sort
Pros:
• Fastest sort when data is in random order.
Cons:
• Complex to understand.
• For data that is in order or reverse order, it can take ten times as long as
with random data.
• Needs a lot of stack space. The recursive version blows the stack when
data is in a reasonable order at the start.
Heap Sort
Pros:
• Is well understood. Since we can easily determine the path through the
binary tree, we can guarantee the maximum compares and moves.
• The data order has no major affect on the performance.
• Scales very well.
Cons:
• Very complex code.
Shell Sort
Pros:
• It is very fast. The only faster sort was the QuickSort, and then only
when the data was in random order.
• It is easy to code. The only complexity is dealing with “h” (see code).
Case Sensitivity
A very simple rule should be applied here: Use the LotusScript
“StrCompare” built-in function to do the compares. It has the same speed as
the “<” operator but works equally fast for any case or accent situation. To
simulate case-insensitive sorting with the “<” operator, you will need to
“same-case” both sides of the comparison. This takes time and will slow
your sort down by as much as 100%.
Sort Order
During our tests, we found that sort order had no effect on the test results.
Results
Here we have some graphical results of various data sorted by the different
sort routines.
Sorting Times
The following graph shows the times for sorting various numbers of strings.
The times are for the sorting operation only — data setup is not included.
8
Bubble sort Quick sort
Seconds
6
Selection sort Heap sort
4 Insert sort Shell sort
0
100 200 400 800 1600 3200
Number of items
Number of Compares
100
0
100 200 400 800
Number of items
Conclusion
Sorting can be a complex issue to decide. The amount of time taken to get
your data into arrays to allow you to use a sort routine may be longer than
the actual sorting. You then will need to get the sorted data out of those
arrays. You may be able to sort the data as you are preparing it or use the
resulting array as is.
There are many factors that influence the type of sort to use. Maybe creating
an extra view will solve all your problems.
In any case, you’ll need to think about your sorting needs. The examples
here use internal arrays of strings, so the problem is nicely encapsulated. For
these examples, the shell sort routine seems to be the easiest to code and
provides excellent performance.
If you are in a position to require a sophisticated sorting routine, spend some
time understanding these routines, and do some reading. The differences in
performance can be amazing!
Sample Application
The following sample application illustrates some of the techniques of
seamlessly navigating between databases.
This sample application is a simple banking application which maintains the
following data:
• Customer data
• Accounts data
• Transactions
273
The end users of this application will be the clerks of the bank. The customers
approach the clerk to open a new account and to do money transactions. The
users are authorized to access all the above-mentioned types of data.
The three different types of data are stored in different Domino databases.
The user should be able to switch between these databases without having to
close the application. The navigation between the databases should be trans-
parent to the users. When the user highlights a customer data document in
the Customer database, and switches to the Transactions database, the transac-
tion documents for that customer should be highlighted.
When the user switches to the Accounts database, the related documents in
the Accounts database for John are highlighted.
LibSystemSetup
This library contains the definition for the class SystemSetup. This class has
the following methods:
• New
• GetDBType
• GetDatabaseName
• GetAllDBNames
Class Variables
The class contains an instance of the NotesDatabase class and the
NotesSession class.
session As NotesSession
curDB As NotesDatabase
New
The constructor of this class actually creates an instance of the NotesSession
class and the NotesDatabase class.
Sub New
Set session = New NotesSession
Set curDB = session.currentDatabase
End Sub
GetDBType
Following is the LotusScript code of the method GetDBType.
Function getDBType As String
If (curDB.FileName = “redcust.nsf”) Then
getDBType = “CUSTOMER”
Elseif (curDB.FileName = “redacct.nsf”) Then
getDBType = “ACCOUNT”
Elseif (curDB.FileName = “redtran.nsf”) Then
getDBType = “TRANSACTIONS”
Elseif (curDB.FileName = “redmain.nsf”) Then
getDBType = “MAIN”
End If
End Function
getDatabaseName = 0
The first parameter to this method is the logical name of the database. The
second parameter is a string list. The method returns this list with two
strings. The first string contains the name of the server. The second string in
the list contains the physical file name of the database.
LibViewNavigator
This script library contains the definition for the class ViewNavigator. This
class has the following methods:
• SwitchToDb
• SetIniVars
The LibViewNavigator script library uses the LibSystemSetup library.
SetIniVars
Following is the LotusScript code for this method.
Sub SetIniVars
Dim curSession As New NotesSession
Dim dbType As String
’Get the logical name for the database to switch to.
dbType =
curSession.getEnvironmentString(“RED_SWITCHTO_DB”)
Call Me.switchToDb(dbType)
End Sub
This method gets the logical name of the database from the environment
variable and calls the other method of the class.
This agent creates an instance of the class ViewNavigator and calls the
method setIniVars. (Don’t confuse this method with the agent.)
The setInivars method obtains the logical name of database to switch. In this
particular case, it will be Account.
The setIniVars method in turns call the other method SwitchToDB and passes
the logical name of the database to this method.
Now, the method SwitchToDB obtains the Key value for the selected
document. In this particular case, it will be 903412. This value is also stored
in the environment variable.
The SwitchToDB method creates an instance of the class SystemSetup from
libSystemSetup.
The switchToDB method calls getDatabaseName method of SystemSetup class.
The logical name of the database to be switched is passed to this method.
This method returns the physical file name and the server name.
The switchToDB method calls getDbType method of SystemSetup class. This
method returns the logical name of the current database.
The switchToDB method calls getDatabaseName method of SystemSetup class.
The logical name of the current database is passed to this method. This
method returns the physical file name, and the server name.
The physical file name and the server name of both the current database and
the database to be switched are stored in the environment variables.
This agent obtains the physical file name of the database to switch and the
server name from the environment variables and opens it.
The current database window is closed.
285
Workarounds for Two Related Issues: The Performance Hit from
@UserRoles and Emulating Local Roles Without Using Enforce a
Consistent ACL
At my company, we generally cannot use “Enforce a consistent Access
Control List across all replicas of this database” since we have scores of
domains that have different internal ACL requirements. Using the feature is
equivalent to disabling cross-domain replication.
However, we often want to use Roles in those databases for which people
create local replicas. While roles are never to be used for security purposes,
they make offering different features to different types of users easy to
maintain and to code.
I began developing a workaround that allows including the role functional-
ity in local replicas without entailing a great deal of maintenance by Notes
development staff, or requiring hard-coded user names in forms or keyword
lists that would inevitably get out of sync with the groups used in the ACL.
While optimizing my @DBLookups, I happened to have the Notes Debug
Window open (see Appendix B-8, “Using NRPC Output”) to examine server
transactions, to understand the performance hits of various things while I
was experimenting.
I correlated a large number of server transactions (24 in one particular form)
to the large number of @UserRoles function calls I was making on a form
and its sub-forms. The @UserRoles functions were being called both when
the document was loaded as well as when it was refreshed, due to the
“Refresh fields on keyword change” setting, a feature that was required for
the application. Most of the calls were in Hide-When formulas, but there
were a few scattered about elsewhere.
After some experimenting, I found that every time an @UserRoles function is
executed from a document stored on a server replica, you get a pair of
client-to-server transactions such as:
(819-10223) GET_SPECIAL_NOTE_ID: 153 ms. [16+16=32]
(820-10223) OPEN_NOTE: 381 ms. [28+5910=5938]
Yes, the values are small, but they can (and did) add up. The timing values
above are real-world fast ethernet values. Imagine a dial up connection
with 12 pairs of those every time you refreshed the form or tabbed out of
certain fields!
Also, create a simple view called LookupRoles with the following selection
and column formulas:
View alias Selection formula First column value
LookupRoles ’Select Form = “LookupRoles” Readers
Create and save one document for each of the roles in the database.
Remember to do this any time you add a role to the application or write a
script agent that keeps them up to date.
Now we have role lookup documents that will replicate to local replicas only
when the end user has that role to begin with. If I only have [Role1] on the
ACL and not [Role2] and [Role3], my local replica will only contain the
document for [Role1] in the view when I replicate it down.
Back to @UserRoles performance. Let’s make it so that @UserRoles function
is only ever called once, and that is only on document load (or create). Let us
also include the lookup to the LookupRoles view during that process.
On all forms or subforms that use @UserRoles, replace all references to
“@UserRoles” with just a reference to the field “UserRoles”. Remember to
also do this for hide-when formulas in: all table cells, blank lines, action
buttons, access controlled section formulas, you name it.
Appendix B-6: Supporting Roles Locally Without Enforcing Consistent ACL 287
Then add the following two hidden fields at the top of the form (in this order):
Field name Properties Value
UserRolesOnLoad Text, Formula that looks up local roles when
Multi-Value, document loads and caches them in the
Computed For document for future reference — See the
Display actual code below
UserRoles Text, Formula that removes the cached roles before
Multi-Value, the document is saved — See the actual code
Computed below
Caution If the person’s roles change, but they already have a local replica
of their existing role documents (with the ‘old’ roles) the roles may still exist
in the local replica. One way to address this is to have a server-based agent
that touches all role documents once a day to make sure they are rechecked
during replication. Another more cumbersome way is to have users with
changed roles clear the replication history and re-replicate before the “local
roles” can be guaranteed to be correct.
Appendix B-6: Supporting Roles Locally Without Enforcing Consistent ACL 289
Appendix B-7
Cascaded Deletions Example
Relational Databases
In relational databases, the data resides on multiple tables. Rows of
different tables are related through the foreign key. The relational database
applications are based on the Entity-Relationship model, where both the
entities and relationship between the entities of the system are represented
by tables.
For example, consider an inventory management application developed
using a relational database. The Supplier table contains the details of different
suppliers. The Parts table contains information about the different items in
the inventory. The Supplier-Parts table has information about who supplies
which part.
Supplier Table Supplier ID Supplier Name
123,567 James Wood
867,458 John Joe
512,890 Siva Sunder
291
Supplier - Parts Table Supplier ID Part ID
123,567 IA
512,890 2D
123,567 2D
The Supplier ID is the primary key for the Supplier table and the Part ID is the
primary key for the Part table. These primary keys are used as foreign keys
in the Supplier-Part table. Relational databases will not allow the row for the
part steel bar in the Parts table to be deleted because it is referred to by some
of the rows in the Supplier-Part table.
In other words, relational databases will not allow the user to delete a row, if
the primary key of the row is used as foreign key in any other table.
But the relational database application can be programmed to delete the
rows in different tables which are related. To delete the row for steel bar in
the Parts table, use the following steps:
1. Delete all the rows in the Supplier-Part table that refer to steel bar
(Rows 2 and 3).
2. Now delete the row for steel bar in the Parts table.
These deletions can be done using the Structured Query Language (SQL).
Domino
Since Domino is not a relational database, Domino by itself does not enforce
Primary key or Foreign key in the documents. To cascade the related
documents in Domino applications:
You have to identify a Primary key for each document.
Use this Primary key as Foreign key in related documents.
The Primary key should be information that uniquely identifies the document
in the database.
There are several ways to generate unique keys. See the section “Using Keys
to Relate Data in Different Databases” in Chapter 2 for a discussion of this.
The user can designate one of the fields in the form as the Primary key for
the document. For example, in a banking application, the customer’s social
security number can be used as the Primary key (as permitted by law). In
such cases, the application should be coded in such a way that the user does
not create multiple documents with the same key value.
After identifying a suitable method to generate the unique keys, you should
establish a mechanism to store the primary key of the document in the
related documents as foreign key.
This can be achieved by allowing the users to create the child documents
only from the parent document and inheriting the primary key value from
the parent document.
In the banking application example, the users should be allowed to create
the account documents only from the customer document, so that the
account document inherits the primary key of the customer document. In the
same way the transaction documents should be created only from the
account document.
If the application is a multiple database application, the name of the server
and the database on which the child document is created should be stored in
the parent document. For example, if the account documents are stored in a
different database, the database name where the account documents are
created and its server name should be stored in the customer document.
If all the documents are stored in the same database, set a flag in the parent
document to indicate that it has one or more child documents.
This way, when the user deletes a parent document, the child documents can
also be deleted recursively.
To maintain data consistency, the users should not be allowed to paste
documents in the database. This is accomplished by programming the
QueryPaste event of views.
Example
The following example shows a simple method of deleting related
documents using the FTSearch method. The example considered here is the
same banking application which was introduced in Appendix B-5,
“Seamlessly switching between databases.”
When a user selects a document in the view and clicks the action button
Cascaded Delete 1, the selected document as well as all the related
documents in the Accounts and Transactions database will be marked as
deleted.
The Notes Remote Procedure Calls (NRPCs) is the method that the client and
server use to communicate with one another. This is very much a low level,
under the cover, network traffic. The user of an application will only see the
lightning bolt in the bottom corner of the Notes screen.
As developers, we do not have control over our network design and size.
However, we can build our applications to minimize the traffic that is passed
down the network, or try to spread the amount of network traffic that we
send at once. By monitoring the RPCs that we send from a client we can
make faster design decisions.
This appendix provides information on the RPCs and how to use the
information that is passed from them.
Note The use of the NOTES.INI variable Client_Clock is not supported or
documented by Lotus, and may be removed at a later date without warning
or acknowledgement.
Accompanying this setting we also need to tell the Notes Client where
to direct this output. It can be either to a window, with the following
NOTES.INI setting:
Debug_Console=1
In the NOTES.INI file, where “c:\temp\debug.txt” is the name for the text
file. You may wish to enable both.
297
Using the RPC Information
The information that is generated by enabling the Client_Clock is as follows:
(Counter-Time [Thread]) RPC: Time Taken [Bytes Sent + Bytes
Received = Total]
From this output we can now compare the two simple operations to see
what effect the implementation of the ‘PostOpen’ event to load a Profile
Document has. In this example we can see that two extra RPCs were run,
how long they took, and the amount of network traffic that was added.
Overview
Basically, the idea is to create a large number of documents with agents, with
the help of the third-party tool TeamStudio. This way you should be able to
get some idea about database size (before and after building the view
indexes), view index sizes, time needed to replicate, time needed to open a
view, time needed to open a document, time needed to save a document
(times both measured when LAN connected and when dialing in with a 28K
modem) and so forth.
Now, you may think that creating the code for the agent is a challenge. Trust
me, it’s not. The real challenge lies in thinking of a way to generate a good
set of values. You have to think of the typical data contained in a field, which
in some cases can be hard to predict. You’ll probably have to modify the
value-generating routine a few times, because you’ll probably notice side
effects of the routine. Remember to consider the impact of your
value-generating routine on performance inhibitors, like view categorization.
Assumptions
You’re nearly done with development of a large scale database.
Limitations
Any simulation is only as good as the subject knowledge you put into it.
This method is easiest when a large portion of the fields are numeric.
This simulation doesn’t include the effect of a large number of users, like
multiple users accessing the same database at the same time, or the effect of
unread marks.
Details
The goal is to create a large number of documents with an agent. In
practice, most people don’t like creating such an agent, because it can
involve a lot of tedious coding — especially when there are many fields.
Now here’s the trick: TeamStudio can help you.
303
With TeamStudio you run a design analysis of your database. This will
include a comma-delimited listing per form of all the fields used. Check out
the TeamStudio Analyzer or TeamStudio Designer Help if you don’t know
how to do this. More information about these products is available on the
Web at:
www.teamstudio.com
What follows is a list I got using this technique (yes, quite a number of
fields). Note that in this particular case I was lucky, because most of my
fields are supposed to contain numeric values.
SaveOptions, CMNotes_Pull_TMP, CMNotes_Pull_Flag, IW_Pull_TMP,
IW_Pull_Flag, Delete_Flag, Form, Country_Code, Company_Code,
CTS_Comment, HdrTitle, HdrSecClass, Contract_Number,
Legal_Number, Contract_Desc, Customer_Number, Customer_Name,
Local_Curr_Ind, ITD_Revenue, Revenue_Total, ITD_Invoiced,
Curr_Mult_Factor, ITD_Price_Rev, ITD_Plan_Rev,
ITD_Actuals_Rev, ITD_Forecast_Rev, ITD_Estimate_Rev,
ITD_Price_Var_Rev, ITD_Plan_Var_Rev, ITD_Price_Cost,
ITD_Plan_Cost, ITD_Actuals_Cost, ITD_Forecast_Cost,
ITD_Estimate_Cost, ITD_Price_Var_Cost, ITD_Plan_Var_Cost,
ITD_Price_GP, ITD_Plan_GP, ITD_Actuals_GP, ITD_Forecast_GP,
ITD_Estimate_GP, ITD_Price_Var_GP, ITD_Plan_Var_GP,
ITD_Price_GPP, ITD_Plan_GPP, ITD_Actuals_GPP,
ITD_Forecast_GPP, ITD_Estimate_GPP, ITD_Price_Var_GPP,
ITD_Plan_Var_GPP, YTD_Pricing_Rev, YTD_Plan_Rev,
YTD_Actuals_Rev, YTD_Forecast_Rev, YTD_Estimate_Rev,
YTD_Price_Var_Rev, YTD_Plan_Var_Rev, YTD_Pricing_Cost,
YTD_Plan_Cost, YTD_Actuals_Cost, YTD_Forecast_Cost,
YTD_Estimate_Cost, YTD_Price_Var_Cost, YTD_Plan_Var_Cost,
YTD_Pricing_GP, YTD_Plan_GP, YTD_Actuals_GP, YTD_Forecast_GP,
YTD_Estimate_GP, YTD_Price_Var_GP, YTD_Plan_Var_GP,
YTD_Pricing_GPP, YTD_Plan_GPP, YTD_Actuals_GPP,
YTD_Forecast_GPP, YTD_Estimate_GPP, YTD_Price_Var_GPP,
YTD_Plan_Var_GPP, YTD_Plan_Rev_1, YTD_Actuals_Rev_1,
YTD_PlanP_Rev, ITD_Plan_Rev_1, ITD_Actuals_Rev_1,
ITD_PlanP_Rev, YTD_Plan_Cost_1, YTD_Actuals_Cost_1,
YTD_PlanP_Cost, ITD_Plan_Cost_1, ITD_Actuals_Cost_1,
ITD_PlanP_Cost, YTD_Plan_GP_1, YTD_Actuals_GP_1, YTD_PlanP_GP,
ITD_Plan_GP_1, ITD_Actuals_GP_1, ITD_PlanP_GP, YTD_Plan_GPP_1,
YTD_Actuals_GPP_1, YTD_PlanP_GPP, ITD_Plan_GPP_1,
ITD_Actuals_GPP_1, ITD_PlanP_GPP, ITD_Price_Rev_1,
ITD_Actuals_Rev_2, ITD_Price_Rev_Dlt, ITD_Price_Cost_1,
ITD_Actuals_Cost_2, ITD_Price_Cost_Dlt, ITD_Price_GP_1,
ITD_Actuals_GP_2, ITD_Price_GP_Dlt, ITD_Price_GPP_1,
ITD_Actuals_GPP_2, ITD_Price_GPP_Dlt, File_Complete,
Status_Exposure, Contract_Sign_Date, Contract_Sign_Date_Alt,
Start_Date, Start_Date_Alt, Contract_Create_Dt,
Contract_Create_Dt_Alt, End_Date, End_Date_Alt, Work_Number,
The next step is to try to simulate the effect of users updating the documents.
In my case I used a simple sub called MyReplaceValue(Doc as
NotesDocument, ItemName as String) to add a random number to the
numeric values and then used the word processor and spreadsheet again to
create code like:
Randomize
Do While Not Doc Is Nothing
Call MyReplaceValue(Doc, “ITD_RevAD_IL”)
ErrorLabel:
Print “Error; resuming”
Exit Sub
End Sub
Important You will probably need a couple of runs of the agent with
different user IDs to accumulate enough data in the $UpdatedBy and
$Revisions items..
This list of limits in Domino R5.0 and R4.6 has been compiled from Notes
Help and the Lotus Knowledge Base.
Feature Limit in Domino R5.0 Limit in Domino R4.6
Maximum size of Up to 64GB (32GB for OS/2) or Up to 4GB or
database defined by OS file size limit defined by OS file
size limit
Maximum size of view 128GB or database size limit 512MB or database
size limit
Maximum number of No limit; however, as the number same
view in a database of views increases, the length of
time to display other views also
increases
Maximum number of 289 ten-character columns; same
columns in a view dependent upon number of
characters per column
Maximum number of ~ 3000 (limited to ~ 64K total ~ 3000 (limited to ~
fields in a database length for all field names). You 64K total length for
can enable the database property all field names).
“Allow more fields in database”
to get up to 64K uniquely-named
fields in the database, but certain
features that use the list of all field
names will not work properly such
as full-text querying, the
Designer's list of field names, and
agents that modify by form.
Maximum number of Limited only by database size same
forms in a database
Maximum size of a text 15K same
field
Maximum size of a Limited only by available disk same
rich-text field space up to 1GB
continued
307
Feature Limit in Domino R5.0 Limit in Domino R4.6
Maximum size of a single 64K same
paragraph in a rich-text
field
Maximum number of ACL size is limited to 32767 bytes, same
entries in an ACL which equals ~950 average length
hierarchical names
Maximum number of 75 same
Roles in an ACL
Limits for titles and Database title: 96 bytes Database title: 96
names Field name: 32 bytes bytes
View name: 64 bytes Field name: 32 bytes
Form name: 64 bytes View name: 64 bytes
Agent name: 127 bytes including Form name: 32 bytes
all cascading names. Each name Agent name: 127
cannot exceed 64 bytes bytes including all
cascading names.
Each name cannot
exceed 64 bytes
Maximum number of 64 same
columns in one table
Maximum number of 255 255
rows in one table
Maximum number of 200 200
cascading views in a
database
Maximum number of ~21,000 entries Not applicable
outline entries
Maximum number of There is no limit Not applicable
outlines in a database
Maximum number of There is no limit Not applicable
framesets in a database
Maximum length of In Notes: no limit
search query string From a Web
browser: 254 bytes
Maximum length of 62 characters (You can add longer same
environment variable in names, but this can cause
NOTES.INI applications to fail)
Maximum length of Key 32,750 characters 200 characters
string parameter for
GetDocumentByKey and
GetAllDocumentsByKey
of the NotesView class
View Characteristics
There are many criteria we can use to decide which kinds of views to test.
In this analysis we investigate the major view types and most common
column properties and, although the study does not cover every situation,
the majority are included. Conclusions, therefore, are not hard and fast
rules, but can be thought of as good generalizations.
Most of the performance literature available, including this redbook, mentions
a few common things about maximizing view performance. Those comments
led to testing the following view characteristics:
• Number of columns
Compare views that differ only by the number of columns being
displayed.
• Categorization
Compare effects of categorization versus not categorizing.
Compare categorization using separate columns for categories versus
using a single column that contains the combined categories (by using
the backslash (\) between categories in the column formula).
• Sorting
Compare sorting a column vs. not sorting it.
Compare dynamic sorting of columns.
• Column calculations
Compare using form fields to store calculations versus doing the
calculation in the column formula.
Compare how the size of data displayed in a column affects things.
309
• Number of fields in a document
Compare effects of adding fields to the documents but not changing the
view in any way.
Test Data
Having decided what view characteristics we are analyzing, we now need
some test data. This is the hard part. How do you get data that simulates a
real application?
We could get data from a real application, but then we are simulating a
single variation from an infinite number of possible application data sets.
Also, real data may be sensitive. Using real data may require the test
database to have a set of matching forms for the data, and so on.
What we chose to do was to generate our own data. There are several
reasons for this choice:
y It’s relatively easy (we don’t have to find an application).
y As we change database size, the distribution of the data can be controlled.
y We don’t have to worry about “real” data (from a security standpoint).
y We can tailor the data attributes to suit the tests we want to do.
We need a relatively complex agent to generate data which has the
characteristics we want. We don’t just want all random data. We need some
random data but we also need data that is chosen from a limited set (so we
can categorize). We want some numbers, dates, text and rich text.
Test Cases
We built a database that has not only the view test cases of this appendix,
but many of the other test cases used to validate performance information
in this redbook. The database is available on the redbook Web site.
We found that when testing with database sizes of 500 or 1000 documents,
the performance numbers are not very meaningful. Domino does a lot of
internal partitioning of the sections inside the NSF file. The sizes of these
partitions are such that when the number of documents are small, doubling
things sometimes has no noticeable effect on space or time. You need to have
a reasonable volume of documents for the numbers to have some validity.
View Testing
A number of views were set up to analyze the test cases. In general, the first
view in each series is a “base” view from which we can compare the effects
of the test.
The actual tests were run as follows:
1. A new copy of the database was created on the server.
2. An agent was run to create 2000 documents. In fact, since some of the 2000
documents had responses, 2714 “notes” were created in the database.
3. Another agent was run to create the calculated column fields using the
same formula that the “column calculation” views use.
4. All view indexes were built (Ctrl-Shift F9).
5. The “Show Database <db name> V” command was issued on the server
remote console to get the view index sizes.
6. An agent was run to double the documents to 4000 (which meant the
database had 5428 “notes”).
7. Steps 4 and 5 were run again.
Number of Columns
There were four views in this test.
NC: 7 Columns
This was the base view. It had seven columns of various types and had no
sorting nor categorization.
NC: 14 Columns
Similar to the base view except that every column was duplicated. The
column formulas in the duplicate columns were identical to the original.
NC: 28 Columns
Similar to the base view except that every column was quadrupled. The
column formulas in the duplicate columns were identical to the original.
3500
3000
Size ( KB ) 2500
NC: 7 Columns
2000
NC: 14 Columns
1500 NC: 14 Different cols
NC: 28 Columns
1000
500
0
0 5000 10000 15000 20000
Number of Documents
Note The middle line on the graph is actually two lines on top of one
another: NC: 14 Columns and NC: 14 Different cols.
As was expected, the number of columns directly relates to the space
requirements. However, in the NC: 14 Columns view there were seven
duplicate columns (they contained the same formula and properties as
seven other columns). In the NC: 14 Different cols view, each of the 14
columns had a slightly different formula. As can be seen by their identical
space requirements, view indexing is not smart enough to optimize when
two (or more) columns are the same, but that is unlikely to happen in the
first place.
Categorization
There were four views in this test.
CAT: No Sorting
This was the base view for categorization. The view had six columns. The
first three columns were text data (which will be categorized in other views
in this section). The remaining three columns contained unsorted text and
numeric data. In this base view, no column was sorted or categorized.
CAT: No Categories
Similar to the base view except that the first three columns were flagged as
sorted, ascending. In this view we still have no categories.
Test Results
The following graph depicts view index size versus categorization:
2000
Size ( KB )
500
0
0 5000 10000 15000 20000
Number of Documents
This one surprised us. It seems that the sorting required for categorization
takes up some space, but the categorization itself takes up almost no space
at all. Likewise, if you examine the timing section later in this appendix,
you see that categorization does not consume huge amounts of time either.
Of all the things you can do with a view that hinders performance,
categorization seems to have the least effect.
Sorting
These were seven views in this test.
SRT: No Sorting
This was the base view. It had seven text and number columns, none of
them sorted.
SRT: 1 Column
Similar to the base view except that the first column was sorted.
Others
During the course of testing, there were also some sorting views created
with five dynamically sorted columns and others where the dynamic
sorting was done ascending vs. descending. A final set was also create
where the dynamic sorting was set to “Both” ascending a descending. Test
results from these views are included elsewhere in this appendix.
Test Results
The following graph depicts view index size versus sorting:
2000
Size ( KB )
500
0
0 5000 10000 15000 20000
Number of Documents
Column Calculations
There were five views in this test.
CC: No Calcs
Similar to the base view except that the view used three pre-calculated
fields that existed in the documents. The formulas for these pre-calculated
fields were identical to the formulas used in the base view. These
pre-calculated fields were displayed in the view instead of doing the
calculations.
Test Results
The following graph depicts view index size versus column calculations:
9000
8000
7000
6000 CC: Column calcs
Size ( KB )
Note The bottom line on the graph is actually three lines on top of one
another: CC: Column calcs, CC: Complex calcs 1 and CC: No calcs 1.
As we can see, space requirements have almost no relation to the
complexity of the calculations happening in the view columns. The major
factor affecting view index size seems to be the size of the data displayed in
the column.
Don’t be fooled, however. Take a look at the timing section later in this
appendix for some other interesting information about column calculations.
Number of Fields
There were no special views in this test. The results of prior tests were
compared against results after the number of fields in the database was
increased.
An agent was run on the 16,000 document database to duplicate the
document fields. System fields (like the Form field) and rich-text fields were
not duplicated.
250
Size ( MB ) 200
150
Before
After
100
50
0
Document area View index area Total DB size
After the agent was run on the 16,000 document database, the size of the
database increased from 192MB to219 MB, but the size of the indexes
remained constant. The increase in database size was due to each document
requiring more storage to hold the larger document. The views did not
require extra storage since the new fields were not part of any view.
In other words, view index size is related to the information displayed in
the columns, and not related to the number of fields in the documents.
NC: 7 Columns
NC: 14 Columns
NC: 14 Different cols
NC: 28 Columns
CAT: No sorting
CAT: No categories
CAT: Separate columns
CAT: Single column
SRT: No sorting
SRT: 1 Column
SRT: All 7 columns
SRT: All + 1 dynamic
SRT: All + 3 dynamic
SRT: All + 5 dynamic
SRT: None + 1 dynamic
SRT: None + 3 dynamic
SRT: None + 5 dynamic
CC: Column calcs
CC: Complex calcs 1
CC: Complex calcs 2
CC: No calcs 1
CC: No calcs 2
0 10 20 30 40 50 60 70 80 90 100
Seconds
Ad Hoc Results
A number of ad hoc tests were done during the other tests. Some points to
note:
• Sorting ascending versus sorting descending had no appreciable
difference in either time taken or view index size.
• Defining a column with dynamic sorting in both directions (ascending
and descending) doubles the time and space required for that dynamic
sort. In other words, if sorting the column one way adds 1MB of space
to the index, sorting both ways adds 2MB. Likewise, if sorting one way
adds 10 seconds to the rebuild time, sorting both ways adds 20 seconds.
• Results using Domino R5.0 seemed similar to Domino R4.x, but
exhaustive tests were not done.
Conclusions
View indexing is a complex subject and your application will have special
needs, and therefore, different results. But we think, given the above test
results, and other prior experience, it is safe to say the column sorting and
size of data displayed in a column are the two most significant factors in
determining view index size and rebuild time.
This appendix describes why reader namescan affect view performance and
then goes on to describe a technique of gaining access to documents with
reader names fields without getting hit with bad-performing views.
Much of the information is an extract from the Lessons Learned section on
the IBM Notes/Web Application Center of Competence Web site — an IBM
intranet Web site.
A Possible Scenario
The following is something that might be overheard at the coffee machine in
a Domino development shop:
Developer #1: “I’ve got a problem. My database has only 10,000 documents
in it but my views take over 10 seconds to open. The documents all have
reader names fields and maybe that’s the problem.”
Developer #2: “Well, my database has over 100,000 documents in it with
reader names fields and my views come up consistently in one second. I
doubt your problem has to do with reader names fields.”
Well, developer #2 is wrong, the problem developer #1 is having is because
of the reader names fields. But why, then, does developer #2 not have a
performance problem when that database is 10 times the size?
Reader Names
Reader names fields and their effect on performance have been discussed in
many places, but we had not found “the answer” until we started an
in-depth study into this feature of Domino.
First, let us say that the reader names feature of Notes is extremely useful. It
basically provides the only way to guarantee that a document can only be
seen by persons referred to in the reader names field (either directly listed,
part of a listed group or who have a role which is listed in the reader names
field).
323
Also, the actual access to a document with a reader names field is very fast.
The extra processing required to check if the user is referred to in the reader
names field is minimal. Why, then, do some applications that use reader
names fields suffer from slow response time?
The answer lies in the fact that the vast majority of Domino applications
access documents via a view. And the only area that causes noticeable
degradation of performance when using reader names fields is the area of
view index preparation for a user.
Fine, but that still doesn’t help us understand the problem discussed by the
two developers in the scenario above! To explain it, we have to go into a bit
more detail about how Domino handles views.
Summary
If you use reader names fields in your documents and have a database with
many documents (as a ballpark figure, this number is around 2,000) and the
number of documents “visible” to the user is 5 percent or less, then special
attention will need to be given to the design of views of those documents.
The designer needs to know a lot more about the proposed data in the
application to be able to judge if the response times for views will be a
problem. If it looks like there might be an issue, various techniques can be
employed to speed up access to views containing reader names documents.
The following techniques can be used to reduce the delays in views that deal
with reader names fields:
1. Use categorization to segment the volume of documents in the view so
each category has a small enough number to make response times
reasonable. Remember — you must flag the view as “collapsed when
opened” in this case.
2. Spread your documents across multiple databases. (This sounds easy but
it has more pitfalls than you might imagine.)
3. Access your documents without going through a view. This technique is
further explained later in this appendix.
Performance Testing
LotusScript and the Formula language have different strengths. This is great
for the Notes community, because it means that the breadth of tasks that can
be performed has been increased since the release of Notes R4.0. There are,
however, some overlapping areas, and it is in these areas that we focused
our testing. The question we try to answer is, “If I can easily use LotusScript
or the Formula language, which should I use?”
Background
We considered the different cases where one might use LotusScript or formulas.
333
Working With Many Documents (Agents)
Many times we need to process lots of documents at a time. Agents are often
used for this. The following types of updates were examined:
y Updating field values in all documents in the database
y Updating field values in some of the documents in the database
y Looking up data from other Notes databases and updating documents
based on this data
Though the differences for one lookup might be small, repeating the process
many times amounts to significant time differences. We focused our testing
in this area.
Points To Consider
Some points to consider when looking at our results:
y Is there a substantial difference in the time to complete a task, or is the
difference negligible?
y How easy is it to code this task in LotusScript versus the Formula language?
Test Methodology
This section details the hardware, software, and methodology used to
perform the tests described in this appendix.
Equipment
The following equipment was used:
• P75 IBM ThinkPad (755CX) with 24MB of RAM and approximately
100MB of available disk space.
• Windows 95, with never more than Lotus Notes and the Explorer loaded
into memory.
• Notes R4.
• The ThinkPad was always used as a stand-alone, but it was always
plugged into a wall socket. No modem connections.
• The location document was always specified as non-LAN.
Additional Comments
The methodology used was to perform three trials in a row, using the
average of the 2nd and 3rd trials. Between each trial, we reset the documents
by running an agent to clear one field. Between each trial, the database was
closed and reopened.
We did notice that the first trial was usually longer than the 2nd and 3rd
trials, often by 10 percent or more. Possible explanations are:
• View caching by the Notes client software.
• When a database is first opened, you will often see a message on the
status bar, “Releasing unused space” or “Performing consistency check.”
If these actions occur on the lookup database, we wouldn’t notice
anything but an increased time for the agent to complete its work. Since
we performed three consecutive trials, we felt that the 2nd and 3rd were
reliable enough and close enough to average.
In the time trials using the 48,000 document database, if the first and second
times recorded were within 3 percent of each other, we used those two
times, and did not record a third time. This was because each trial itself was
so time consuming.
Analysis
Every case is unique, but we do want to give some sort of summary from all
these tests.
LotusScript
Some things to think about with LotusScript:
• LotusScript often gives several methods for getting at the same piece of
data. In the case of our tests, we found that using the ColumnValues
property saved about 10 percent over simply getting a handle to the
document and then using extended class syntax (such as, x =
doc.fieldname).
Rules of Thumb
Some rules of thumb:
• The more bytes written to a field, the longer it takes to perform the update.
• Writing data to a field which you have looked up takes longer than
writing that same data if it is hard-coded.
• The more fields you need to update, the longer it takes.
• The more documents you need to update, the longer it takes.
• Overwriting with the same data is faster than overwriting with different data.
• Running against documents which you don’t need to update takes time.
Other Factors to Consider
Some other things to note:
• For formulas which perform lookups, @formulas are much easier to code,
and to maintain, than are LotusScript scripts. On the other hand, they
usually require special (often hidden) views to lookup against. The
maintenance of these views takes some time and effort and can also create
an issue for overall database size. LotusScript doesn’t require any such
overhead. Two LotusScript search methods, Search and FullTextSearch,
can be used to find a collection of documents that match criteria without
using an indexed (sorted column) view to find documents.
• LotusScript gives the ability to get data from rich-text fields. @Formulas
do not.
• LotusScript can easily update documents in other Notes databases.
@formulas can accomplish this (with a great deal more work) only if run
in the foreground.
Composing a Document
Form - Initialize Event
Form - Window Title Formula
Form - QueryOpen Event
Subject Field - Default Value Formula
Subject Field - Initialize Event
From Field - Value Formula
From Field - Initialize Event
Counter Field - Value Formula
Counter Field - Initialize Event
347
DisplayNum Field - Value Formula
DisplayNum Field - Initialize Event
Body Field - Default Value Formula
Body Field - Initialize Event
Subject Field - Entering Event
Form - PostOpen Event
Toggling from Edit Mode to Read Mode with Document Open (with
Changes Made and Saving)
Form - QueryModeChange Event
Do You Want to Save Your Changes? - Answer YES
Form - QuerySave Event }
Subject Field - Input Translation Formula } same sequence as
Counter Field - Value Formula } File Save above
DisplayNum Field - Value Formula }
Subject Field - Input Validation Formula }
Form - PostModeChange Event
Form - QueryClose Event }
Form - Terminate Event }
Subject Field - Terminate Event } same sequence as
Form Field - Terminate Event } File Close Window
Counter Field - Terminate Event } above
DisplayNum Field - Terminate Event }
Body Field - Terminate Event }
Form - Initialize Event
Form - Window Title Formula }
Form - QueryOpen Event }
Subject Field - Initialize Event }
From Field - Initialize Event } same sequence as
Counter Field - Initialize Event } Opening an
DisplayNum Field - Value Formula } existing document
DisplayNum Field - Initialize Event } above.
Body Field - Initialize Event }
Form - PostOpen Event }
Appendix C-5: Execution Order of Notes Form Events and Formulas 349
Form - Terminate Event }
Subject Field - Terminate Event } same sequence as
Form Field - Terminate Event } File Close Window
Counter Field - Terminate Event } above
DisplayNum Field - Terminate Event }
Body Field - Terminate Event }
Form - Initialize Event }
Form - Window Title Formula }
Form - QueryOpen Event }
Subject Field - Initialize Event }
From Field - Initialize Event } same sequence as
Counter Field - Initialize Event } Opening an
DisplayNum Field - Value Formula } existing document
DisplayNum Field - Initialize Event } above.
Body Field - Initialize Event }
Form - PostOpen Event }
Moving the Cursor from One Editable Field to Another
First Field - Exiting Event
Second Field - Entering Event
Pressing F9 to Refresh Fields While in Edit Mode
Subject Field - Input Translation Formula
Counter Field - Value Formula
DisplayNum Field - Value Formula
Subject Field - Input Validation Formula
Form - PostRecalc Event
Note Closing the document after changing it results in the prompt: “Do you
wish to save this document?” Selecting Yes performs the same as a Save fol-
lowed by a Window Close. Selecting No performs the same as a Window Close.
Note In Notes 4.0, it appears that the Initialize and Terminate events of Action
Hotspots and Buttons either in the form or embedded in an RTF field do not get
activated.
Note In order to enter an Initialize or Terminate script into a Computed or
Computed for display field, it may be necessary to first set the field to Editable,
add the scripts and then change the field definition back to Computed or
Computed for Display.
This appendix describes what happens in Domino under the cover when a
URL is submitted from a Web browser. It is an excerpt from the article “The
Architecture of the Domino Web Server - Part 2” by Richard Schwartz. You
can view the entire article in Iris Today, the technical Webzine located at
www.notes.net. This Web site is produced by Iris Associates, the
developers of Domino and Notes. Visit Notes.net to obtain the latest version
of the article as well as other related articles.
Domino.Commands
Users interact with Domino applications through commands issued as
URLs. Each command specifies a top-level object and activates the methods
needed to carry out a request and generate HTML output. The Domino
Web Server implements many commands. The commands related to the
display and modification of documents are worth a closer look. These are
the commands that enable interactive applications, so the similarities and
differences in their implementation are of particular interest.
?OpenDocumentand ?EditDocument
Three commands display the contents of a document:
?OpenDocumentopens an existing document in read mode, ?EditDocument
opens an existing document in edit mode, and ?OpenForm opens a new
document in edit mode. The implementations of ?OpenDocument and
?EditDocument are very similar. Both execute the following sequence of
steps:
1. Open the existing document.
2. Read all items from document into memory.
3. Load the Notes form referenced by this document.
4. Scan the Notes form and execute default value formulas for any items
that are not yet in memory, and execute all computed field formulas
and add/update items to the in-memory document accordingly.
351
5. Run the appropriate agent if an item named $$QueryOpenAgent exists.
6. Render the Notes form into an HTML page or HTML form using the
item values from the in-memory document.
7. Free the in-memory document and all items it contains.
The only significant difference between ?OpenDocument and
?EditDocument commands is in step 6, where ?OpenDocument instructs the
GenerateHTML methods to respect read-mode hide attributes contained
within the Notes form, and to create HTML for a read-only page.
?EditDocument instructs these methods to respect edit-mode hide attributes
on the Notes form and to create an HTML form.
?OpenForm
The ?OpenFormcommand executes a similar sequence of steps:
1. Create a new document in memory.
2. Load the Notes form referenced in the URL.
3. Scan the Notes form and execute all default value formulas and
computed field formulas, adding items to the in-memory document.
4. Run the appropriate agent if an item named $$QueryOpenAgent exists.
5. Render the Notes form into an HTML form, respecting edit-mode hide
attributes and using item values from the in-memory document.
6. Free the in-memory document and all items it contains.
The last step of the procedure for all three commands frees the in-memory
document and its associated items. The ?EditDocument and ?OpenForm
commands do not cache the documents for later use because that would
violate the stateless nature of the a Web server. If and when the browser
sends edited information back, the Domino Web Server will re-establish all
the data structures necessary to handle the updates.
?CreateDocumentand ?SaveDocument
?CreateDocumentand ?SaveDocument are the two commands that receive
HTTP POST data generated by browsers when a user clicks the Submit
button on an HTML form and saves the data in Notes documents. Submit
buttons on HTML forms generated by the ?OpenForm command send the
?CreateDocument command, and Submit buttons on HTML forms
generated by the ?EditDocument command send the ?SaveDocument
This appendix was written by Andrew Wharton, and was first published as
an article in Iris Today, the technical Webzine located at www.notes.net.
This Web site is produced by Iris Associates, the developers of Domino and
Notes. Visit Notes.net to obtain the latest version of the article as well as
other related articles.
Note Since this article was written, more support for client-side caching
has been added to Domino. On every page being served by Domino there is
now a Last-Modified header. This means that a Web browser that already
has a copy of the page in its local cache does not have to reload the page
unless it has been changed since the last time it was downloaded.
Note Until and including the current versions of Domino (R4.6.6 and
R5.0.2) use of the feature named “Use JavaScript when generating pages”
will always turn off the command cache. Iris is looking into how this
restriction can be removed in the future.
355
Caching URL Commands
The following types of Domino URL commands (and the HTML that they
generate) are currently the only candidates for the Command Cache:
?OpenDatabase
?OpenView
?OpenDocument
?OpenForm
?ReadForm
Other commands (for example, ?EditDocument) are not considered for
caching. Domino only serves pages from the Command Cache if the URL
request exactly matches the URL of the cached pages, even though Domino
URL syntax allows multiple ways to specify the same URL command (by
using replica IDs instead of database names, or view names instead of view
UNIDs).
Caching @Functions
Determining the algorithm to make an accurate and timely decision as to
which Web pages are cacheable is one stumbling block to making a very
useful caching system. In 4.6, we considered the very presence of
@functions (among others) too volatile, and thus, did not consider any
pages with @functions as candidates for caching. Unfortunately, this meant
that many Web pages could not take advantage of caching and the
performance gains that it provides.
In R4.61, much has changed. As part of the ongoing effort to provide
performance improvements in the Domino server, we now provide the
ability to cache Web pages that contain @functions. This is a very simple
statement with very powerful implications for the Web site administrator,
the Web application designer and the Web application user.
Domino 4.61 now has the ability to analyze all macro language (@function)
formulas for their dependencies through the Formula Analyzer. Rather than
exclude all pages that contain any @function formulas from the Command
Cache, the Formula Analyzer intelligently examines the formula on the
page and decides its level of volatility. By doing this first, Domino can
decide immediately whether the command is too volatile to be cached (for
example, the Web page contains @Now) and, perhaps more importantly,
under what conditions a cached command becomes invalid.
Cache Flags
When the Formula Analyzer examines a command invoking @formulas,
flags are assigned to that cache candidate based on the evaluation of the
@formula(s), among other things. The following flags are used by the
Domino HTTP server to determine the cache strategy, explained in the next
section. (A cache candidate can and often does have multiple flags.)
Flag Description
OffDb The page uses data outside the current database. This
includes the use of CGI variables.
TimeVariant The page uses time-variant data (such as @Now).
HadEffect The page has an important side effect (such as @DialogBox).
UsedEnv The page uses the environment (NOTES.INI). This does not
include CGI variables.
UserVariant The page is dependent on the user’s identity. This includes
using any data or design note that includes Read ACLs,
Readers fields, Authors fields or controlled access sections.
DesignUserVariant The page is from a database that has protected design
elements.
DbData The page uses data in the database other than the referenced
document. This includes all views, embedded views in forms,
and so on.
UsedDocId The page uses the document’s ID.
UsedNewDoc The page uses a newly-created in-memory note.
Unknown The page does something that couldn’t be analyzed (such as
executed LotusScript).
Error The page generated an error of some sort.
Any commands with the following flags are not cached (the DontCache
strategy):
OffDb
TimeVariant
HadEffect
UsedEnv
Error
Unknown
UserVariant (if authenticated)
DesignUserVariant (if authenticated)
Cache Statistics
You can check the efficacy of your Command Cache by monitoring the
following server statistics:
Domino.Cache.Command.Count — This is the actual number of
commands that are contained in the Command Cache.
Domino.Cache.Command.MaxSize — This is the maximum number of
commands that can be cached. This is the number configured from the
Server document in the Public Address Book using the “Maximum
Cached Commands” field.
Domino.Cache.Command.HitRate — This is the percentage ratio of the
number of times a valid cache entry is found in the cache to the number
of times the cache was investigated for a cache entry.
Domino.Cache.Command.DisplaceRate — This is the percentage ratio
of the number of times that a new cached command displaces an aged
command to the number of times the cache was investigated for a cache
entry.
Additional Web material is referenced in this book and can be found on the
IBM Redbooks Web site. The material is described in the following table.
File name Description
5602a2.zip Contains two databases that illustrate the techniques described in
Appendix A-2, “High Performance Reference Databases”:
- LWDir.nsf contains the compressed people records and shows
different ways to search and see details for them.
- mail46lw.ns4 is a mail database where the memo form has an
extra action button named GetPerson that looks up and gets
people information from LWDir.nsf
5602a2x.zip Contains template (lwnab.ntf) for databases where an agent creates a
compressed version of the people information in Domino Directory.
The template also contains scheduled agents to keep the database in
synch with Domino Directory. Note that the data format used in this
template is slightly different from the one used in the databases in
5602a2.zip, but the concepts it illustrates are the same.
5602b4c2.zip Contains database with test data used for writing appendices B-4,
“Sorting” and C-2, “View Indexing Comparisons.”
5602b5b7.zip Contains three databases (redcust.nsf, redtran.nsf and redacct.nsf)
that illustrate the techniques described in Appendices B-5,
“Switching Seamlessly Between Databases” and B-7, “Cascaded
Deletions Example.”
rc2033.pdf Softcopy version of Planning Domino Email Servers using Notes
Transactions by Bucky Pope, 1998, IEEE Third International
Workshop on Systems Management.
rc2034.pdf Softcopy version of A Planning Model for Lotus Notes Applications by
Bucky Pope, IBM Watson Research.
reorgprocess.pdf Softcopy version of Analysis and Process for Balancing Domino Mail
Servers at the IBM Global Services North Data Centers by John
Capurso, Jon Champlin, Bill Pointer, Bucky Pope, Lorrie Renz.
OZemailtest.pdf Softcopy version of Planning Realistic Performance Tests for Domino
Email Servers using Notes Transactions by Bucky Pope, Sydney
October 1998, 11th Software Testing SympOZium.
rc94265.pdf Softcopy version of Characterizing Lotus Notes Email Clients by
Bucky Pope, IBM Research Report.
rc2162.pdf Softcopy version of The Use of Life Expectancy to Manage Lotus Notes
Email Storage by Bucky Pope and Lily Mummert, Paper presented
for Computer Measurement Group at CMG99.
369
How to Get the Web Material
To get the Web material, point your Web browser to:
ftp://www.redbooks.ibm.com/redbooks/sg245602
Select Additional Materials and open the file that corresponds with the
redbook form number.
The publications listed in this section are considered particularly suitable for
a more detailed discussion of the topics covered in this redbook.
371
• Developing e-business Application Using Lotus Enterprise Solution Builder
R3.0, IBM form number SG24-5405, Lotus part number CT69TNA
• Connecting Domino to the Enterprise Using Java, IBM form number
SG24-5425, Lotus part number CT6EMNA
• Lotus Domino for AS/400: Integration with Enterprise Applications, IBM
form number SG24-5345, Lotus part number CT7BMNA
• LotusScript for Visual Basic Programmers, IBM form number SG24-4856,
Lotus part number 12498
• Lotus Solutions for the Enterprise, Volume 1. Lotus Notes: An Enterprise
Application Platform, IBM form number SG24-4837, Lotus part number
12968 (available in soft copy only)
• Lotus Solutions for the Enterprise, Volume 2. Using DB2 in a Domino
Environment, IBM form number SG24-4918, Lotus part number CT69BNA
• Lotus Solutions for the Enterprise, Volume 3. Using the IBM CICS Gateway
for Lotus Notes, IBM form number SG24-4512 (available in soft copy only)
• Lotus Solutions for the Enterprise, Volume 4. Lotus Notes and the MQSeries
Enterprise Integrator, IBM form number SG24-2217, Lotus part number
12992
• Lotus Solutions for the Enterprise, Volume 5. NotesPump, the Enterprise Data
Mover, IBM form number SG24-5255, Lotus part number CT69DNA
• Enterprise Integration with Domino for S/390, IBM form number SG24-5150
Other Resources
These publications are also relevant as further information sources:
• Maximizing Application and Server Performance in Domino, Lotus White
Paper January 1999, Lotus part number CC737NA
• Domino R5 Performance and Scalability, Lotus White Paper June 1999,
Lotus part number CC798NA
• Applying Use Cases: A Practical Guide, by G. Schneider and J. P. Winters,
Addison Wesley, MA, USA, 1998, ISBN 0-201-30981-5
• Algorithms by Robert Sedgwick, Addison-Wesley 2nd Edition, April
1988, ISBN 0201066726
• Lotus Notes & Domino 5 Scalable Network Design by John P. Lamp and
Peter W. Lew, McGraw-Hill , 2nd Edition 1999, ISBN 007913792X, IBM
Form Number SR23-9218-00
This section explains how both customers and IBM employees can find out about ITSO
redbooks, redpieces, and CD-ROMs. A form for ordering books and CD-ROMs by fax or e-mail
is also provided.
• Redbooks Web Site http://www.redbooks.ibm.com
Search for, view, download or order hardcopy/CD-ROM redbooks from the Redbooks Web site. Also
read redpieces and download additional materials (code samples or diskette/CD-ROM images) from
this redbooks site.
Redpieces are redbooks in progress; not all redbooks become redpieces and sometimes just a few
chapters will be published this way. The intent is to get the information out much quicker than the
formal publishing process allows.
• E-mail Orders
Send orders by e-mail including information from the redbooks fax order form to:
e-mail address
In United States: [email protected]
Outside North America: Contact information is in the “How to Order” section at this site:
http://www.elink.ibmlink.ibm.com/pbl/pbl/
• Telephone Orders
United States (toll free) 1-800-879-2755
Canada (toll free) 1-800-IBM-4YOU
Outside North America Country coordinator phone number is in the “How to Order”
section at this site:
http://www.elink.ibmlink.ibm.com/pbl/pbl/
• Fax Orders
United States (toll free) 1-800-445-9269
Canada (toll free) 1-800-267-4455
Outside North America Fax phone number is in the “How to Order” section at this site:
http://www.elink.ibmlink.ibm.com/pbl/pbl/
This information was current at the time of publication, but is continually subject to change. The
latest information may be found at the Redbooks Web site.
377
378
IBM Redbook Fax Order Form
Please send me the following:
Company
Address
We accept American Express, Diners, Eurocard, MasterCard, and Visa. Payment by credit card not available
in all countries. Signature mandatory for credit card payment.
379
380
Index
381
Web command cache improving response time, 9 subforms, 89
statistics, 361 internals (Domino R5.0), 151 tables, 91
Capacity limits for titles and names, 308 viewing all elements using
bottlenecks, 40 local replica, 19 NotesPeek, 184
extending, 9 overcoming limits, 9 views, 88, 109
Case study sharing of data and/or Domino Enterprise Connection
compact reference databases, 227 functionality, 10 (DECS), 153
designing for large data volume single database application, 8 Domino Enterprise Connection
and large user size, archiving, 13 Services (DECS), 24
population, 205 splitting up applications, 11 Domino extension manager, 147
Centralization, 8 supporting mobile users, 10 Domino Global Workbench, 96
Client. See Notes client; Web browser supporting more users, 10 Domino Log, 174, 191
Client_Clock, 191, 196 Database open, 73, 186 Domino Object Model, 69, 70, 198.
Clustering, 11, 154 showing db open, 187 See Also Domino design
ICM, 11 Database properties, 154 elements; Domino Objects
Code profiling, 197 accessed (In this file), 158 Domino Objects, 73
coding example, 198 allow more fields in database, 160 append item option, 79
Code Reuse display images after loading, 156 AutoReload option, 74
via %INCLUDE, 83 document table bitmap back-end classes, 73
via agents, 80 optimization, 157 disabling autoreload, 74
via LotusScript, 81 headline monitoring, 159 extended syntax, 76
via subforms, 80 prevent overwriting deleted GetAllDocumentsByKey, 77
Command Cache, 355 data, 158 GetDocumentByKey, 77
COMPACT task, 126 prevent the use of stored GetDocumentByUNID, 76
Computed fields, 100 forms, 155 lazy initialization, 71
Computed for display fields, 57 size of $Revisions fields, 160 NotesDocument, 74
Computed when composed size of $UpdatedBy fields, 159 object reuse, 72
fields, 60 specialized response opening a database, 73
Concurrent updates, 12 hierarchy, 158 reuse, 73
check in/check out, 12 unread marks, 156 searching, 75
controlling with Lotus Databases UnprocessedDocuments, 79
Sametime, 12 special, 16 using AppendToTextList, 77
Console command DECS. See Domino Enterprise using columnvalues, 74
show dbs, 164, 175, 187 Connection Services Domino OffLine Services (DOLS), 19
Constructing Your Test Deferred processing, 33 Domino Server Performance, 172
Environment Design elements. See Domino design monitoring tools, 173, 174,
cleaning the environment, 180 elements 175, 176
Cookies, 108, 180 Design Synopsis, 183 DominoAnalyzeFormulas, 357
CORBA, 146 third party tools, 184 Double Byte Character Set
DESKTOP.DSK, 115 support, 206
Dial Up Networking, 168, 180 Dynamic lookups, 37
D Do Loops, 60
Data. See Subsets of data DocumentUniqueID, 36
subsets in applications, 15 Domino design elements, 87 E
Data age check, 13 agents, 143 Encryption, 22, 150
Database buttons, 96 Enforce Consistent ACL, 22
access control requirements, 10 CACHE.DSK, 138 roles, 20
activity, 173 forms, 88 Enterprise integration, 23
application examples, 14 framesets, 131, 132 add-in task, 25
application with several outlines, 135 coexistence with DB2/MVS, 207
databases, 8 pages, 130 Enterprise Solution Builder, 25
compact size, 228 profile documents, 106 Lotus Connector classes, 24
compaction, 151 resources, 136 Lotus Enterprise Integrator, 24
extending capacity, 9 shared actions, 138 mirroring data, 23
Index 383
onBlur event, 104 using the Evaluate statement, 56 saving and closing a
using, 94 Lotus Connector classes, 24 document, 191
Lotus Enterprise Integrator (LEI), 24 testing an application, 185
K LotusScript, 52, 53, 60, 94 Notes Global Designer, 96
Keys %INCLUDE, 83 Notes Log, 173, 188
@Unique, 36 automatic conversion, 67 Notes Remote Procedure Calls
DocumentUniqueID, 36 comparing data, 67 (NRPCs), 28, 48, 92, 182, 191,
relating data, 35 creating loops, 60 195, 196
events, 104 enabling, 196
L FTSearch method, 75, 96 examining output, 197
LANs, 162, 195 If statements, 61 NOTES.INI, 106, 126, 152
Layout regions, 92 integer division, 62 CACHE, 139
Lazy Initialization, 70 LotusScript Extensions (LSX), 52 Client_Clock, 196
LEI. See Lotus Enterprise Integrator QuerySave event, 104 Debug_Console, 196
Lightweight databases reading files, 63 Debug_Outfile, 196, 197
case study, 227 redim, 66 DominoAnalyzeFormulas, 357
Limiting bandwidth, 46 script library, 81, 122 DominoDefaultCacheValid, 360
Limits search method, 57, 75, 96 DominoTraceCmdCache, 360
Application development variant types, 62 environment variables, 68
features, 307 versus Formulas, 333 InitialCacheQuota, 139
database size, 153 WebQuerySave event, 105 limits, 308
overcoming, 9 LotusScript Extensions (LSX), 52 NSF_Buffer_Pool_Size, 31
UNK table, 9 lsof, 172 NSF_DbCache_Maxentries, 31
Load distribution Server_Clock, 182
clustering, 11 VIEW_REBUILD_DIR, 152
replication, 12 M NotesDocument class, 74
splitting application into several Measuring test results, 48 NotesPeek, 141, 184
databases, 13 Memory leak, 170 NotesUIDocument Class, 74
Load tools Methodology, 39
third party, 233 Software Performance
Local Area Network (LAN), 27 Engineering, 44 O
Local replicas, 19 Use Case Model, 41 Object oriented design, 84
Domino OffLine Services, 19 Mobile users, 10, 14, 21, 38, 207 Object reuse, 72, 73, 131
Local replication, 13 compact mobile versions of big locating documents, 77
Locations, multple databases, 16 OLE, 52
design consierations, 17 Domino OffLine Services, 19 objects, 101
Log, 173, 174 security, 22 On Disk Structure (ODS), 141, 151,
Logging Monitoring tools 152
of background processing, 34 third party, 231 OS/2, 171
Lookups Multidatabase applications monitoring tools, 171
@DbColumn, 56 techniques, 35 using IPTrace, 181
@DbCommand, 56 Outlines, 135
@DbLookup, 56 performance considerations, 135
@IsDocBeingEdited, 96 N
@IsDocBeingLoaded, 57 Netstat, 166, 172
@IsDocumentBeingSaved, 96 Network performance, 162, 164 P
alternate search methods, 57 dial-up networking, 168 Pages, 130
caching, 56 netstat, 166 Performance
design considerations, 37 ping example, 165 application factors, 4
finetuning, 95 ping utility, 164 application usage, 162
hidden views, 57 tracert, 167 as responsiveness, 2
LotusScript, 96 Notes client as throughput, 2
monitoring via ECL settings, 183 @ClientType, 55 factors affecting performance, 161
using profile documents, 107 bandwidth requirements, 29 guidelines for views, 126
Index 385
using, 89 UNK table, 9 top performance items, 193
Subsets of data more fields in database, 160 troubleshooting, 187
non-replica copies of databases, UnprocessedDocuments, 79 types (table), 112
15 Unread marks, 127, 156, 193 unread marks, 127, 156
readers fields, 15 UPDALL task, 124, 125, 126, 152 view actions, 189
selective replication, 15 UPDATE task, 123, 124, 125, 126 view applet, 130
svmon, 171 URL requests view index, 110, 115, 120, 121,
Swap, 172 ?CreateDocument, 352 123, 126
Switching between databases ?EditDocument, 351 Virtual memory, 168
framesets, 132 ?OpenDocument, 351 vmstat, 171, 172
Switching seamlessly between ?OpenForm, 352
databases, 38 ?SaveDocument, 352
System Management Facility, 172 candidates for command cache, W
356 WANs, 162
Usage patterns, 177 Web agents, 192
T Use Case Model, 41 Web browser, 89, 92, 93, 94, 102, 105,
Tables, 194 143
considerations, 91 @ClientType, 55
Domino R5.0 enhancements, 92 V bandwidth requirements, 29
limits, 308 Views, 109 caching, 108
size, 91 accessing information, 189 client-side caching, 355
tabbed tables, 92 actions, 122 cookies, 108, 180
timed tables, 92 categorization, 120, 127, 129 Domino images, 142
Task Manager, 170 column design, 120 laying out pages, 141
Test Environment, 179 column formula, 128 linking identity, 108
cleaning the environment, 180 columns, 127 number of lines in a view, 130
tools & techniques, 180 ColumnValues, 74 profile information, 107
Third Party Tools, 176, 177 data displayed, 122 saving and closing a document,
monitoring tools, 231 discarding index, 124 191
stress testing and load tools, 233 DisplayInView indicator, 239 servlets, 25
Time/date views, 235 dynamic sorting, 121 temporary internet files, 180
using agents, 239 formula, 122, 128 testing an application, 185
tprof, 171 GetNextDocument, 75 Web browsers
Tracert, 167 GetNthDocument, 75 how Domino handles document
Transaction Logging, 152 GetView, 76 URL requests, 351
Troubleshooting, 161, 164 index size in notes log, 173 WebQuerySave, 191
agents, 191 indexing comparisons, 309 While loops, 60
application performance, 178 internal information, 109 Windows NT, 169, 185
client performance, 177 limits, 307 monitoring tools, 169, 170
Domino server performance, 172 opening, 188
forms, 190 performance guidelines, 126
memory leaks, 170 personal on first use views, 110,
network performance, 164 112, 116
opening database, 186 private views, 110, 117
server operating system, 168 refresh, 123
Server.Load, 176 removing indexes, 180
usage patterns, 177 response hierarchy, 158
views, 187 SELECT statement, 128
selection formula, 120, 128, 157
single category view, 114
U size, 9
Unique Key table. See UNK table size in LOG.NSF, 110
UNIX, 181 sorting, 121
using IPTrace, 181 time/date views, 235
Your feedback is very important to help us maintain the quality of ITSO redbooks.
Please complete this questionnaire and return it using one of the following methods:
• Use the online evaluation form at http://www.redbooks.ibm.com/
• Fax it to: USA International Access Code +1 914 432 8264
• Send your comments in an Internet note to [email protected]
Which of the following best describes you?
Please rate your overall satisfaction with this book using the scale:
(1 = very good, 2 = good, 3 = average, 4 = poor, 5 = very poor)
Was this redbook published in time for your needs? Yes _________ No ________
____________________________________________________________________________________
____________________________________________________________________________________
____________________________________________________________________________________
____________________________________________________________________________________
____________________________________________________________________________________
____________________________________________________________________________________
____________________________________________________________________________________
____________________________________________________________________________________
____________________________________________________________________________________
____________________________________________________________________________________
____________________________________________________________________________________
387
388
xii Lotus Domino Release 5.0: A Developer’s Handbook
Printed in the U.S.A.
www.redbooks.ibm.com
SG24-5602-00
SG24-5602-00