summaryrefslogtreecommitdiff
path: root/doc/UsersGuide/UtilityRoutines.tex
diff options
context:
space:
mode:
authorjthorn <jthorn@17b73243-c579-4c4c-a9d2-2d5706c11dac>2001-12-20 16:59:29 +0000
committerjthorn <jthorn@17b73243-c579-4c4c-a9d2-2d5706c11dac>2001-12-20 16:59:29 +0000
commit8c07f9aa71c72b9e344f2da3b57f70503b6eb679 (patch)
treec0faa82836aef8b15db70e7251000ed055502329 /doc/UsersGuide/UtilityRoutines.tex
parentdaf60ea934bd88caa2874a36fbe564561a34b07e (diff)
add new chapter "Utility Routines",
initially containing programming guide for the key/value tables routines. also renumber all the other cactusparts, i.e. utility routines is now C, Infrastructure Thorn Writer's Guide is now D, Function Reference E, etc git-svn-id: http://svn.cactuscode.org/flesh/trunk@2522 17b73243-c579-4c4c-a9d2-2d5706c11dac
Diffstat (limited to 'doc/UsersGuide/UtilityRoutines.tex')
-rw-r--r--doc/UsersGuide/UtilityRoutines.tex367
1 files changed, 367 insertions, 0 deletions
diff --git a/doc/UsersGuide/UtilityRoutines.tex b/doc/UsersGuide/UtilityRoutines.tex
new file mode 100644
index 00000000..aa3beb97
--- /dev/null
+++ b/doc/UsersGuide/UtilityRoutines.tex
@@ -0,0 +1,367 @@
+% /*@@
+% @file UtilityRoutines.tex
+% @date 27 Jan 1999
+% @author Jonathan Thornburg
+% @desc
+% Description of the Util_* utility routines for the Cactus User's Guide.
+% @enddesc
+% @version $Header$
+% @@*/
+\begin{cactuspart}{3}{Utility Routines}{$RCSfile$$}{$Revision$}
+\renewcommand{\thepage}{\Alph{part}\arabic{page}}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{Introduction}
+
+As well as the high-level \verb|CCTK_|* routines, Cactus also
+provides a set of lower-level \verb|Util_|* utility routines, which
+are mostly independent of the rest of Cactus. This chapter gives a
+general overview of programming with these utility routines.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\chapter{Key/Value Tables}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\section{Motivation}
+
+Various Cactus functions need to pass information through a generic
+interface. In the past we have used various ad-hoc means to do this,
+and we often had trouble passing "extra" information that wasn't
+anticipated in the original design. For example, for interpolation
+\verb|CCTK_InterpLocal()| and \verb|CCTK_InterpGV()| require that
+any parameters (such as the order of the interpolant) be encoded
+into the interpolator's character string name. Similarly, elliptic
+solvers often need to pass various parameters, but we don't have a
+good way to do this.
+
+Key/value tables (``tables'' for short) provide a clean solution
+to these problems. They're implemented by the \verb|Util_Table|*
+functions (described in detail in
+section~\ref{sect-FunctionReference/UtilityFunctions}).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\section{The Basic Idea}
+
+Basically, a table is an object which maps strings to almost-arbitrary
+user-defined data. (If you know Perl, a table is very much like a
+Perl hash table.)%%%
+\footnote{%%%
+ However, the present Cactus tables implementation
+ is optimized for a relatively small number of
+ distinct keys in any one table. It will still
+ work ok for huge numbers of keys, but it will be
+ slow.
+ }%%%
+
+More formally, a table is an object which stores a set of ``keys''
+and a corresponding set of ``values''.
+
+Keys are C-style null-terminated character strings, with the slash
+character \verb|'/'| reserved for future expansion.%%%
+\footnote{%%%
+ Think of hierarchical tables for storing
+ tree-like data structures.%%%
+ }%%%
+
+Values are 1-dimensional arrays of any of the usual Cactus data types
+described in section~\ref{sect-ThornWriting/DataTypes}.
+A string can be stored by treating it as a 1-dimensional array of
+\verb|CCTK_CHAR| (there's an example of this below).
+
+The basic ``life cycle'' of a table is that you first create it
+with \verb|Util_TableCreate()|, then set values in it with one or
+more of the \verb|Util_TableSet*()| and/or \verb|Util_TableSet*Array()|
+functions, then later on some other piece of code can get (copies of)
+the values you set from the table with one or more of the
+\verb|Util_TableGet*()| and/or \verb|Util_TableGet*Array()| functions.
+Finally, when you're through with a table you destroy it with
+\verb|Util_TableDestroy()|.
+
+For simple uses, there's also a short-cut function
+\verb|Util_TableCreateFromString()|, which creates a table and
+sets some integer or real values in it, based on a parameter-file--style
+string.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\section{A Simple Example}
+
+Here's a simple example (in C)%%%
+\footnote{%%%
+ In theory tables should be usable from both
+ C and Fortran, but noone has written the Fortran
+ wrappers yet, so at present tables are C-only.
+ }%%%
+{} of how to use a table:
+\begin{verbatim}
+#include "util_Table.h"
+#include "cctk.h"
+
+/* create a table and set some values in it */
+int handle = Util_TableCreate(UTIL_TABLE_FLAGS_DEFAULT);
+Util_TableSetInt(handle, 2, "two");
+Util_TableSetReal(handle, 3.14, "pi");
+
+...
+
+/* get the values from the table */
+CCTK_INT two_value;
+CCTK_REAL pi_value;
+Util_TableGetInt(handle, &two_value, "two"); /* sets two_value = 2 */
+Util_TableGetReal(handle, &pi_value, "pi"); /* sets pi_value = 3.14 */
+\end{verbatim}
+
+Actually, you shouldn't write code like this -- in the real world
+errors sometimes happen, and it's not at all nice to have your program
+crash. The {\em right\/} thing to do is to always check for errors.
+To allow this, all the table routines return a status, which is
+zero or positive for a successful return, but negative if and only
+if some sort of error has occured.%%%
+\footnote{%%%
+ Often (as in the examples here) you don't care
+ about the details of which error occured. But if
+ you do, there are various error codes defined in
+ {\t "util\_Table.h"} and {\t "util\_ErrorCodes.h"};
+ the detailed function descriptions in
+ section~\ref{sect-FunctionReference/UtilityFunctions}
+ say which error codes each function can return.
+ }%%%
+{} So, the above example can (should) be rewritten like this:
+
+\begin{verbatim}
+#include <util_Table.h>
+
+/* create a table and set some values in it */
+int handle = Util_TableCreate(UTIL_TABLE_FLAGS_DEFAULT);
+if (handle < 0)
+ CCTK_WARN(-1, "couldn't create table!");
+
+/* try to set two_value = 2 and set pi_value = 3.14 */
+if (Util_TableSetInt(handle, 2, "two") < 0)
+ CCTK_WARN(-1, "couldn't set integer value in table!");
+if (Util_TableSetReal(handle, 3.14, "pi") < 0)
+ CCTK_WARN(-1, "couldn't set real value in table!");
+
+...
+
+/* get the values from the table */
+CCTK_INT two_value;
+CCTK_REAL pi_value;
+/* try to get two_value and pi_value from the table */
+if (Util_TableGetInt(handle, &two_value, "two") < 0)
+ CCTK_WARN(-1, "couldn't get integer value from table!");
+if (Util_TableGetReal(handle, &pi_value, "pi") < 0)
+ CCTK_WARN(-1, "couldn't get integer value from table!");
+
+/* now two_value = 2 and pi_value = 3.14 */
+\end{verbatim}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\section{Arrays as Table Values}
+
+As well as a single numbers (or characters or pointers), tables can
+also store 1-dimensional arrays of numbers (or characters or pointers).%%%
+\footnote{%%%
+ The table makes (stores) a {\em copy\/} of the array
+ you pass in, so you probably shouldn't use tables to
+ store really big arrays like grid functions. But it's
+ fine to store things like parameters and coefficients.
+ (If you do have a really big array, consider storing
+ a pointer to it.)%%%
+ }%%%
+
+For example (continuing the previous example):
+\begin{verbatim}
+static const CCTK_INT a[3] = { 42, 69, 105 };
+if (Util_TableSetIntArray(handle, 3, a, "my array") < 0)
+ CCTK_WARN(-1, "couldn't set integer array value in table!");
+
+...
+
+CCTK_INT blah[10];
+int count = Util_TableGetIntArray(handle, 10, blah, "my array");
+if (count < 0)
+ CCTK_WARN(-1, "couldn't get integer array value from table!");
+/* now count = 3, blah[0] = 42, blah[1] = 69, blah[2] = 105, */
+/* and all remaining elements of blah[] are unchanged */
+\end{verbatim}
+As you can see, a table entry remembers the length of any array
+value that has been stored in it.%%%
+\footnote{%%%
+ In fact, actually {\em all\/} table values are
+ arrays -- setting or getting a single value is
+ just the special case where the array length is 1.
+ }%%%
+{}
+
+If you only want the first few values of a larger array, just pass
+in the appropriate length of your array:
+that's ok:
+\begin{verbatim}
+CCTK_INT blah2[2];
+int count = Util_TableGetIntArray(handle, 2, blah2, "my array");
+if (count < 0)
+ CCTK_WARN(-1, "couldn't get integer array value from table!");
+/* now count = 3, blah2[0] = 42, blah2[1] = 69 */
+\end{verbatim}
+You can even ask for just the first value:
+\begin{verbatim}
+CCTK_INT blah1;
+int count = Util_TableGetInt(handle, blah1, "my array");
+if (count < 0)
+ CCTK_WARN(-1, "couldn't get integer array value from table!");
+/* now count = 3, blah1 = 42 */
+\end{verbatim}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\section{Character Strings}
+
+One very common thing you might want to store in a table is a
+character string. While you could do this by explicitly storing
+an array of \verb|CCTK_CHAR|, there are also more-convenient routines
+specially for setting and getting strings:
+\begin{verbatim}
+if (Util_TableSetString(handle, "black holes are fun", "bh") < 0)
+ CCTK_WARN(-1, "couldn't set string value in table!");
+
+...
+char buffer[50];
+if (Util_TableGetString(handle, 50, buffer, "bh") < 0)
+ CCTK_WARN(-1, "couldn't get string value from table!");
+
+/* now buffer[] contains the string "black holes are fun" */
+\end{verbatim}
+
+\verb|Util_TableGetString()| guarantees that the string is
+terminated by a null character (\verb|'\0'|), and also returns an
+error if the string is too long for the buffer.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\section{Table Options}
+
+A table has an integer ``flags word'' which may be used to specify
+various options, via bit flags defined in \verb|"util_Table.h"|:
+\begin{description}
+\item[Keys May be Case-Sensitive or Case-Insensitive]
+ By default keys are compared as C-style character strings,
+ compared with the standard \verb|strcmp()| function.
+ However, optionally keys may be made case-insensitive,
+ compared with \verb|Util_StrCmpi()|.%%%
+\footnote{%%%
+ It's not entirely clear how non-ASCII characters
+ like \c{c}, \'{e}, \ss, \dots should be handled in
+ this case (some of them have only a single case).
+ And what about the 16-bit Asian character sets
+ used for Chinese, Japanese, Korean, \dots.
+ In general, Cactus basically just ignores
+ internationalization issues. Sigh\dots
+ }%%%
+\item[Auto-Destruction of Tables]
+ By default, you (the programmer) are responsibe for
+ destroying a table when you're done with it. However,
+ tables also support an ``auto-destroy'' flag. If this
+ is set for a table, then the table will automagically
+ be destroyed when the {\em next\/} table is created
+ (regardless of what flags that table has).
+ Thus at most one table with the auto-destroy flag set
+ can exist at any time, and, in practice, so long as
+ you don't store huge arrays in them, there's no need
+ to bother with explicitly destroying such tables
+ (\ie{} the memory waste is pretty small).
+ The convenience routine
+ \verb|Util_TableCreateFromString()| sets the
+ auto-destroy flag for the tables it creates, so if
+ you're willing to skip error checking, you can use
+ it directly in another function call, as in (for example)
+\begin{verbatim}
+CCTK_SomeCactusFunction(..., Util_TableCreateFromString("answer=42"), ...);
+\end{verbatim}
+\end{description}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\section{Table Iterators}
+
+In the examples up to now, the code which wanted to get values from
+the table knew what the keys were. It's also useful to be able to
+write generic code which can operate on a table without knowing the
+keys. ``Table iterators'' (``iterators'' for short) are used for this.
+
+An iterator is an abstraction of a pointer to a particular table entry.
+Iterators are analogous to the Unix current working directory, to
+database cursors, to the \verb|DIR *| pointers used by the POSIX
+\verb|opendir()|, \verb|readdir()|, \verb|closedir()|, and similar
+functions, and to Perl hash tables' \verb|each()|, \verb|keys()|,
+and \verb|values|.
+
+The entries in a table may be considered to be in some
+implementation-defined order; an iterator may be used to walk through
+some or all of the table entries in this order. This order is
+arbitrary, and may change if there is any change in the table
+(setting a value or deleting a table entry).%%%
+\footnote{%%%
+ For example, if tables were implemented by hashing,
+ the internal order could be that of the hash buckets.
+ }%%%
+{} Any change in the table also invalidates all iterators pointing
+anywhere in the table; using any such iterator is an error.
+Multiple iterators may point into the same table; they all use the
+same ordering, and (unlike in Perl) they're all independent.
+
+The detailed function description
+(section~\ref{sect-FunctionReference/UtilityFunctions})
+for \verb|Util_TableItQueryKeyValueInfo()| has an example of
+using an iterator to print out all the entries in a table.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\section{Multithreading}
+
+{\bf At the moment, the table functions are {\em not\/} thread-safe
+in a multithreaded environment!} However, this should change in
+the not-too-distant future: then all the table functions will default
+to being thread-safe. That is, user code will be able call these
+functions concurrently from multiple threads, with the thread routines
+taking care of any necessary locking. (There may be a flags-word bit
+to suppress this for maximum performance if you know you won't be
+making concurrent calls from multiple threads.)
+
+Note that tables and iterators will still be process-wide, i.e. all
+threads see the same tables and iterators (think of them as like the
+Unix current working directory, with the various routines which modify
+the table or change iterators acting like a Unix \verb|chdir()| system call).
+
+For the implementation, this means that we will need a reader/writer
+lock for each table and for each iterator: any number of threads will
+be able to concurrently read the data structure, but any write will
+require exclusive access.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\section{Metadata about All Tables}
+
+We have decided that tables do not {\em themselves\/} have names or other
+attributes. However, at some time in the future we may add some special
+``system tables'' by Cactus itself to store this sort of information
+for those cases where it's needed.
+
+For example, at some time in the future we may add support for a
+``checkpoint me'' bit in a table's flags word, so that if you want a
+table to be checkpointed, you just need to set this bit.
+In this case the table will probably get a system-generated name in
+the checkpoint dump file. But if you want the table to have some
+other name in the dump file, then you need to tell the checkpointing
+code that by setting an appropriate entry in a checkpoint table.
+(You would find the checkpoing table by looking in a special
+``master system table'' that records handles of other interesting tables.)
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\end{cactuspart}