summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchatty1993-12-22 12:26:39 +0000
committerchatty1993-12-22 12:26:39 +0000
commit7ebcfbbbfb1f844261b3c810684ffa244e41080b (patch)
tree71c90ea1a6d2a73c33935500cd033baf3b508163
parentfa5d3f424a09155e714394eb9b501c81373e0973 (diff)
downloadivy-league-7ebcfbbbfb1f844261b3c810684ffa244e41080b.zip
ivy-league-7ebcfbbbfb1f844261b3c810684ffa244e41080b.tar.gz
ivy-league-7ebcfbbbfb1f844261b3c810684ffa244e41080b.tar.bz2
ivy-league-7ebcfbbbfb1f844261b3c810684ffa244e41080b.tar.xz
replaced TRUE/FALSE by true/false
-rw-r--r--utils/IdTable.cc307
-rw-r--r--utils/RegExp.cc40
-rw-r--r--utils/bool.h10
-rw-r--r--utils/doc.main4
4 files changed, 189 insertions, 172 deletions
diff --git a/utils/IdTable.cc b/utils/IdTable.cc
index bd18e0a..bfca17a 100644
--- a/utils/IdTable.cc
+++ b/utils/IdTable.cc
@@ -17,13 +17,13 @@
#include <memory.h>
/*?class CcuIdTable
-The class \typ{CcuIdTable} stores object pointers in a table, and assigns them a unique identifier.
+A \typ{CcuIdTable} stores pointers in a table, and assigns them a unique identifier.
Objects can be added, removed and retrieved in constant time (roughly, an index and a test).
This makes this class very useful for distributed applications that usually need
to communicate object identifiers instead of object pointers. In such applications,
mapping the identifier to an object must be a very fast operation.
-The following paragraphs details the implementation of the ident table.
+The following paragraphs details the implementation of the identifier table.
An identifier (id for short) is a 32 bits number made of an index in a table
in the lower 16 bits, and a check number in the higher 16 bits.
@@ -32,8 +32,7 @@ and the object pointer.
Each entry in the table corresponds to a unique id made of the check of this
entry and its index.
-Free entries in the table are linked in a free list by using the type field.
-They also have a nil object pointer.
+Entries can be discarded, then reused.
Each time an entry is reused, its check number is incremented.
Thus, the id corresponding to this entry differs from the previous id.
@@ -52,63 +51,87 @@ Note that growing the table only involves linking the new free entries.
This is far less expensive than rehashing a hash table for instance.
?*/
+/*
+ * TID_MASK = 2^TID_SHIFT = max table size
+ * TID_MASK = TID_SHIFT bits set to 1.
+ */
+#define TID_MAX (2 << 16)
+#define TID_SHIFT 16
+#define TID_MASK 0xffff
+
+
+struct CcuIdCell {
+ sword Check; // the check number
+ CcuIdType Type; // for the appli, for free list when not allocated
+ CcuIdItem* Info;
+
+inline CcuID ComputeId (const CcuIdTable* t)
+ {
+ return (CcuID) ((Check << TID_SHIFT) | (this - t->Entries));
+ }
+};
+
/*?
-Build an ident table with \var{nb} entries.
+Build an ident table with $2^sz$ entries.
The table grows automatically (by a factor of 2) until 32768 entries (the maximum).
?*/
-CcuIdTable :: CcuIdTable (int nb)
+CcuIdTable :: CcuIdTable (int sz)
{
- if (nb > TID_MAX)
- nb = TID_MAX;
- entries = new CcuIdCell [nb];
- memset (entries, 0, nb * sizeof (CcuIdCell));
- last = entries + nb;
+ if (sz > TID_MAX)
+ sz = TID_MAX;
+ else if (sz < 0)
+ sz = 0;
+ int nb = 2 << sz;
+
+ Entries = new CcuIdCell [nb];
+ memset (Entries, 0, nb * sizeof (CcuIdCell));
+ LastCell = Entries + nb;
- // link free entries with the 'typ' field
+ // link free entries with the 'Type' field
int i = 0;
- for (CcuIdCell* p = entries; p < last; p++)
- p->typ = ++i;
+ for (CcuIdCell* p = Entries; p < LastCell; p++)
+ p->Type = ++i;
- (--p)->typ = 0; // end of free list
- free = 0;
- last_free = --i;
- num_free = nb;
+ (--p)->Type = 0; // end of free list
+ FirstFree = 0;
+ LastFree = --i;
+ NumFree = nb;
}
/*?hidden?*/
bool
CcuIdTable :: Grow (int newNb)
{
- int nb = last - entries;
+ int nb = LastCell - Entries;
if (nb >= TID_MAX)
- return FALSE;
+ return false;
if (newNb >= TID_MAX)
newNb = TID_MAX;
CcuIdCell* newTbl = new CcuIdCell [newNb];
int size = nb * sizeof (CcuIdCell);
- memcpy (newTbl, entries, size);
+ memcpy (newTbl, Entries, size);
memset (newTbl + nb, 0, newNb * sizeof (CcuIdCell) - size);
#ifdef CPLUS_BUG4
- delete [nb] entries;
+ delete [nb] Entries;
#else
- delete [] entries;
+ delete [] Entries;
#endif
- entries = newTbl;
- last = newTbl + newNb;
+ Entries = newTbl;
+ LastCell = newTbl + newNb;
- // link free entries with the 'typ' field
+ // link free entries with the 'Type' field
int i = nb;
- for (CcuIdCell* p = entries + nb; p < last; p++)
- p->typ = ++i;
+ for (CcuIdCell* p = Entries + nb; p < LastCell; p++)
+ p->Type = ++i;
// prepend to current free list (to use them first)
- (--p)->typ = free;
- free = nb;
- last_free = --i;
- num_free += newNb - nb;
+ (--p)->Type = FirstFree;
+ FirstFree = nb;
+ LastFree = --i;
+ NumFree += newNb - nb;
- return TRUE;
+ return true;
}
/*?
@@ -118,47 +141,61 @@ If the table is full, return 0 (0 cannot be a valid identifier).
It can be used to store the type of the object.
\var{obj} cannot be 0.
?*/
-lword
-CcuIdTable :: Store (const void* obj, sword typ)
+CcuID
+CcuIdTable :: Store (CcuIdItem* obj, CcuIdType typ)
{
- if (num_free == 0)
- if (! Grow ((last - entries) * 2))
+ if (NumFree == 0)
+ if (! Grow ((LastCell - Entries) * 2))
return 0;
// get entry out of free list
- register CcuIdCell* p = entries + free;
- free = p->typ;
- --num_free;
+ register CcuIdCell* p = Entries + FirstFree;
+ FirstFree = p->Type;
+ --NumFree;
- p->chk++;
- p->obj = obj;
- p->typ = typ;
+ p->Check++;
+ p->Info = obj;
+ p->Type = typ;
- return (p->chk << TID_SHIFT) | (p - entries);
+ return p->ComputeId (this);
}
/*?
Remove object with identifier \var{id} from table.
-Return FALSE if it was not found.
+Return false if it was not found.
?*/
-bool
-CcuIdTable :: Remove (lword id)
+CcuIdItem*
+CcuIdTable :: Remove (CcuID id, bool* found, CcuIdType* type)
{
- register sword i = sword (id & TID_MASK);
- register CcuIdCell* p = entries + i;
-
- if (p->chk != id >> TID_SHIFT)
- return FALSE;
-
- // link at end of free list (this avoids reusing the same ids too often)
- p->obj = 0; // mark free
- if (num_free)
- entries [last_free].typ = i;
- else
- free = i;
- last_free = i;
- num_free++;
-
- return TRUE;
+ register CcuIdIndex i = CcuIdIndex (id & TID_MASK);
+ register CcuIdCell* p = Entries + i;
+
+ CcuIdType ret_type;
+ bool ret_found;
+ CcuIdItem* ret_value;
+
+ if (p->Check != id >> TID_SHIFT) {
+ ret_type = 0;
+ ret_value = 0;
+ ret_found = false;
+ } else {
+ ret_type = p->Type;
+ ret_value = p->Info;
+ ret_found = true;
+ /* link at end of free list (this avoids reusing the same ids too often) */
+ p->Info = 0; // mark as free
+ p->Check = 0; // mark as free
+ if (NumFree > 0)
+ Entries [LastFree].Type = (CcuIdType) i;
+ else
+ FirstFree = i;
+ LastFree = i;
+ NumFree++;
+ }
+ if (found)
+ *found = ret_found;
+ if (type)
+ *type = ret_type;
+ return ret_value;
}
/*?
@@ -166,17 +203,17 @@ Retrieve object with identifier \var{id} from table.
Return the object pointer, or 0 if it was not found.
if \var{typ} is not 0, it is filled with the type of the object.
?*/
-const void*
-CcuIdTable :: Get (lword id, sword* typ)
+CcuIdItem*
+CcuIdTable :: Get (CcuID id, CcuIdType* typ)
{
- register CcuIdCell* p;
-
- p = entries + (id & TID_MASK);
- if (p->chk != id >> TID_SHIFT)
+ register CcuIdCell* p;
+
+ p = Entries + (id & TID_MASK);
+ if (p->Check != id >> TID_SHIFT)
return 0;
if (typ)
- *typ = p->typ;
- return p->obj;
+ *typ = p->Type;
+ return p->Info;
}
/*?
@@ -187,72 +224,48 @@ This makes it possible to store entries in the table with identifiers allocated
elsewhere, for instance to maintain a local copy of a remote table.
?*/
void
-CcuIdTable :: Change (lword id, const void* obj, sword typ)
+CcuIdTable :: Change (CcuID id, CcuIdItem* obj, CcuIdType typ)
{
- register CcuIdCell* p;
+ register CcuIdCell* p;
- p = entries + (id & TID_MASK);
- int ip = p - entries;
+ p = Entries + (id & TID_MASK);
+ int ip = p - Entries;
- if (p >= last) {
- int size = last - entries;
+ if (p >= LastCell) {
+ int size = LastCell - Entries;
while (size <= ip)
size *= 2;
if (! Grow (size))
return;
- p = entries + ip;
+ p = Entries + ip;
}
- if (! p->obj) {
+ if (! p->Info) {
// it's in the free list
- if (ip == free) {
+ if (ip == FirstFree) {
// if we maintain two tables in sync, this will always be the case
- free = p->typ;
+ FirstFree = p->Type;
} else {
- int i = free;
+ int i = FirstFree;
int j;
- while ((j = entries [i].typ) != ip)
+ while ((j = Entries [i].Type) != ip)
i = j;
- entries [i].typ = p->typ;
- if (ip == last_free)
- last_free = i;
+ Entries [i].Type = p->Type;
+ if (ip == LastFree)
+ LastFree = i;
}
- num_free--;
+ NumFree--;
}
- p->chk = sword (id >> TID_SHIFT);
- p->typ = typ;
- p->obj = obj;
+ p->Check = sword (id >> TID_SHIFT);
+ p->Type = typ;
+ p->Info = obj;
}
/*?class CcuIdIter
The class \typ{CcuIdIter} is an iterator over \typ{CcuIdTable}.
?*/
-/*?hidden?*/
-void
-CcuIdIter :: Step ()
-{
- if (! cur)
- return;
-
- // if table changed, reassign current
- if (entries != idt->entries) {
- cur = idt->entries + (cur - entries);
- entries = idt->entries;
- }
-
- // find valid entry
- while (cur < idt->last) {
- if (cur->obj)
- return;
- cur++;
- }
- cur = 0;
-}
-
#ifdef DOC
-// fake entries for documentation
-
/*?
Build an iterator over the table \var{t}.
?*/
@@ -261,59 +274,63 @@ CcuIdIter :: CcuIdIter (CcuIdTable& t)
}
/*?
-This operator is similar to \fun{Current} below, except that it
-advances the iterator to the next valid entry if the current entry has ben removed.
-The iterator can be on an invalid entry if the current entry is removed from
-the iterator itself.
+Reset the iterator to enumerate the whole table again.
?*/
-const void*
-CcuIdIter :: operator () ()
+void
+CcuIdIter :: Reset ()
{
}
+#endif /* DOC */
+
/*?
-Advance the iterator to the next entry and return its associated data.
-Return NIL if the whole table has been enumerated.
-Note that this cannot be distinguished from an NIL data associated to
-the current entry.
+Advance the iterator to the next entry.
?*/
-const void*
+CcuIdIter&
CcuIdIter :: operator ++ ()
{
+ if (! CurCell)
+ return *this;
+
+ // if table changed, reassign current
+ if (Entries != TheTable->Entries) {
+ CurCell = TheTable->Entries + (CurCell - Entries);
+ Entries = TheTable->Entries;
+ }
+
+ // find valid entry
+ while (++CurCell < TheTable->LastCell) {
+ if (CurCell->Info != 0) {
+ StatusFlag = Normal;
+ return *this;
+ }
+ }
+ StatusFlag = EndOfTable;
+ CurCell = 0;
+ return *this;
}
/*?nextdoc?*/
-const void*
-CcuIdIter :: Current ()
+CcuIdItem*
+CcuIdIter :: Current () const
{
+ return (CurCell && StatusFlag == Normal) ? CurCell->Info : 0;
}
/*?nextdoc?*/
-sword
-CcuIdIter :: CurType ()
+CcuIdType
+CcuIdIter :: CurType () const
{
+ return (CurCell && StatusFlag == Normal) ? CurCell->Type : 0;
}
/*?
Return the information of the current entry:
its associated data, its type, and its ident.
If the iterator is finished, these functions return 0.
-\fun{CurId} is the only function for which 0 cannot be returned
-for a valid entry. So this is the most secure way to identify that the whole
-table has been ennumerated.
?*/
-lword
-CcuIdIter :: CurId ()
+CcuID
+CcuIdIter :: CurId () const
{
+ return (CurCell && StatusFlag == Normal) ? CurCell->ComputeId (TheTable) : 0;
}
-
-/*?
-Reset the iterator to enumerate the whole table again.
-?*/
-void
-CcuIdIter :: Reset ()
-{
-}
-
-#endif /* DOC */
-
diff --git a/utils/RegExp.cc b/utils/RegExp.cc
index 99f7db3..7803f06 100644
--- a/utils/RegExp.cc
+++ b/utils/RegExp.cc
@@ -39,8 +39,8 @@ CcuRegExp :: CcuRegExp (const char* expr)
#include <malloc.h>
/*?
-Compile a regular expression before using it. This function returns FALSE upon failure,
-TRUE upon success.
+Compile a regular expression before using it. This function returns false upon failure,
+true upon success.
?*/
bool
CcuRegExp :: Compile ()
@@ -49,22 +49,22 @@ CcuRegExp :: Compile ()
if (regcomp (&tmp, String, REG_NOSUB) == 0) {
Compiled = malloc (sizeof (struct regex_t));
memcpy (&Compiled, &tmp, sizeof (struct regex_t));
- return TRUE;
+ return true;
} else
- return FALSE;
+ return false;
}
/*?
-Match a string against a regular expression. This function returns FALSE upon failure,
-TRUE upon success.
+Match a string against a regular expression. This function returns false upon failure,
+true upon success.
?*/
bool
CcuRegExp :: Match (const char* s)
{
if (Compiled)
- return regexec ((struct regex_t*) Compiled, s, 0, 0, 0) ? TRUE : FALSE;
+ return regexec ((struct regex_t*) Compiled, s, 0, 0, 0) ? true : false;
else
- return FALSE;
+ return false;
}
/*?nodoc?*/
@@ -96,10 +96,10 @@ CcuRegExp :: Compile ()
{
if (re_comp (String) != 0) {
Compiled = 0;
- return FALSE;
+ return false;
} else {
Compiled = this;
- return TRUE;
+ return true;
}
}
@@ -109,11 +109,11 @@ CcuRegExp :: Match (const char* s)
{
if (Compiled != this)
if (!Compile ())
- return FALSE;
+ return false;
if (re_exec (s) == 1)
- return TRUE;
+ return true;
else
- return FALSE;
+ return false;
}
#endif /* RE_COMP */
@@ -130,27 +130,27 @@ extern "C" {
#endif
/*?
-Compile a regular expression before using it. This function returns FALSE upon failure,
-TRUE upon success.
+Compile a regular expression before using it. This function returns false upon failure,
+true upon success.
?*/
bool
CcuRegExp :: Compile ()
{
Compiled = regcmp (String, 0);
- return Compiled ? TRUE : FALSE;
+ return Compiled ? true : false;
}
/*?
-Match a string against a regular expression. This function returns FALSE upon failure,
-TRUE upon success.
+Match a string against a regular expression. This function returns false upon failure,
+true upon success.
?*/
bool
CcuRegExp :: Match (const char* s)
{
if (Compiled)
- return regex (Compiled, s) ? TRUE : FALSE;
+ return regex (Compiled, s) ? true : false;
else
- return FALSE;
+ return false;
}
/*?nodoc?*/
diff --git a/utils/bool.h b/utils/bool.h
index ec3b36d..67f2265 100644
--- a/utils/bool.h
+++ b/utils/bool.h
@@ -14,14 +14,14 @@
#ifndef _bool_h
#define _bool_h 1
-#if defined(TRUE)
-#undef TRUE
-#undef FALSE
+#if defined(true)
+#undef true
+#undef false
#endif
enum bool {
- TRUE = 1,
- FALSE = 0
+ true = 1,
+ false = 0
};
#endif /* _bool_h */
diff --git a/utils/doc.main b/utils/doc.main
index 364a939..5622ec3 100644
--- a/utils/doc.main
+++ b/utils/doc.main
@@ -414,14 +414,14 @@ const char* file1 = path.Find ("my_file");
const char* file2 = path.Find ("other_file");
/* file1 now refers to garbage */
-const char* file2 = path.Find ("other_file", TRUE);
+const char* file2 = path.Find ("other_file", true);
path.SetAlloc (1);
char* file3 = path.Find ("my_file");
FreeString (file1); // crash !
FreeString (file2); // safe
-FreeString (file3); // safe (default allocation now TRUE)
+FreeString (file3); // safe (default allocation now true)
\end{ccode}
\chapter{Regular expressions}