Package cx.fbn.nevernote.threads

Source Code of cx.fbn.nevernote.threads.IndexRunner

/*
* This file is part of NixNote
* Copyright 2009 Randy Baumgarte
*
* This file may be licensed under the terms of of the
* GNU General Public License Version 2 (the ``GPL'').
*
* Software distributed under the License is distributed
* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the GPL for the specific language
* governing rights and limitations.
*
* You should have received a copy of the GPL along with this
* program. If not, go to http://www.gnu.org/licenses/gpl.html
* or write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/

package cx.fbn.nevernote.threads;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.TreeSet;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.locks.LockSupport;

import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.tika.exception.TikaException;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.parser.ParseContext;
import org.apache.tika.parser.microsoft.OfficeParser;
import org.apache.tika.parser.microsoft.ooxml.OOXMLParser;
import org.apache.tika.parser.odf.OpenDocumentParser;
import org.apache.tika.parser.pdf.PDFParser;
import org.apache.tika.parser.rtf.RTFParser;
import org.apache.tika.sax.BodyContentHandler;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;

import com.evernote.edam.type.Data;
import com.evernote.edam.type.Note;
import com.evernote.edam.type.Resource;
import com.trolltech.qt.core.QByteArray;
import com.trolltech.qt.core.QIODevice.OpenModeFlag;
import com.trolltech.qt.core.QObject;
import com.trolltech.qt.core.QTemporaryFile;
import com.trolltech.qt.xml.QDomDocument;
import com.trolltech.qt.xml.QDomElement;
import com.trolltech.qt.xml.QDomNodeList;

import cx.fbn.nevernote.Global;
import cx.fbn.nevernote.signals.IndexSignal;
import cx.fbn.nevernote.signals.NoteResourceSignal;
import cx.fbn.nevernote.signals.NoteSignal;
import cx.fbn.nevernote.sql.DatabaseConnection;
import cx.fbn.nevernote.utilities.ApplicationLogger;

public class IndexRunner extends QObject implements Runnable {
 
  private final ApplicationLogger   logger;
  private String             guid;
  private QByteArray          resourceBinary;
  public volatile NoteSignal       noteSignal;
  public volatile NoteResourceSignal  resourceSignal;
  private int              indexType;
  public final int          SCAN=1;
  public final int          REINDEXALL=2;
  public final int          REINDEXNOTE=3;
  public boolean            keepRunning;
  private final QDomDocument      doc;
  private static String        regex = Global.getWordRegex();
  public String            specialIndexCharacters = "";
  public boolean            indexNoteBody = true;
  public boolean            indexNoteTitle = true;
  public boolean            indexImageRecognition = true;
  private final DatabaseConnection  conn;
  private volatile LinkedBlockingQueue<String> workQueue;
  private static int MAX_QUEUED_WAITING = 1000;
  public boolean interrupt;
  public boolean idle;
  public boolean indexAttachmentsLocally = true;
  public volatile IndexSignal      signal;
  private final TreeSet<String>    foundWords;
  int uncommittedCount = 0;

 
  public IndexRunner(String logname, String u, String i, String r, String uid, String pswd, String cpswd) {
    foundWords = new TreeSet<String>();
    logger = new ApplicationLogger(logname);
    conn = new DatabaseConnection(logger, u, i, r, uid, pswd, cpswd, 500);
    indexType = SCAN;
    guid = null;
    keepRunning = true;
    doc = new QDomDocument();
    workQueue=new LinkedBlockingQueue<String>(MAX_QUEUED_WAITING)
  }
 
  public void setIndexType(int t) {
    indexType = t;
  }
 
 
  @Override
  public void run() {
    thread().setPriority(Thread.MIN_PRIORITY);
    noteSignal = new NoteSignal();
    resourceSignal = new NoteResourceSignal();
    signal = new IndexSignal();
    logger.log(logger.EXTREME, "Starting index thread ");
    while (keepRunning) {
      idle=true;
      try {
        conn.commitTransaction();
        uncommittedCount = 0;
        String work = workQueue.take();
        idle=false;
        if (work.startsWith("SCAN")) {
          guid=null;
          interrupt = false;
          indexType = SCAN;
        }
        if (work.startsWith("REINDEXALL")) {
          guid = null;
          indexType=REINDEXALL;
        }
        if (work.startsWith("REINDEXNOTE")) {
          work = work.replace("REINDEXNOTE ", "");
          guid = work;
          indexType = REINDEXNOTE;
        }
        if (work.startsWith("STOP")) {
          keepRunning = false;
          guid = null;
        }
        logger.log(logger.EXTREME, "Type:" +indexType);
        if (indexType == SCAN && keepRunning) {
          logger.log(logger.MEDIUM, "Scanning for unindexed notes & resources");
          scanUnindexed();
          setIndexType(0);
        }
        if (indexType == REINDEXALL && keepRunning) {
          logger.log(logger.MEDIUM, "Marking all for reindex");
          reindexAll();
          setIndexType(0);
        }
        if (indexType == REINDEXNOTE && keepRunning) {
          reindexNote();
        }
      } catch (InterruptedException e) {
        logger.log(logger.LOW, "Thread interrupted exception: " +e.getMessage());
      }
    }
    logger.log(logger.EXTREME, "Shutting down database");
    conn.dbShutdown();
    logger.log(logger.EXTREME, "Database shut down.  Exiting thread");
  }
 
  // Reindex a note
  public void indexNoteContent() {
    foundWords.clear();
   
    logger.log(logger.EXTREME, "Entering indexRunner.indexNoteContent()");
   
    logger.log(logger.EXTREME, "Getting note content");
    Note n = conn.getNoteTable().getNote(guid,true,false,true,true, true);
    String data;
    if (indexNoteBody) {
      data = n.getContent();
      data = conn.getNoteTable().getNoteContentNoUTFConversion(n.getGuid());
   
      logger.log(logger.EXTREME, "Removing any encrypted data");
      data = removeEnCrypt(data.toString());
      logger.log(logger.EXTREME, "Removing xml markups");
    } else
      data = "";
    String text;
    if (indexNoteTitle)
      text =  removeTags(StringEscapeUtils.unescapeHtml4(data) +" "+ n.getTitle());
    else
      text = removeTags(StringEscapeUtils.unescapeHtml4(data));
       
    logger.log(logger.EXTREME, "Splitting words");
    String[] result = text.toString().split(regex);
    conn.commitTransaction();
    conn.beginTransaction();
    logger.log(logger.EXTREME, "Deleting existing words for note from index");
    conn.getWordsTable().expungeFromWordIndex(guid, "CONTENT");
   
    logger.log(logger.EXTREME, "Number of words found: " +result.length);
    for (int j=0; j<result.length && keepRunning; j++) {
      if (interrupt) {
        processInterrupt();
      }
      if (!result[j].trim().equals("")) {
        logger.log(logger.EXTREME, "Result word: " +result[j].trim());
        addToIndex(guid, result[j], "CONTENT");
      }
    }
   
    // Add tags
    for (int j=0; j<n.getTagNamesSize(); j++) {
      if (n.getTagNames() != null && n.getTagNames().get(j) != null && !n.getTagNames().get(j).trim().equals(""))
        addToIndex(guid, n.getTagNames().get(j), "CONTENT");
    }
   
    // If we were interrupted, we will reindex this note next time
    if (Global.keepRunning) {
      logger.log(logger.EXTREME, "Resetting note guid needed");
      conn.getNoteTable().setIndexNeeded(guid, false);
    }
    conn.commitTransaction();
    uncommittedCount = 0;
    logger.log(logger.EXTREME, "Leaving indexRunner.indexNoteContent()");
  }
 
 
  private String removeTags(String text) {
    StringBuffer buffer = new StringBuffer(text);
    boolean inTag = false;
    for (int i=buffer.length()-1; i>=0; i--) {
      if (buffer.charAt(i) == '>')
        inTag = true;
      if (buffer.charAt(i) == '<')
        inTag = false;
      if (inTag || buffer.charAt(i) == '<')
        buffer.deleteCharAt(i);
    }
   
    return buffer.toString();
  }

 
  public synchronized boolean addWork(String request) {
    if (workQueue.size() == 0) {
      workQueue.offer(request);
      return true;
    }
    return false;
  }
 
  public synchronized int getWorkQueueSize() {
    return workQueue.size();
  }
 
  public void indexResource() {
   
    if (guid == null)
      return;
    foundWords.clear();
    Resource r = conn.getNoteTable().noteResourceTable.getNoteResourceRecognition(guid);
    if (!indexImageRecognition ||
        r == null || r.getRecognition() == null ||
        r.getRecognition().getBody() == null ||
        r.getRecognition().getBody().length == 0)
      resourceBinary = new QByteArray(" ");
    else
      resourceBinary = new QByteArray(r.getRecognition().getBody());
   
    conn.commitTransaction();
    conn.beginTransaction();
    conn.getWordsTable().expungeFromWordIndex(r.getNoteGuid(), "RESOURCE");
    // This is due to an old bug & can be removed at some point in the future 11/23/2010
    conn.getWordsTable().expungeFromWordIndex(guid, "RESOURCE");  
    conn.commitTransaction();
    uncommittedCount = 0;
    conn.beginTransaction();
     
    doc.setContent(resourceBinary);
    QDomElement docElem = doc.documentElement();
     
    // look for text tags
    QDomNodeList anchors = docElem.elementsByTagName("t");
    for (int i=0; i<anchors.length() && keepRunning; i++) {
      if (interrupt) {
        if (interrupt) {
          processInterrupt();
        }
      }
      QDomElement enmedia = anchors.at(i).toElement();
      String weight = new String(enmedia.attribute("w"));
      String text = new String(enmedia.text()).toLowerCase();
      if (!text.equals("")) {
        conn.getWordsTable().addWordToNoteIndex(r.getNoteGuid(), text, "RESOURCE", new Integer(weight));
        uncommittedCount++;
        if (uncommittedCount > 100) {
          conn.commitTransaction();
          uncommittedCount=0;
        }
      }
    }
   
    if (Global.keepRunning && indexAttachmentsLocally) {
      conn.commitTransaction();
      uncommittedCount = 0;
      conn.beginTransaction();
      indexResourceContent(guid);
    }
       
    if (Global.keepRunning)
      conn.getNoteTable().noteResourceTable.setIndexNeeded(guid,false);
    conn.commitTransaction();
    uncommittedCount = 0;
  }
 
  private void indexResourceContent(String guid) {
    Resource r = conn.getNoteTable().noteResourceTable.getNoteResource(guid, true);
    if (r != null && r.getMime() != null) {
      if (r.getMime().equalsIgnoreCase("application/pdf")) {
        indexResourcePDF(r);
        return;
      }
      if (r.getMime().equalsIgnoreCase("application/docx") ||
        r.getMime().equalsIgnoreCase("application/xlsx") ||
        r.getMime().equalsIgnoreCase("application/pptx")) {
        indexResourceOOXML(r);
        return;
      }
      if (r.getMime().equalsIgnoreCase("application/vsd") ||
          r.getMime().equalsIgnoreCase("application/ppt") ||
          r.getMime().equalsIgnoreCase("application/xls") ||
          r.getMime().equalsIgnoreCase("application/msg") ||
          r.getMime().equalsIgnoreCase("application/doc")) {
        indexResourceOffice(r);
        return;
      }
      if (r.getMime().equalsIgnoreCase("application/rtf")) {
          indexResourceRTF(r);
          return;
      }
      if (r.getMime().equalsIgnoreCase("application/odf") ||
        r.getMime().equalsIgnoreCase("application/odt") ||
        r.getMime().equalsIgnoreCase("application/odp") ||
        r.getMime().equalsIgnoreCase("application/odg") ||
        r.getMime().equalsIgnoreCase("application/odb") ||
        r.getMime().equalsIgnoreCase("application/ods")) {
        indexResourceODF(r);
        return;
      }
    }
  }


  private void indexResourceRTF(Resource r) {

    Data d = r.getData();
    for (int i=0; i<20 && d.getSize() == 0; i++)
      d = r.getData();
    if (d.getSize()== 0)
      return;

    QTemporaryFile f = writeResource(d);
    if (!keepRunning) {
      return;
    }
   
    InputStream input;
    try {
      input = new FileInputStream(new File(f.fileName()));
      ContentHandler textHandler = new BodyContentHandler(-1);
      Metadata metadata = new Metadata();
      RTFParser parser = new RTFParser()
      ParseContext context = new ParseContext();
      parser.parse(input, textHandler, metadata, context);
      String[] result = textHandler.toString().split(regex);
      for (int i=0; i<result.length && keepRunning; i++) {
        addToIndex(r.getNoteGuid(), result[i], "RESOURCE");
      }
      input.close();
   
      f.close();
    } catch (java.lang.ClassCastException e) {
      logger.log(logger.LOW, "Cast exception: " +e.getMessage());
    } catch (FileNotFoundException e) {
      logger.log(logger.LOW, "FileNotFound  exception: " +e.getMessage());
    } catch (IOException e) {
      logger.log(logger.LOW, "IO  exception: " +e.getMessage());
    } catch (SAXException e) {
      logger.log(logger.LOW, "SAX  exception: " +e.getMessage());
    } catch (TikaException e) {
      logger.log(logger.LOW, "Tika  exception: " +e.getMessage());
    } catch (Exception e) {
      logger.log(logger.LOW, "Unknown  exception: " +e.getMessage());
    } catch (java.lang.NoSuchMethodError e) {
      logger.log(logger.LOW, "NoSuchMethod error: " +e.getMessage());
    } catch (Error e) {
      logger.log(logger.LOW, "Unknown error: " +e.getMessage());
    }
  }

 
  private void indexResourceODF(Resource r) {

    Data d = r.getData();
    for (int i=0; i<20 && d.getSize() == 0; i++)
      d = r.getData();
    if (d.getSize()== 0)
      return;
    QTemporaryFile f = writeResource(d);
    if (!keepRunning) {
      return;
    }
   
    InputStream input;
    try {
      input = new FileInputStream(new File(f.fileName()));
      ContentHandler textHandler = new BodyContentHandler(-1);
      Metadata metadata = new Metadata();
      OpenDocumentParser parser = new OpenDocumentParser()
      ParseContext context = new ParseContext();
      parser.parse(input, textHandler, metadata, context);
      String[] result = textHandler.toString().split(regex);
      for (int i=0; i<result.length && keepRunning; i++) {
        if (interrupt) {
          processInterrupt();
        }
        addToIndex(r.getNoteGuid(), result[i], "RESOURCE");
      }
      input.close();
   
      f.close();
    } catch (java.lang.ClassCastException e) {
      logger.log(logger.LOW, "Cast exception: " +e.getMessage());
    } catch (FileNotFoundException e) {
      logger.log(logger.LOW, "FileNotFound  exception: " +e.getMessage());
    } catch (IOException e) {
      logger.log(logger.LOW, "IO  exception: " +e.getMessage());
    } catch (SAXException e) {
      logger.log(logger.LOW, "SAX  exception: " +e.getMessage());
    } catch (TikaException e) {
      logger.log(logger.LOW, "Tika  exception: " +e.getMessage());
    } catch (Exception e) {
      logger.log(logger.LOW, "Unknown  exception: " +e.getMessage());
    } catch (java.lang.NoSuchMethodError e) {
      logger.log(logger.LOW, "NoSuchMethod error: " +e.getMessage());
    } catch (Error e) {
      logger.log(logger.LOW, "Unknown error: " +e.getMessage());
    }
  }

 
  private void indexResourceOffice(Resource r) {

    Data d = r.getData();
    for (int i=0; i<20 && d.getSize() == 0; i++)
      d = r.getData();
    if (d.getSize()== 0)
      return;
    QTemporaryFile f = writeResource(d);
    if (!keepRunning) {
      return;
    }
   
    InputStream input;
    try {
      input = new FileInputStream(new File(f.fileName()));
      ContentHandler textHandler = new BodyContentHandler(-1);
      Metadata metadata = new Metadata();
      OfficeParser parser = new OfficeParser()
      ParseContext context = new ParseContext();
      parser.parse(input, textHandler, metadata, context);
      String[] result = textHandler.toString().split(regex);
      for (int i=0; i<result.length && keepRunning; i++) {
        if (interrupt) {
          processInterrupt();
        }
        addToIndex(r.getNoteGuid(), result[i], "RESOURCE");
      }
      input.close();
   
      f.close();
    } catch (java.lang.ClassCastException e) {
      logger.log(logger.LOW, "Cast exception: " +e.getMessage());
    } catch (FileNotFoundException e) {
      logger.log(logger.LOW, "FileNotFound  exception: " +e.getMessage());
    } catch (IOException e) {
      logger.log(logger.LOW, "IO  exception: " +e.getMessage());
    } catch (SAXException e) {
      logger.log(logger.LOW, "SAX  exception: " +e.getMessage());
    } catch (TikaException e) {
      logger.log(logger.LOW, "Tika  exception: " +e.getMessage());
    } catch (Exception e) {
      logger.log(logger.LOW, "Unknown  exception: " +e.getMessage());
    } catch (java.lang.NoSuchMethodError e) {
      logger.log(logger.LOW, "NoSuchMethod error: " +e.getMessage());
    } catch (Error e) {
      logger.log(logger.LOW, "Unknown error: " +e.getMessage());
    }
  }

 
 
  private void indexResourcePDF(Resource r) {

    Data d = r.getData();
    for (int i=0; i<20 && d.getSize() == 0; i++)
      d = r.getData();
    if (d.getSize()== 0)
      return;
    QTemporaryFile f = writeResource(d);
    if (!keepRunning) {
      return;
    }
   
    InputStream input;
    try {     
      input = new FileInputStream(new File(f.fileName()));
      ContentHandler textHandler = new BodyContentHandler(-1);
      Metadata metadata = new Metadata();
      PDFParser parser = new PDFParser()
      ParseContext context = new ParseContext();
      parser.parse(input, textHandler, metadata, context);
      String[] result = textHandler.toString().split(regex);
      for (int i=0; i<result.length && keepRunning; i++) {
        if (interrupt) {
          processInterrupt();
        }
        addToIndex(r.getNoteGuid(), result[i], "RESOURCE");
      }
      input.close();
   
      f.close();
    } catch (java.lang.ClassCastException e) {
      logger.log(logger.LOW, "Cast exception: " +e.getMessage());
    } catch (FileNotFoundException e) {
      logger.log(logger.LOW, "FileNotFound  exception: " +e.getMessage());
    } catch (IOException e) {
      logger.log(logger.LOW, "IO  exception: " +e.getMessage());
    } catch (SAXException e) {
      logger.log(logger.LOW, "SAX  exception: " +e.getMessage());
    } catch (TikaException e) {
      logger.log(logger.LOW, "Tika  exception: " +e.getMessage());
    } catch (Exception e) {
      logger.log(logger.LOW, "Unknown  exception: " +e.getMessage());
    } catch (java.lang.NoSuchMethodError e) {
      logger.log(logger.LOW, "NoSuchMethod error: " +e.getMessage());
    } catch (Error e) {
      logger.log(logger.LOW, "Unknown error: " +e.getMessage());
    }
  }
 
 
  private void indexResourceOOXML(Resource r) {

    Data d = r.getData();
    for (int i=0; i<20 && d.getSize() == 0; i++)
      d = r.getData();
    if (d.getSize()== 0)
      return;
    QTemporaryFile f = writeResource(d);
    if (!keepRunning) {
      return;
    }
   
    InputStream input;
    try {
      input = new FileInputStream(new File(f.fileName()));
      ContentHandler textHandler = new BodyContentHandler(-1);
      Metadata metadata = new Metadata();
      OOXMLParser parser = new OOXMLParser()
      ParseContext context = new ParseContext();
      parser.parse(input, textHandler, metadata, context);
      String[] result = textHandler.toString().split(regex);
      for (int i=0; i<result.length && keepRunning; i++) {
        if (interrupt) {
          processInterrupt();
        }
        addToIndex(r.getNoteGuid(), result[i], "RESOURCE");
      }
      input.close();
   
      f.close();
    } catch (java.lang.ClassCastException e) {
      logger.log(logger.LOW, "Cast exception: " +e.getMessage());
    } catch (FileNotFoundException e) {
      logger.log(logger.LOW, "FileNotFound  exception: " +e.getMessage());
    } catch (IOException e) {
      logger.log(logger.LOW, "IO  exception: " +e.getMessage());
    } catch (SAXException e) {
      logger.log(logger.LOW, "SAX  exception: " +e.getMessage());
    } catch (TikaException e) {
      logger.log(logger.LOW, "Tika  exception: " +e.getMessage());
    } catch (Exception e) {
      logger.log(logger.LOW, "Unknown  exception: " +e.getMessage());
    } catch (java.lang.NoSuchMethodError e) {
      logger.log(logger.LOW, "NoSuchMethod error: " +e.getMessage());
    } catch (Error e) {
      logger.log(logger.LOW, "Unknown error: " +e.getMessage());    }
  }
 

 
  private QTemporaryFile writeResource(Data d) {
    QTemporaryFile newFile = new QTemporaryFile();
    newFile.open(OpenModeFlag.WriteOnly);
    newFile.write(d.getBody());
    newFile.close();
    return newFile;
  }

 
  private String removeEnCrypt(String content) {
    int index = content.indexOf("<en-crypt");
    int endPos;
    boolean tagFound = true;
    while (tagFound && keepRunning) {
      if (interrupt) {
        processInterrupt();
      }
      endPos = content.indexOf("</en-crypt>", index)+11;
      if (endPos > -1 && index > -1) {
        content = content.substring(0,index)+content.substring(endPos);
        index = content.indexOf("<en-crypt");
      } else {
        tagFound = false;
      }
    }
    return content;
  }

 
  private void addToIndex(String guid, String word, String type) {
    if (foundWords.contains(word))
      return;
    StringBuffer buffer = new StringBuffer(word.toLowerCase());
    for (int i=buffer.length()-1; i>=0; i--) {
      if (!Character.isLetterOrDigit(buffer.charAt(i)) && specialIndexCharacters.indexOf(buffer.charAt(i)) == -1)
        buffer.deleteCharAt(i);
      else
        break;
    }
    buffer = buffer.reverse();
    for (int i=buffer.length()-1; i>=0; i--) {
      if (!Character.isLetterOrDigit(buffer.charAt(i)))
        buffer.deleteCharAt(i);
      else
        break;
    }
    buffer = buffer.reverse();
    if (buffer.length() > 0) {
      // We have a good word, now let's trim off junk at the beginning or end
      if (!foundWords.contains(buffer.toString())) {
        foundWords.add(buffer.toString());
        foundWords.add(word);
        conn.getWordsTable().addWordToNoteIndex(guid, buffer.toString(), type, 100);
        uncommittedCount++;
        if (uncommittedCount > 100) {
          conn.commitTransaction();
          uncommittedCount=0;
        }
      }
    }
    return;
  }
 
  private void scanUnindexed() {
    List<String> notes = conn.getNoteTable().getUnindexed();
    guid = null;
    boolean started = false;
    if (notes.size() > 0) {
      signal.indexStarted.emit();
      started = true;
    }
    for (int i=0; i<notes.size() && keepRunning; i++) {
      if (interrupt) {
        processInterrupt();
      }
      guid = notes.get(i);
      if (guid != null && keepRunning) {
        indexNoteContent();
      }
    }
   
    List<String> unindexedResources = conn.getNoteTable().noteResourceTable.getUnindexed();
    if (unindexedResources.size() > 0 && !started) {
      signal.indexStarted.emit();
      started = true;
    }
    for (int i=0; i<unindexedResources.size()&& keepRunning; i++) {
      if (interrupt) {
        processInterrupt();
      }
      guid = unindexedResources.get(i);
      if (keepRunning) {
        indexResource();
      }
    }
   
    // Cleanup stuff that was deleted at some point
    List<String> guids = conn.getWordsTable().getGuidList();
    logger.log(logger.LOW, "GUIDS in index: " +guids.size());
    for (int i=0; i<guids.size() && keepRunning; i++) {
      if (!conn.getNoteTable().exists(guids.get(i))) {
        logger.log(logger.LOW, "Old GUID found: " +guids.get(i));
        conn.getWordsTable().expunge(guids.get(i));
      }
    }
   
    if (started && keepRunning)
      signal.indexFinished.emit();
  }
 
  private void reindexNote() {
    if (guid == null)
      return;
    conn.getNoteTable().setIndexNeeded(guid, true);
  }
 
  private void reindexAll() {
    conn.getNoteTable().reindexAllNotes();
    conn.getNoteTable().noteResourceTable.reindexAll();
  }

  private void waitSeconds(int len) {
    long starttime = 0; // variable declared
    //...
    // for the first time, remember the timestamp
      starttime = System.currentTimeMillis();
    // the next timestamp we want to wake up
    starttime += (1000.0);
    // Wait until the desired next time arrives using nanosecond
    // accuracy timer (wait(time) isn't accurate enough on most platforms)
    LockSupport.parkNanos((Math.max(0,
        starttime - System.currentTimeMillis()) * 1000000));
  }
 
  private void processInterrupt() {
    conn.commitTransaction();
    waitSeconds(1);
    uncommittedCount = 0;
    conn.beginTransaction();
    interrupt = false;
  }
 
}
TOP

Related Classes of cx.fbn.nevernote.threads.IndexRunner

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.