function getTraceUids(oldFullData, newData) {
    var len = newData.length;
    var oldFullInput = [];
    var i, prevFullInput;
    for(i = 0; i < oldFullData.length; i++) {
        var thisFullInput = oldFullData[i]._fullInput;
        if(thisFullInput !== prevFullInput) oldFullInput.push(thisFullInput);
        prevFullInput = thisFullInput;
    }
    var oldLen = oldFullInput.length;
    var out = new Array(len);
    var seenUids = {};

    function setUid(uid, i) {
        out[i] = uid;
        seenUids[uid] = 1;
    }

    function tryUid(uid, i) {
        if(uid && typeof uid === 'string' && !seenUids[uid]) {
            setUid(uid, i);
            return true;
        }
    }

    for(i = 0; i < len; i++) {
        var newUid = newData[i].uid;
        if(typeof newUid === 'number') newUid = String(newUid);

        if(tryUid(newUid, i)) continue;
        if(i < oldLen && tryUid(oldFullInput[i].uid, i)) continue;
        setUid(Lib.randstr(seenUids), i);
    }

    return out;
}
Create a list of uid strings satisfying (in this order of importance):
1. all unique, all strings
2. matches input uids if provided
3. matches previous data uids