tDOM

Check-in [4592100a23]
Login
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2019 Conference, Houston/TX, US, Nov 4-8
Send your abstracts to [email protected]
or submit via the online form by Sep 9.

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Save work.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | localkey
Files: files | file ages | folders
SHA3-256: 4592100a2369fcc6522bc5420849281a24c5498a6efce5ecc3f0f10b23f10407
User & Date: rolf 2019-05-18 00:41:39
Context
2019-05-21
22:37
Merged from schema. check-in: 72ce7820c1 user: rolf tags: localkey
2019-05-18
00:41
Save work. check-in: 4592100a23 user: rolf tags: localkey
2019-05-17
00:02
Now start to actually use the local key constraint info. check-in: 120c8294a0 user: rolf tags: localkey
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to generic/schema.c.

   255    255       if (cp->namespace) {                                \
   256    256           Tcl_SetStringObj (rObj, cp->namespace, -1);     \
   257    257           Tcl_AppendToObj (rObj, ":", 1);                 \
   258    258       }                                                   \
   259    259       Tcl_AppendToObj (rObj, cp->name, -1);
   260    260   
   261    261   #define S(str)  str, sizeof (str) -1
          262  +
          263  +#define getKeyState(ks) \
          264  +    if (sdata->keyStatePool) { \
          265  +        ks = sdata->keyStatePool; \
          266  +        sdata->keyStatePool = ks->next; \
          267  +    } else { \
          268  +        ks = TMALLOC (KeyState); \
          269  +    }
   262    270   
   263    271   static SchemaCP*
   264    272   initSchemaCP (
   265    273       Schema_CP_Type type,
   266    274       void *namespace,
   267    275       char *name
   268    276       )
