Inserts a data instance at the specified PRE value. Notes: The data instance in the specified data clip must differ from this instance. Attributes must be inserted via #insertAttr. @param pre target PRE value (insertion position) @param par target parent PR
(final int pre, final int par, final DataClip source)
| 737 | * @param source clip with source data |
| 738 | */ |
| 739 | public final void insert(final int pre, final int par, final DataClip source) { |
| 740 | final int sCount = source.size(); |
| 741 | if(sCount == 0) return; |
| 742 | |
| 743 | meta.update(); |
| 744 | resources.docs(); |
| 745 | |
| 746 | // resize buffer to cache more entries |
| 747 | final int bSize = Math.min(sCount, IO.ENTRIES); |
| 748 | bufferSize(bSize); |
| 749 | |
| 750 | // organize namespaces to avoid duplicate declarations |
| 751 | final NSScope nsScope = new NSScope(pre, this); |
| 752 | |
| 753 | // indicates if database only contains a dummy node |
| 754 | final Data sdata = source.data; |
| 755 | int c = 0, sTopPre = source.start; |
| 756 | for(int sPre = sTopPre; sPre < source.end; ++sPre, ++c) { |
| 757 | if(c != 0 && c % bSize == 0) insert(pre + c - bSize); |
| 758 | |
| 759 | // values of source node |
| 760 | final int sKind = sdata.kind(sPre); |
| 761 | final int sSize = sdata.size(sPre, sKind); |
| 762 | final int sPar = sdata.parent(sPre, sKind); |
| 763 | |
| 764 | // PRE and DIST value of new node |
| 765 | final int nPre = pre + c, nDist; |
| 766 | if(sPre == sTopPre) { |
| 767 | // handle top level entry: calculate distance based on target database |
| 768 | nDist = nPre - par; |
| 769 | // calculate PRE value of next top level entry |
| 770 | sTopPre += sSize; |
| 771 | } else { |
| 772 | // handle descendant node: calculate distance based on source database |
| 773 | nDist = sPre - sPar; |
| 774 | } |
| 775 | // documents: use -1 as namespace root |
| 776 | final int nsPre = sKind == DOC ? -1 : nPre - nDist; |
| 777 | nsScope.loop(nsPre, c); |
| 778 | |
| 779 | switch(sKind) { |
| 780 | case DOC: |
| 781 | // add document |
| 782 | nsScope.open(nPre); |
| 783 | doc(sSize, sdata.text(sPre, true)); |
| 784 | ++meta.ndocs; |
| 785 | break; |
| 786 | case ELEM: { |
| 787 | // add element. |
| 788 | final boolean nsFlag = nsScope.open(nPre, sdata.namespaces(sPre)); |
| 789 | final byte[] name = sdata.name(sPre, sKind); |
| 790 | elem(nDist, elemNames.put(name), sdata.attSize(sPre, sKind), sSize, |
| 791 | nspaces.uriIdForPrefix(prefix(name), true), nsFlag); |
| 792 | break; |
| 793 | } |
| 794 | case TEXT: |
| 795 | case COMM: |
| 796 | case PI: |