Example #1
0
extern int
SyncTreeMarkReachable(struct SyncTreeWorkerHead *head, int minLevel) {
    int count = 0;
    while (head->level > minLevel) {
        struct SyncTreeWorkerEntry *ent = SyncTreeWorkerTop(head);
        if (ent == NULL) break;
        struct SyncHashCacheEntry *ce = ent->cacheEntry;
        if (ce == NULL) break;
        ce->state |= SyncHashState_marked;
        count++;
        struct SyncNodeComposite *nc = ((head->remote > 0) ? ce->ncR : ce->ncL);
        if (nc == NULL) break;
        int lim = nc->refLen;
        if (ent->pos >= lim) {
            // done with the current level, go back to the previous level
            ent = SyncTreeWorkerPop(head);
            if (ent == NULL) break;
            ent->pos++;
        } else {
            struct SyncNodeElem *ep = &nc->refs[ent->pos];
            if (ep->kind & SyncElemKind_leaf) {
                // a leaf, so skip it
                ent->pos++;
            } else {
                // a node, so push into it
                ent = SyncTreeWorkerPush(head);
                if (ent == NULL) break;
            }
        }
    }
    return count;
}
Example #2
0
extern enum SyncCompareResult
SyncTreeLookupName(struct SyncTreeWorkerHead *head,
                   struct ccn_charbuf *name,
                   int minLevel) {
    
    enum SyncCompareResult cr = SCR_inside;
    while (head->level > minLevel) {
        struct SyncTreeWorkerEntry *ent = SyncTreeWorkerTop(head);
        if (ent->cacheEntry == NULL) {
            // probably a real bug!
            return SCR_error;
        }
        struct SyncHashCacheEntry *ce = ent->cacheEntry;
        struct SyncNodeComposite *nc = ((head->remote > 0) ? ce->ncR : ce->ncL);
        if (nc == NULL) {
            // report desired node as missing
            return SCR_missing;
        }
        int lim = nc->refLen;
        if (ent->pos >= lim) {
            // done with the current level, go back to the previous level
            ent = SyncTreeWorkerPop(head);
            if (ent == NULL) break;
            ent->pos++;
        } else {
            
            if (ent->pos == 0) {
                // need to check the min and max of the current node
                enum SyncCompareResult cr = SyncNodeCompareMinMax(nc, name);
                if (cr == SCR_after) {
                    // not in this node at all, so pop out
                    ent->pos = lim;
                } else if (cr != SCR_inside) return cr;
            }
            if (ent->pos < lim) {
                struct SyncNodeElem *ep = &nc->refs[ent->pos];
                if (ep->kind & SyncElemKind_leaf) {
                    // a leaf, so the element name is inline
                    cr = SyncNodeCompareLeaf(nc, ep, name);
                    if (cr != SCR_after) return cr;
                    ent->pos++;
                } else {
                    // a node, so try this recursively
                    ent = SyncTreeWorkerPush(head);
                    if (ent == NULL) {
                        return SCR_error;
                    }
                }
            }
        }
        
    }
    return SCR_after;
}
Example #3
0
extern enum SyncCompareResult
SyncTreeGenerateNames(struct SyncTreeWorkerHead *head,
                      struct SyncNameAccum *accum,
                      int minLevel) {
    
    while (head->level > minLevel) {
        struct SyncTreeWorkerEntry *ent = SyncTreeWorkerTop(head);
        if (ent->cacheEntry == NULL) {
            // probably a real bug!
            return SCR_error;
        }
        struct SyncHashCacheEntry *ce = ent->cacheEntry;
        struct SyncNodeComposite *nc = ((head->remote > 0) ? ce->ncR : ce->ncL);
        if (nc == NULL) {
            // TBD: fetch node if not present
            return SCR_missing;
        }
        int lim = nc->refLen;
        if (ent->pos >= lim) {
            // done with the current level, go back to the previous level
            ent = SyncTreeWorkerPop(head);
            if (ent == NULL) break;
            ent->pos++;
        } else {
            struct SyncNodeElem *ep = &nc->refs[ent->pos];
            if (ep->kind & SyncElemKind_leaf) {
                // a leaf, so the element name is inline
                struct ccn_buf_decoder bd;
                struct ccn_buf_decoder *d = SyncInitDecoderFromOffset(&bd,
                                                                      nc,
                                                                      ep->start,
                                                                      ep->stop);
                struct ccn_charbuf *cb = ccn_charbuf_create();
                int res = SyncAppendElementInner(cb, d);
                if (res < 0) {
                    // that did not work well
                    ccn_charbuf_destroy(&cb);
                    return SCR_error;
                }
                SyncNameAccumAppend(accum, cb, 0);
                ent->pos++;
            } else {
                ent = SyncTreeWorkerPush(head);
                if (ent == NULL) {
                    return SCR_error;
                }                
            }
        }
        
    }
    return SCR_after;
}
Example #4
0
int
BuildTree(struct SyncUpdateData *ud,
          struct SyncTreeWorkerHead *tw,
          struct SyncNameAccum *src) {
    int res = 0;
    while (res == 0) {
        struct SyncTreeWorkerEntry *ent = SyncTreeWorkerTop(tw);
        if (ent == NULL) break;
        struct SyncHashCacheEntry *ce = ent->cacheEntry;
        if (ce == NULL)
            // no cache entry, so bad news
            return -__LINE__;
        struct SyncNodeComposite *nc = CacheEntryFetch(ud, ce);
        if (nc == NULL) {
            if (ce->state & SyncHashState_fetching)
                // can't process this node now, it's being fetched
                return 0;
            return -__LINE__;
        }
        struct ccn_charbuf *name = BestName(ud);
        enum SyncCompareResult scr = SyncNodeCompareMinMax(nc, name);
        switch (scr) {
            case SCR_before:
                // name < Min(L), so add name, advance names
                UpdateAddName(ud, name);
                AdvanceName(ud);
                break;
            case SCR_min:
                // name == Min(L), advance names
                AdvanceName(ud);
                break;
            case SCR_max:
                // R == Max(L), discard R, advance both
                ent->pos++;
                AdvanceName(ud);
                break;
            case SCR_after:
                // R > Max(L), advance L
                AcceptNode(ud);
                break;
            case SCR_inside:
                // Min(L) < R < Max(L), so dive into L
                if (SyncTreeWorkerPush(tw) == NULL)
                    return - __LINE__;
                break;
            default:
                // this is really broken
                return -__LINE__;
        }
    }
}