Package org.exist.dom

Source Code of org.exist.dom.DefaultDocumentSet

/*
*  eXist Open Source Native XML Database
*  Copyright (C) 2000-2012 The eXist Project
*  http://exist-db.org
*
*  This program is free software; you can redistribute it and/or
*  modify it under the terms of the GNU Lesser General Public License
*  as published by the Free Software Foundation; either version 2
*  of the License, or (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU Lesser General Public License for more details.
*
*  You should have received a copy of the GNU Lesser General Public
*  License along with this library; if not, write to the Free Software
*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*
*  $Id$
*/
package org.exist.dom;

import java.util.Arrays;
import java.util.BitSet;
import java.util.Iterator;
import java.util.TreeSet;

import org.exist.collections.Collection;
import org.exist.numbering.NodeId;
import org.exist.storage.DBBroker;
import org.exist.storage.lock.Lock;
import org.exist.util.LockException;
import org.exist.util.hashtable.Int2ObjectHashMap;
import org.exist.xmldb.XmldbURI;
import org.w3c.dom.Node;

/**
* Manages a set of documents.
*
* This class implements the NodeList interface for a collection of documents.
* It also contains methods to retrieve the collections these documents
* belong to.
*
* @author wolf
*/
public class DefaultDocumentSet extends Int2ObjectHashMap implements MutableDocumentSet {

    private BitSet docIds = new BitSet();
    private BitSet collectionIds = new BitSet();
    private TreeSet<Collection> collections = new TreeSet<Collection>();

    public DefaultDocumentSet() {
        super(29, 1.75);
    }

    public DefaultDocumentSet(int initialSize) {
        super(initialSize, 1.75);
    }

    @Override
    public void clear() {
        super.clear();
        docIds = new BitSet();
        collectionIds = new BitSet();
        collections = new TreeSet<Collection>();
    }

    @Override
    public void add(DocumentImpl doc) {
        add(doc, true);
    }

    @Override
    public void add(DocumentImpl doc, boolean checkDuplicates) {
        final int docId = doc.getDocId();
        if (checkDuplicates && contains(docId))
            {return;}
        docIds.set(docId);
        put(docId, doc);
        final Collection collection = doc.getCollection();
        if (collection != null) {
          if (!collectionIds.get(collection.getId())) {
            collectionIds.set(collection.getId());
              collections.add(collection);
          }
        }
    }

    public void add(Node node) {
        if (!(node instanceof DocumentImpl))
            {throw new RuntimeException("wrong implementation");}
        add((DocumentImpl) node);
    }

    @Override
    public void addAll(DocumentSet other) {
      for (final Iterator<DocumentImpl> i = other.getDocumentIterator(); i.hasNext(); ) {
        add(i.next());
      }
    }

    @Override
    public void addCollection(Collection collection) {
      if (!collectionIds.get(collection.getId())) {
        collectionIds.set(collection.getId());
        collections.add(collection);
      }
    }

    @Override
    public Iterator<DocumentImpl> getDocumentIterator() {
        return valueIterator();
    }

    @Override
    public Iterator<Collection> getCollectionIterator() {
        return collections.iterator();
    }

    @Override
    public int getDocumentCount() {
        return size();
    }

    public int getCollectionCount() {
        return collections.size();
    }

    @Override
    public DocumentImpl getDoc(int docId) {
        return (DocumentImpl) get(docId);
    }

    @Override
    public XmldbURI[] getNames() {
        final XmldbURI result[] = new XmldbURI[size()];
        DocumentImpl d;
        int j = 0;
        for (final Iterator<DocumentImpl> i = getDocumentIterator(); i.hasNext(); j++) {
            d = i.next();
            result[j] = d.getFileURI();
        }
        Arrays.sort(result);
        return result;
    }

    @Override
    public DocumentSet intersection(DocumentSet other) {
        final DefaultDocumentSet r = new DefaultDocumentSet();
        DocumentImpl d;
        for (final Iterator<DocumentImpl> i = getDocumentIterator(); i.hasNext();) {
            d = i.next();
            if (other.contains(d.getDocId()))
                {r.add(d);}
        }
        for (final Iterator<DocumentImpl> i = other.getDocumentIterator(); i.hasNext();) {
            d = i.next();
            if (contains(d.getDocId()) && (!r.contains(d.getDocId())))
                {r.add(d);}
        }
        return r;
    }

