tDOM

Check-in [120c8294a0]
Login

Check-in [120c8294a0]

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

Overview
Comment:Now start to actually use the local key constraint info.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | localkey
Files: files | file ages | folders
SHA3-256: 120c8294a03dda1c21e96db6c03bc452f17f5e7418a5798a1c32aa034659d952
User & Date: rolf 2019-05-17 00:02:41.302
Context
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
2019-05-16
22:25
Still working on digest local key constraint specification: Now support union "Path ( '|' Path )*" for selector and fields. Distinct between element and attribute selecting steps because of the distict spaces of the names. check-in: 69c262ef77 user: rolf tags: localkey
Changes
Unified Diff Ignore Whitespace Patch
Changes to generic/schema.c.
512
513
514
515
516
517
518

519
520
521
522
523
524
525
{
    SchemaData *sdata = (SchemaData *) clientData;
    unsigned int i;
    SchemaValidationStack *down;
    Tcl_HashEntry *h;
    Tcl_HashSearch search;
    SchemaDocKey *dk;


    /* Protect the clientData to be freed inside (even nested)
     * Tcl_Eval*() calls to avoid invalid mem access and postpone the
     * cleanup until the Tcl_Eval*() calls are finished (done in
     * schemaInstanceCmd(). */
    if (sdata->currentEvals) {
        sdata->cleanupAfterEval = 1;







>







512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
{
    SchemaData *sdata = (SchemaData *) clientData;
    unsigned int i;
    SchemaValidationStack *down;
    Tcl_HashEntry *h;
    Tcl_HashSearch search;
    SchemaDocKey *dk;
    KeyState *ks, *nextks;

    /* Protect the clientData to be freed inside (even nested)
     * Tcl_Eval*() calls to avoid invalid mem access and postpone the
     * cleanup until the Tcl_Eval*() calls are finished (done in
     * schemaInstanceCmd(). */
    if (sdata->currentEvals) {
        sdata->cleanupAfterEval = 1;
577
578
579
580
581
582
583







584
585
586
587
588
589
590
         h != NULL;
         h = Tcl_NextHashEntry (&search)) {
        dk = Tcl_GetHashValue (h);
        Tcl_DeleteHashTable (&dk->ids);
        FREE (dk);
    }
    Tcl_DeleteHashTable (&sdata->idTables);







    FREE (sdata);
}

static void
cleanupLastPattern (
    SchemaData *sdata,
    unsigned int from







>
>
>
>
>
>
>







578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
         h != NULL;
         h = Tcl_NextHashEntry (&search)) {
        dk = Tcl_GetHashValue (h);
        Tcl_DeleteHashTable (&dk->ids);
        FREE (dk);
    }
    Tcl_DeleteHashTable (&sdata->idTables);
    ks = sdata->keyStatePool;
    while (ks) {
        nextks = ks->next;
        FREE (ks->values);
        FREE (ks);
        ks = nextks;
    }
    FREE (sdata);
}

static void
cleanupLastPattern (
    SchemaData *sdata,
    unsigned int from
733
734
735
736
737
738
739


740
741
742
743
744
745
746
747
748
749
750
751
752
753
754





















755
756
757
758
759
760
761
762
763
764

765
766
767
768















769
770
771
772
773
774
775
static void
pushToStack (
    SchemaData *sdata,
    SchemaCP *pattern
    )
{
    SchemaValidationStack *stackElm, *se;



    DBG(fprintf(stderr, "push to Stack:\n");serializeCP(pattern));
    if (sdata->stackPool) {
        stackElm = sdata->stackPool;
        sdata->stackPool = stackElm->down;
    } else {
        stackElm = TMALLOC (SchemaValidationStack);
    }
    memset (stackElm, 0, sizeof (SchemaValidationStack));
    se = sdata->stack;
    stackElm->down = se;
    stackElm->pattern = pattern;
    if (pattern->type == SCHEMA_CTYPE_INTERLEAVE) {
        stackElm->interleaveState = MALLOC (sizeof (int) * pattern->nc);
        memset (stackElm->interleaveState, 0, sizeof (int) * pattern->nc);





















    }
    sdata->stack = stackElm;
}

static void
popStack (
    SchemaData *sdata
    )
{
    SchemaValidationStack *se;

    DBG(fprintf(stderr, "pop from Stack:\n");serializeCP(sdata->stack->pattern));
    if (sdata->stack->interleaveState) {
        FREE (sdata->stack->interleaveState);
        sdata->stack->interleaveState = NULL;















    }
    se = sdata->stack->down;
    sdata->stack->down = sdata->stackPool;
    sdata->stackPool = sdata->stack;
    sdata->stack = se;
}








>
>
|














>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>










>




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
static void
pushToStack (
    SchemaData *sdata,
    SchemaCP *pattern
    )
{
    SchemaValidationStack *stackElm, *se;
    KeyConstraint *kc;
    KeyState *ks;
    
    DBG(fprintf(stderr, "push to Stack:\n");serializeCP(pattern));
    if (sdata->stackPool) {
        stackElm = sdata->stackPool;
        sdata->stackPool = stackElm->down;
    } else {
        stackElm = TMALLOC (SchemaValidationStack);
    }
    memset (stackElm, 0, sizeof (SchemaValidationStack));
    se = sdata->stack;
    stackElm->down = se;
    stackElm->pattern = pattern;
    if (pattern->type == SCHEMA_CTYPE_INTERLEAVE) {
        stackElm->interleaveState = MALLOC (sizeof (int) * pattern->nc);
        memset (stackElm->interleaveState, 0, sizeof (int) * pattern->nc);
    }
    if (pattern->type == SCHEMA_CTYPE_NAME) {
        /* Handle local key contraint matches */

        /* And open new local key contraints, if necessary. */
        kc = pattern->localkeys;
        while (kc) {
            if (sdata->keyStatePool) {
                ks = sdata->keyStatePool;
                sdata->keyStatePool = ks->next;
            } else {
                ks = TMALLOC (KeyState);
                ks->values = TMALLOC (Tcl_HashTable);
            }
            Tcl_InitHashTable (ks->values, TCL_STRING_KEYS);
            ks->selector = kc->selector;
            ks->fields = kc->fields;
            ks->next = stackElm->keyState;
            stackElm->keyState = ks;
            kc = kc->next;
        }
    }
    sdata->stack = stackElm;
}

static void
popStack (
    SchemaData *sdata
    )
{
    SchemaValidationStack *se;
    KeyState *ks, *nextks;
    DBG(fprintf(stderr, "pop from Stack:\n");serializeCP(sdata->stack->pattern));
    if (sdata->stack->interleaveState) {
        FREE (sdata->stack->interleaveState);
        sdata->stack->interleaveState = NULL;
    }
    if (sdata->stack->pattern->type == SCHEMA_CTYPE_NAME) {
        /* Check and cleanup local key contraints */
        ks = sdata->stack->keyState;
        while (ks) {
            nextks = ks->next;
            Tcl_DeleteHashTable (ks->values);
            if (sdata->keyStatePool) {
                ks->next = sdata->keyStatePool;
            } else {
                ks->next = NULL;
            }
            sdata->keyStatePool = ks;
            ks = nextks;
        }
    }
    se = sdata->stack->down;
    sdata->stack->down = sdata->stackPool;
    sdata->stackPool = sdata->stack;
    sdata->stack = se;
}

Changes to generic/schema.h.
99
100
101
102
103
104
105








106
107
108
109
110
111
112
    char     *name;
    KeyType   type;
    KeyStep  *selector;
    KeyStep **fields;
    int       nrFields;
    struct KeyConstraint *next;
} KeyConstraint;









typedef struct SchemaCP
{
    Schema_CP_Type    type;
    char             *namespace;
    char             *name;
    struct SchemaCP  *next;







>
>
>
>
>
>
>
>







99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
    char     *name;
    KeyType   type;
    KeyStep  *selector;
    KeyStep **fields;
    int       nrFields;
    struct KeyConstraint *next;
} KeyConstraint;

typedef struct KeyState 
{
    struct KeyState *next;
    KeyStep         *selector;
    KeyStep        **fields;
    Tcl_HashTable   *values;
} KeyState;

typedef struct SchemaCP
{
    Schema_CP_Type    type;
    char             *namespace;
    char             *name;
    struct SchemaCP  *next;
125
126
127
128
129
130
131

132
133
134
135
136
137
138
{
    SchemaCP *pattern;
    struct SchemaValidationStack *next;
    struct SchemaValidationStack *down;
    int               activeChild;
    int               hasMatched;
    int              *interleaveState;

} SchemaValidationStack;

typedef enum {
    VALIDATION_READY,
    VALIDATION_STARTED,
    VALIDATION_ERROR,
    VALIDATION_FINISHED







>







133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
{
    SchemaCP *pattern;
    struct SchemaValidationStack *next;
    struct SchemaValidationStack *down;
    int               activeChild;
    int               hasMatched;
    int              *interleaveState;
    KeyState         *keyState;
} SchemaValidationStack;

typedef enum {
    VALIDATION_READY,
    VALIDATION_STARTED,
    VALIDATION_ERROR,
    VALIDATION_FINISHED
178
179
180
181
182
183
184

185
186
187
188
189
190
191
    unsigned int contentSize;
    SchemaAttr **currentAttrs;
    unsigned int numAttr;
    unsigned int numReqAttr;
    unsigned int attrSize;
    SchemaValidationStack *stack;
    SchemaValidationStack *stackPool;

    ValidationState validationState;
    unsigned int skipDeep;
    Tcl_DString *cdata;
    Tcl_HashTable ids;
    int unknownIDrefs;
    Tcl_HashTable idTables;
} SchemaData;







>







187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
    unsigned int contentSize;
    SchemaAttr **currentAttrs;
    unsigned int numAttr;
    unsigned int numReqAttr;
    unsigned int attrSize;
    SchemaValidationStack *stack;
    SchemaValidationStack *stackPool;
    KeyState *keyStatePool;
    ValidationState validationState;
    unsigned int skipDeep;
    Tcl_DString *cdata;
    Tcl_HashTable ids;
    int unknownIDrefs;
    Tcl_HashTable idTables;
} SchemaData;