ctree.htmTEXTBlWd:hJNɮJNV Ctree changes and issues

Back to index


CTREE CHANGES FOR MACINTOSH PROGRAMMERS

(The following will hopefully be rolled into later releases of c-tree)

c-tree changes to enable Mac databases to be built with different creators and types, getting around the current hard-coded constants.

1) in ctclib.c, just before the definition of sopen(), add the lines
long ctMacCreator = 'CTRE';
long ctMacType = '????';

2) in ctclib.c, change the following line in sopen()
rtn = sopenWithType(afilnam, acflag,shflag, 'CTRE', '????');
to
rtn = sopenWithType(afilnam, acflag,shflag, ctMacCreator, ctMacType);

3) in ctoptn.h, add the following 3 lines
// Macintosh programmers only, hack to allow setting types
extern long ctMacCreator;
extern long ctMacType;

Mac c-tree Plus 6.4b

The tests in sopenWithType make invalid assumptions about the values of the iomode flags, which runs headlong into the issue of different flag values in different compilers. Note, this particular bug probably won't affect other platforms (they call the ANSI sopen() ) but the thinking involved may imply similar vulnerabilities elsewhere (only where they are bit-anding with someone else's flag definitions) I haven't been able to find any other similar bugs in a global search for the bit-and and bit-or operators:

in ctmpl.h
#define BUPDATE (O_RDWR | O_BINARY)

in ctclib.c
RNDFILE mbopen(PFAST pCTFILE ctnum,COUNT opmode)
{
RNDFILE retval;
NINT acflag,shflag;
TEXT afilnam[MAX_NAME];


acflag = BUPDATE;

acflag is then passed down to

COUNT sopenWithType(pTEXT afilnam,COUNT acflag,COUNT shflag,ULONG
type,ULONG creator)
{
COUNT retval;
TEXT pname[256];
IOParam pb;
FAST IOParam *pbp = &pb; /* must be ptr to work as reg param */
OSErr result;
pTEXT filebuf;


pbp->ioNamePtr = 0;
if (PBGetVol((ParmBlkPtr)pbp, false)) pbp->ioVRefNum = 0;
pbp->ioNamePtr = (StringPtr)pfcstr(afilnam, pname, 255);
pbp->ioVersNum = 0;
if (acflag & O_RDONLY) pbp->ioPermssn = fsRdPerm; /* ??? seems like it should be fsRdWrPerm */
else if (acflag & O_WRONLY) pbp->ioPermssn = fsWrPerm;
else if (acflag & O_RDWR) {
if (shflag & SH_DENYNO) pbp->ioPermssn = fsRdWrShPerm;
else pbp->ioPermssn = fsRdWrPerm;
}
else pbp->ioPermssn = fsCurPerm;

RESULTS OF YOUR CODE:
1) with Symantec and Apple definitions:
#define O_WRONLY 0x0001
#define O_RDWR 0x0002
#define O_RDONLY 0

if (acflag & O_RDONLY)
will fail. It will fall through to the default case which is relatively safe (granting ReadWrite permission sometimes to a file expecting ReadOnly)
pbp->ioPermssn = fsCurPerm

2) with Metrowerks definitions
#define O_RDWR 0x0
#define O_RDONLY 0x1
#define O_WRONLY 0x2

if (acflag & O_RDWR)
will fail, falling through again to the default case which grants ReadWrite to only the first program to open the file.