    public DocumentSet union(DocumentSet other) {
        final DefaultDocumentSet result = new DefaultDocumentSet();
        result.addAll(other);
        DocumentImpl d;
        for (final Iterator<DocumentImpl> i = getDocumentIterator(); i.hasNext();) {
            d = i.next();
            if (!result.contains(d.getDocId()))
                {result.add(d);}
        }
        return result;
    }

    @Override
    public boolean contains(DocumentSet other) {
        if (other.getDocumentCount() > size())
            {return false;}
        for (int idx = 0; idx < tabSize; idx++) {
            if(values[idx] == null || values[idx] == REMOVED)
                {continue;}
            final DocumentImpl d = (DocumentImpl) values[idx];
            if (!contains(d.getDocId()))
                {return false;}
        }
        return true;
    }

    @Override
    public boolean contains(int id) {
      return docIds.get(id);
    }

    @Override
    public NodeSet docsToNodeSet() {
        final NodeSet result = new NewArrayNodeSet(getDocumentCount());
        DocumentImpl doc;
        for (final Iterator<DocumentImpl> i = getDocumentIterator(); i.hasNext();) {
            doc = i.next();
            if(doc.getResourceType() == DocumentImpl.XML_FILE) {  // skip binary resources
                result.add(new NodeProxy(doc, NodeId.DOCUMENT_NODE));
            }
        }
        return result;
    }

    public int getMinDocId() {
        int min = DocumentImpl.UNKNOWN_DOCUMENT_ID;
        DocumentImpl d;
        for (final Iterator<DocumentImpl> i = getDocumentIterator(); i.hasNext();) {
            d = i.next();
            if (min == DocumentImpl.UNKNOWN_DOCUMENT_ID)
                {min = d.getDocId();}
            else if (d.getDocId() < min)
                {min = d.getDocId();}
        }
        return min;
    }

    public int getMaxDocId() {
        int max = DocumentImpl.UNKNOWN_DOCUMENT_ID;
        DocumentImpl d;
        for (final Iterator<DocumentImpl> i = getDocumentIterator(); i.hasNext();) {
            d = i.next();
            if (d.getDocId() > max)
                {max = d.getDocId();}
        }
        return max;
    }

    @Override
    public boolean equalDocs(DocumentSet other) {
        if (this == other)
            // we are comparing the same objects
            {return true;}
        if (size() != other.getDocumentCount())
            {return false;}
        for(int idx = 0; idx < tabSize; idx++) {
            if (values[idx] == null || values[idx] == REMOVED)
                {continue;}
            if (!other.contains(keys[idx]))
                {return false;}
        }
        return true;
    }

    @Override
    public void lock(DBBroker broker, boolean exclusive, boolean checkExisting) throws LockException {
        DocumentImpl d;
        Lock dlock;
        //final Thread thread = Thread.currentThread();
        for(int idx = 0; idx < tabSize; idx++) {
            if(values[idx] == null || values[idx] == REMOVED)
                {continue;}
            d = (DocumentImpl)values[idx];
            dlock = d.getUpdateLock();
            //if (checkExisting && dlock.hasLock(thread))
                //continue;
            if(exclusive)
                {dlock.acquire(Lock.WRITE_LOCK);}
            else
                {dlock.acquire(Lock.READ_LOCK);}
        }
    }

    @Override
    public void unlock(boolean exclusive) {
        DocumentImpl d;
        Lock dlock;
        final Thread thread = Thread.currentThread();
        for(int idx = 0; idx < tabSize; idx++) {
            if(values[idx] == null || values[idx] == REMOVED)
                {continue;}
            d = (DocumentImpl)values[idx];
            dlock = d.getUpdateLock();
            if(exclusive)
                {dlock.release(Lock.WRITE_LOCK);}
            else if (dlock.isLockedForRead(thread))
                {dlock.release(Lock.READ_LOCK);}
        }
    }

    @Override
    public String toString() {
        final StringBuilder result = new StringBuilder();
        for (final Iterator<DocumentImpl> i = getDocumentIterator(); i.hasNext(); ) {
            result.append(i.next());
            result.append(", ");
        }
        return result.toString();
    }
}
TOP

Related Classes of org.exist.dom.DefaultDocumentSet

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.