................................................................................
   513    521       SchemaData *sdata = (SchemaData *) clientData;
   514    522       unsigned int i;
   515    523       SchemaValidationStack *down;
   516    524       Tcl_HashEntry *h;
   517    525       Tcl_HashSearch search;
   518    526       SchemaDocKey *dk;
   519    527       KeyState *ks, *nextks;
          528  +    KeyTable *kt, *nextkt;
   520    529   
   521    530       /* Protect the clientData to be freed inside (even nested)
   522    531        * Tcl_Eval*() calls to avoid invalid mem access and postpone the
   523    532        * cleanup until the Tcl_Eval*() calls are finished (done in
   524    533        * schemaInstanceCmd(). */
   525    534       if (sdata->currentEvals) {
   526    535           sdata->cleanupAfterEval = 1;
................................................................................
   581    590           Tcl_DeleteHashTable (&dk->ids);
   582    591           FREE (dk);
   583    592       }
   584    593       Tcl_DeleteHashTable (&sdata->idTables);
   585    594       ks = sdata->keyStatePool;
   586    595       while (ks) {
   587    596           nextks = ks->next;
   588         -        FREE (ks->values);
   589    597           FREE (ks);
   590    598           ks = nextks;
          599  +    }
          600  +    kt = sdata->keyTablePool;
          601  +    while (kt) {
          602  +        nextkt = kt->next;
          603  +        FREE (kt);
          604  +        kt = nextkt;
   591    605       }
   592    606       FREE (sdata);
   593    607   }
   594    608   
   595    609   static void
   596    610   cleanupLastPattern (
   597    611       SchemaData *sdata,
................................................................................
   742    756   pushToStack (
   743    757       SchemaData *sdata,
   744    758       SchemaCP *pattern
   745    759       )
   746    760   {
   747    761       SchemaValidationStack *stackElm, *se;
   748    762       KeyConstraint *kc;
   749         -    KeyState *ks;
          763  +    KeyState *ks, *newks;
          764  +    KeyTable *kt;
   750    765       
   751    766       DBG(fprintf(stderr, "push to Stack:\n");serializeCP(pattern));
   752    767       if (sdata->stackPool) {
   753    768           stackElm = sdata->stackPool;
   754    769           sdata->stackPool = stackElm->down;
   755    770       } else {
   756    771           stackElm = TMALLOC (SchemaValidationStack);
................................................................................
   759    774       se = sdata->stack;
   760    775       stackElm->down = se;
   761    776       stackElm->pattern = pattern;
   762    777       if (pattern->type == SCHEMA_CTYPE_INTERLEAVE) {
   763    778           stackElm->interleaveState = MALLOC (sizeof (int) * pattern->nc);
   764    779           memset (stackElm->interleaveState, 0, sizeof (int) * pattern->nc);
   765    780       }
   766         -    if (pattern->type == SCHEMA_CTYPE_NAME) {
          781  +    if (pattern->type == SCHEMA_CTYPE_NAME && se) {
   767    782           /* Handle local key contraint matches */
   768         -
          783  +        ks = se->keyState;
          784  +        while (ks) {
          785  +            if (ks->selector->name != pattern->name
          786  +                || ks->selector->ns == pattern->namespace) continue;
          787  +            if (ks->selector->child) {
          788  +                getKeyState(newks);
          789  +                newks->keyTable = ks->keyTable;
          790  +                newks->ownTable = 0;
          791  +                newks->selector = ks->selector->child;
          792  +                newks->fields = ks->fields;
          793  +                if (ks->type == SCHEMA_STEP_DESCENDANT_ELEMENT) {
          794  +                    
          795  +                }
          796  +                newks->next = stackElm->keyState;
          797  +                stackElm->keyState = newks;
          798  +            } else {
          799  +                /* Selector has matched, grab the fields */
          800  +            }
          801  +        }
          802  +        
   769    803           /* And open new local key contraints, if necessary. */
   770    804           kc = pattern->localkeys;
   771    805           while (kc) {
   772         -            if (sdata->keyStatePool) {
   773         -                ks = sdata->keyStatePool;
   774         -                sdata->keyStatePool = ks->next;
          806  +            getKeyState (ks);
          807  +            if (sdata->keyTablePool) {
          808  +                kt = sdata->keyTablePool;
          809  +                sdata->keyTablePool = kt->next;
   775    810               } else {
   776         -                ks = TMALLOC (KeyState);
   777         -                ks->values = TMALLOC (Tcl_HashTable);
          811  +                kt = TMALLOC (KeyTable);
   778    812               }
   779         -            Tcl_InitHashTable (ks->values, TCL_STRING_KEYS);
          813  +            Tcl_InitHashTable (&kt->values, TCL_STRING_KEYS);
          814  +            ks->keyTable = kt;
          815  +            ks->ownTable = 1;
          816  +            ks->type = kc->type;
   780    817               ks->selector = kc->selector;
   781    818               ks->fields = kc->fields;
   782    819               ks->next = stackElm->keyState;
   783    820               stackElm->keyState = ks;
   784    821               kc = kc->next;
   785    822           }
   786    823       }
................................................................................
   800    837           sdata->stack->interleaveState = NULL;
   801    838       }
   802    839       if (sdata->stack->pattern->type == SCHEMA_CTYPE_NAME) {
   803    840           /* Check and cleanup local key contraints */
   804    841           ks = sdata->stack->keyState;
   805    842           while (ks) {
   806    843               nextks = ks->next;
   807         -            Tcl_DeleteHashTable (ks->values);
   808         -            if (sdata->keyStatePool) {
   809         -                ks->next = sdata->keyStatePool;
   810         -            } else {
   811         -                ks->next = NULL;
          844  +            if (ks->ownTable) {
          845  +                ks->keyTable->next = sdata->keyTablePool;
          846  +                sdata->keyTablePool = ks->keyTable;
          847  +                Tcl_DeleteHashTable (&ks->keyTable->values);
   812    848               }
          849  +            ks->next = sdata->keyStatePool;
   813    850               sdata->keyStatePool = ks;
   814    851               ks = nextks;
   815    852           }
   816    853       }
   817    854       se = sdata->stack->down;
   818    855       sdata->stack->down = sdata->stackPool;
   819    856       sdata->stackPool = sdata->stack;

Changes to generic/schema.h.

    99     99       char     *name;
   100    100       KeyType   type;
   101    101       KeyStep  *selector;
   102    102       KeyStep **fields;
   103    103       int       nrFields;
   104    104       struct KeyConstraint *next;
   105    105   } KeyConstraint;
          106  +
          107  +typedef struct KeyTable {
          108  +    struct KeyTable *next;
          109  +    Tcl_HashTable    values;
          110  +} KeyTable;
   106    111   
   107    112   typedef struct KeyState 
   108    113   {
   109    114       struct KeyState *next;
          115  +    StepType         type;
   110    116       KeyStep         *selector;
   111    117       KeyStep        **fields;
   112         -    Tcl_HashTable   *values;
          118  +    int              ownTable;
          119  +    KeyTable        *keyTable;
   113    120   } KeyState;
   114    121   
   115    122   typedef struct SchemaCP
   116    123   {
   117    124       Schema_CP_Type    type;
   118    125       char             *namespace;
   119    126       char             *name;
................................................................................
   188    195       SchemaAttr **currentAttrs;
   189    196       unsigned int numAttr;
   190    197       unsigned int numReqAttr;
   191    198       unsigned int attrSize;
   192    199       SchemaValidationStack *stack;
   193    200       SchemaValidationStack *stackPool;
   194    201       KeyState *keyStatePool;
          202  +    KeyTable *keyTablePool;
   195    203       ValidationState validationState;
   196    204       unsigned int skipDeep;
   197    205       Tcl_DString *cdata;
   198    206       Tcl_HashTable ids;
   199    207       int unknownIDrefs;
   200    208       Tcl_HashTable idTables;
   201    209   } SchemaData;