PROPOSED FIX TO sopenWithType
if ((acflag & O_RDONLY)==O_RDONLY) pbp->ioPermssn = fsRdPerm; /* ??? seems like it should be fsRdWrPerm */
else if ((acflag & O_WRONLY)==O_WRONLY) pbp->ioPermssn = fsWrPerm;
else if ((acflag & O_RDWR)==O_RDWR) {
if ((shflag & SH_DENYNO)==SH_DENYNO) pbp->ioPermssn = fsRdWrShPerm;

The above code makes a multiple reader/one writer work, in contrast to the immediate err 12 on opening the second accessor encountered before.


CTREE BACKEND IMPLEMENTATION DETAILS

This provides some documentation of how the c-tree Plus backend works, as much for our benefit as yours - you should never be fiddling with these mechanisms unless you are prepared to accept the responsibility of possibly breaking the database engine.

On the other hand, if you have suggested improvements - great!

COMPARATIVE SEARCHES FOR UNIQUE KEYS

Greater-than
Must append a suffix to the key that's the highest possible suffix.
eg:
key = 1
first actual value = 1 suffix 26,345
to prevent finding that key, we need to search for > 1 suffix MAXLONG

Greater-than or equal
Must append a suffix to the key that's the lowest possible suffix.
eg:
key = 1
first actual value = 1 suffix 26,345
to find that key, we need to search for > 1 suffix 0

Less than
Must append a suffix to the key that's the lowest possible suffix.
eg:
key = 1
first actual value = 1 suffix 26,345
to find that key, we need to search for < 1 suffix 0

Less than or equal
Must append a suffix to the key that's the highest possible suffix.
eg:
key = 1
first actual value = 1 suffix 26,345
to find that key, we need to search for < 1 suffix MAXLONG

DUPLICATE KEY BACKGROUND

c-tree handles dup keys by appending the record offset to the key, to make it unique. This means you can't predict the complete value of the key, or the starting key!

COMPARATIVE SEARCHES FOR DUPLICATE KEYS

Greater-than
Must append a suffix to the key that's the highest possible suffix.
eg:
key = 1
first actual value = 1 suffix 26,345
to prevent finding that key, we need to search for > 1 suffix MAXLONG

Greater-than or equal
Must append a suffix to the key that's the lowest possible suffix.
eg:
key = 1
first actual value = 1 suffix 26,345
to find that key, we need to search for > 1 suffix 0

Less than
Must append a suffix to the key that's the lowest possible suffix.
eg:
key = 1
first actual value = 1 suffix 26,345
to find that key, we need to search for < 1 suffix 0

Less than or equal
Must append a suffix to the key that's the highest possible suffix.
eg:
key = 1
first actual value = 1 suffix 26,345
to find that key, we need to search for < 1 suffix MAXLONG

FIELD MAPPING TO STORAGE

There is a record buffer associated with every dbTable instance.

This record buffer is mapped to the field by a table of offsets and lengths, stored in the OOFILE_tableBackend_ctree class. This mapping table is used in constructing the ctree ISEG structures describing the indexes. It is also used in transferring data between the record buffer and gui classes, or other operators that transfer data. (eg: operator=, operator char* & stream output).

Thus, most fields don't have a separate buffer but just refer into the main record buffer.

Blob, Text and other (future) expandable fields are contained in a separate file. There is one Blob file per connection (ie: superfile enclosing a set of c-tree files).

To optimize writing and reading Blob records, they are not pulled in from the database until needed, by some data interchange or linking to a gui editing class. The blobs are also only written back if updated. Thus, a blob is managed by a pair of length and record offset fields in the main record. The dbBlob object contains also a dirty flag and a pointer to a memory buffer.

A blob which has been cleared or never written has a zero length and no corresponding blob record. This means we have some special case handling for empty dbText fields, which contain a single char - the terminating null, but should be treated as zero-length blobs rather than length=1.


Back to index


ZObject Master 3.0.4 Prefs ctree.htmPartSIT!PartSIT!uh%Realmz Preferences%ScriptWizard Preferences5%Sound Preferences@  w%w%w%    w%w%w%  "a/Q,  w%w%w%4  5  w%w%w%<  =  w%w%w%C  D  w%w%w%H  I  w%w%w%   w%w%w%   w%w%w%  w%w%w%   w%w%w%    w%w%w%!    w%w%w%    w%w%w%    w%w%w%  1  w%w%w%4  i  w%w%w%m    w%w%w%    w%w%w%    w%w%w%  +  w%w%w%/  j  w%w%w%n    w%w%w%    w%w%w%    w%w%w%   w%w%w%    w%w%w%    w%w%w%    w%w%w%    w%w%w%    w%w%w%  I  w%w%w%M  O  w%w%w%S  k  w%w%w%o    w%w%w%    w%w%w%    w%w%w%    w%w%w%    w%w%w%    w%w%w%  F  w%w%w%J  ^  w%w%w%b  d  w%w%w%h    w%w%w%    w%w%w%    w%w%w%    w%w%w%  0  w%w%w%4  M  w%w%w%Q  R  w%w%w%V  W  w%w%w%[  x  w%w%w%|    w%w%w%    w%w%w%   #  w%w%w% '   w%w%w%    w%w%w%     w%w%w%   P  w%w%w% T   w%w%w%    w%w%w%    w%w%w%    w%w%w%     w%w%w%   2  w%w%w% 6  ]  w%w%w% a   w%w%w%    w%w%w%    w%w%w%   E  w%w%w% I  m  w%w%w% p   w%w%w%    w%w%w%    w%w%w%    w%w%w%   *  w%w%w% .   w%w%w%    w%w%w%   B  w%w%w%F    w%w%w%    w%w%w%    w%w%w%    w%w%w%    w%w%w%    w%w%w%    w%w%w%  w%w%w%    w%w%w%    w%w%w%  -  w%w%w%0  1  w%w%w%5 Y  w%w%w%^  _  w%w%w%b  o  w%w%w%s    w%w%w%    w%w%w%    w%w%w%    w%w%w%  @  w%w%w%C  Y  w%w%w%]    w%w%w%    w%w%w%    w%w%w%    w%w%w%    w%w%w%  %  w%w%w%)  m  w%w%w%q  u  w%w%w%y    w%w%w%    w%w%w%    w%w%w%    w%w%w%  F  w%w%w%J  N  w%w%w%R  Z  w%w%w%^    w%w%w%    w%w%w%    w%w%w%   w%w%w%    w%w%w%    w%w%w%    w%w%w%   w%w%w%    w%w%w%    w%w%w%  %  w%w%w%)  -  w%w%w%1  9  w%w%w%=  b  w%w%w%f    w%w%w%    w%w%w%    w%w%w%    w%w%w%  "  w%w%w%&  K  w%w%w%O    w%w%w%    w%w%w%    w%w%w%    w%w%w%    w%w%w%    w%w%w%  T  w%w%w%W  j  w%w%w%n    w%w%w%    w%w%w%    w%w%w%    w%w%w%  2  w%w%w%6  7  w%w%w%; S  w%w%w%]    w%w%w%  "  w%w%w%'    w%w%w%  .  w%w%w%3    w%w%w%    w%w%w%    w%w%w%    w%w%w%(  )  w%w%w%5  6  w%w%w%=  Z0.Zstylsoup&8859222