NOTE: updateIndexes() is not thread-safe without synchronized.
see https://github.com/couchbase/couchbase-lite-java-core/issues/1363
348319
@Override
    public Status updateIndexes(List<ViewStore> inputViews) throws CouchbaseLiteException {
        synchronized (lockUpdateIndexes) {
            assert (inputViews != null);

            // workaround
            if (!inputViews.contains(this))
                inputViews.add(this);

            final ArrayList<View> views = new ArrayList<View>(inputViews.size());
            final ArrayList<Mapper> mapBlocks = new ArrayList<Mapper>(inputViews.size());
            final ArrayList<String> docTypes = new ArrayList<String>(inputViews.size());
            boolean useDocType = false;
            for (ViewStore v : inputViews) {
                ForestDBViewStore view = (ForestDBViewStore) v;
                ViewStoreDelegate delegate = view.getDelegate();
                Mapper map = delegate != null ? delegate.getMap() : null;
                if (map == null) {
                    Log.v(Log.TAG_VIEW, "    %s has no map block; skipping it", view.getName());
                    continue;
                }
                try {
                    view.openIndex();
                } catch (ForestException e) {
                    throw new CouchbaseLiteException(ForestBridge.err2status(e));
                }
                views.add(view._view);
                mapBlocks.add(map);
                String docType = delegate.getDocumentType();
                docTypes.add(docType);
                if (docType != null && !useDocType)
                    useDocType = true;
            }

            if (views.size() == 0) {
                Log.v(TAG, "    No input views to update the index");
                return new Status(Status.NOT_MODIFIED);
            }

            boolean success = false;
            Indexer indexer = null;
            try {
                indexer = new Indexer(views.toArray(new View[views.size()]));
                indexer.triggerOnView(this._view);
                DocumentIterator itr;
                try {
                    itr = indexer.iterateDocuments();
                    if (itr == null)
                        return new Status(Status.NOT_MODIFIED);
                } catch (ForestException e) {
                    if (e.code == FDBErrors.FDB_RESULT_SUCCESS)
                        return new Status(Status.NOT_MODIFIED);
                    else
                        throw new CouchbaseLiteException(ForestBridge.err2status(e));
                }
                // Now enumerate the docs:
                Document doc;
                while ((doc = itr.nextDocument()) != null) {
                    // For each updated document:
                    try {
                        String docType = useDocType ? doc.getType() : null;
                        // Skip design docs
                        boolean validDocToIndex =
                                !doc.deleted() && !doc.getDocID().startsWith("_design/");
                        // Read the document body:
                        Map<String, Object> body = ForestBridge.bodyOfSelectedRevision(doc);
                        body.put("_id", doc.getDocID());
                        body.put("_rev", doc.getRevID());
                        body.put("_local_seq", doc.getSequence());
                        if (doc.conflicted()) {
                            List<String> currentRevIDs = ForestBridge.getCurrentRevisionIDs(doc);
                            if (currentRevIDs != null && currentRevIDs.size() > 1)
                                body.put("_conflicts",
                                        currentRevIDs.subList(1, currentRevIDs.size()));
                        }
                        // Feed it to each view's map function:
                        for (int viewNumber = 0; viewNumber < views.size(); viewNumber++) {
                            if (!indexer.shouldIndex(doc, viewNumber))
                                continue;

                            boolean indexIt = validDocToIndex;
                            if (indexIt && useDocType) {
                                String viewDocType = docTypes.get(viewNumber);
                                if (viewDocType != null)
                                    indexIt = viewDocType.equals(docType);
                            }

                            if (indexIt)
                                emit(indexer, viewNumber, doc, body, mapBlocks.get(viewNumber));
                            else
                                emit(indexer, viewNumber, doc, body, null);
                        }
                    } finally {
                        doc.free();
                    }
                }
                success = true;
            } catch (ForestException e) {
                throw new CouchbaseLiteException(ForestBridge.err2status(e));
            } finally {
                if (indexer != null) {
                    try {
                        indexer.endIndex(success);
                    } catch (ForestException ex) {
                        Log.e(TAG, "Failed to call Indexer.endIndex(boolean)", ex);
                        if (success)
                            throw new CouchbaseLiteException(ForestBridge.err2status(ex));
                    }
                }
            }
            Log.v(TAG, "... Finished re-indexing (%s)", viewNames(inputViews));
            return new Status(Status.OK);
        }
    }
233746
protected void doUpdateIndex(Set<String> removedNodes, Set<String> addedNodes, Set<String> parentRemovedNodes,
      Set<String> parentAddedNodes)
   {
      ChangesHolder changes = searchManager.getChanges(removedNodes, addedNodes);
      ChangesHolder parentChanges = parentSearchManager.getChanges(parentRemovedNodes, parentAddedNodes);

      if (changes == null && parentChanges == null)
      {
         return;
      }

      try
      {
         doUpdateIndex(new ChangesFilterListsWrapper(changes, parentChanges));
      }
      catch (RuntimeException e)
      {
         if (isTXAware())
         {
            // The indexing is part of the global tx so the error needs to be thrown to
            // allow to roll back other resources
            throw e;
         }
         getLogger().error(e.getLocalizedMessage(), e);
         logErrorChanges(handler, removedNodes, addedNodes);
         logErrorChanges(parentHandler, parentRemovedNodes, parentAddedNodes);
      }
   }
532374
public Future<?> buildIndexAsync()
    {
        // if we're just linking in the index to indexedColumns on an already-built index post-restart, we're done
        boolean allAreBuilt = true;
        for (ColumnDefinition cdef : columnDefs)
        {
            if (!SystemKeyspace.isIndexBuilt(baseCfs.keyspace.getName(), getNameForSystemKeyspace(cdef.name.bytes)))
            {
                allAreBuilt = false;
                break;
            }
        }

        if (allAreBuilt)
            return null;

        // build it asynchronously; addIndex gets called by CFS open and schema update, neither of which
        // we want to block for a long period.  (actual build is serialized on CompactionManager.)
        Runnable runnable = new Runnable()
        {
            public void run()
            {
                baseCfs.forceBlockingFlush();
                buildIndexBlocking();
            }
        };
        FutureTask<?> f = new FutureTask<Object>(runnable, null);

        new Thread(f, "Creating index: " + getIndexName()).start();
        return f;
    }
474115
private void doUpdate() throws PageException, SearchException, IOException {
	// check attributes
	required("index", action, "collection", collection);
	required("index", action, "key", key);

	if (type == -1) type = (query == null) ? SearchIndex.TYPE_FILE : SearchIndex.TYPE_CUSTOM;

	if (type == SearchIndex.TYPE_CUSTOM) {
	    required("index", action, "body", body);
	    // required("index",action,"query",query);
	}
	IndexResult result;

	result = collection.index(pageContext, key, type, urlpath, title, body, language, extensions, query, recurse, categoryTree, category, timeout, custom1, custom2, custom3,
		custom4);
	if (!StringUtil.isEmpty(status)) pageContext.setVariable(status, toStruct(result));
    }
1247459
private void onKeyUpdated(final int index, final Map.Entry<String, String> object, final String value) {
        final HashMap<String, String> _m = new LinkedHashMap<String, String>(getValue());
        final String lastKeyValue = object.getKey();
        String mapValue = "";
        if (lastKeyValue != null) {
            mapValue = _m.remove(lastKeyValue);
        }
        _m.put(value, mapValue);
        setValue(_m, true);
    }
564721
public void sendIndexToBuffer(String index, Map<String, List<String>> fields) {
		String doc = pyUtils.solrDocument(fields);
		addToBuffer(index, doc);
	}
146507
private void check() throws CouchbaseLiteException {
        synchronized (lock) {
            if (c4query != null) { return; }

            database = (Database) from.getSource();
            final String json = encodeAsJson();
            Log.v(DOMAIN, "Query encoded as %s", json);
            if (json == null) { throw new CouchbaseLiteException("Failed to generate JSON query."); }

            if (columnNames == null) { columnNames = generateColumnNames(); }

            try {
                c4query = database.getC4Database().createQuery(json);
            }
            catch (LiteCoreException e) {
                throw CBLStatus.convertException(e);
            }
        }
    }
1333338
@Override
    protected int onExecuteUpdate()
    {
        Map<String, Object> persistDetails = new HashMap<String, Object>();
        DataFrame dataFrame;
        try
        {
            String query = getJPAQuery();// .toLowerCase();

            persistDetails = parseInsertIntoQuery(query);

            dataFrame = getDataFrameToPersist(query, (String) persistDetails.get("fetchQuery"));

            String clientName = (String) persistDetails.get("client");

            SparkDataClient dataClient = SparkDataClientFactory.getDataClient(clientName);
            dataClient.saveDataFrame(dataFrame, getEntityMetadata().getEntityClazz(), persistDetails);
        }
        catch (Exception e)
        {
            logger.error("Error during executing query, Caused by:", e);
            throw new QueryHandlerException(e);
        }

        return getDataFrameSize(dataFrame);
    }
1343521
@Override
  public void update(Result<Integer> result, 
                     int nodeIndex,
                     String sql,
                     Object[] args)
  {
    NodePodAmp node = _podKraken.getNode(nodeIndex);
    
    for (int i = 0; i < node.serverCount(); i++) {
      ServerBartender server = node.server(i);
      
      if (server != null && server.isUp()) {
        ClusterServiceKraken proxy = _podKraken.getProxy(server);
        
        // XXX: failover
        
        proxy.update(result, nodeIndex, sql, args);
        return;
      }
    }

    RuntimeException exn = new ServiceException(L.l("update failed with no live servers"));
    exn.fillInStackTrace();
    
    // XXX: fail
    result.fail(exn);
  }
1291479
private void esIndex(String index, String id, String json, String pipeline) {
        logger.debug("Indexing {}/{}?pipeline={}", index, id, pipeline);
        logger.trace("JSon indexed : {}", json);

        if (!closed) {
            esClient.index(index, id, json, pipeline);
        } else {
            logger.warn("trying to add new file while closing crawler. Document [{}]/[{}] has been ignored", index, id);
        }
    }
574188
@Deprecated
	public static void updateSettings(Client client, String root, String index) throws Exception {
		String settings = IndexSettingsReader.readUpdateSettings(root, index);
		updateIndexWithSettingsInElasticsearch(client, index, settings);
	}
1254129
synchronized int removeAllDocuments(String uuid) throws IOException
   {
      synchronized (updateMonitor)
      {
         //updateInProgress = true;
         indexUpdateMonitor.setUpdateInProgress(true, false);
      }
      int num;
      try
      {
         Term idTerm = new Term(FieldNames.UUID, uuid.toString());
         executeAndLog(new Start(Action.INTERNAL_TRANSACTION));
         num = volatileIndex.removeDocument(idTerm);
         if (num > 0)
         {
            redoLog.append(new DeleteNode(getTransactionId(), uuid));
         }
         for (int i = 0; i < indexes.size(); i++)
         {
            PersistentIndex index = indexes.get(i);
            // only remove documents from registered indexes
            if (indexNames.contains(index.getName()))
            {
               int removed = index.removeDocument(idTerm);
               if (removed > 0)
               {
                  redoLog.append(new DeleteNode(getTransactionId(), uuid));
               }
               num += removed;
            }
         }
         executeAndLog(new Commit(getTransactionId()));
      }
      finally
      {
         synchronized (updateMonitor)
         {
            //updateInProgress = false;
            indexUpdateMonitor.setUpdateInProgress(false, false);
            updateMonitor.notifyAll();
            releaseMultiReader();
         }
      }
      return num;
   }
436610
public void pauseOfflineIndexing() {

        if (m_offlineUpdateFrequency != Long.MAX_VALUE) {
            m_configuredOfflineIndexingFrequency = m_offlineUpdateFrequency;
            m_offlineUpdateFrequency = Long.MAX_VALUE;
            updateOfflineIndexes(0);
        }
    }
1124020
private void reindexContent( boolean includeSystemContent,
                                 IndexWriter indexes ) {
        if (indexes.canBeSkipped()) return;
        // The node type schemata changes every time a node type is (un)registered, so get the snapshot that we'll use throughout
        RepositoryCache repoCache = runningState.repositoryCache();

        logger.debug(JcrI18n.reindexAll.text(runningState.name()));

        if (includeSystemContent) {
            String systemWorkspaceName = repoCache.getSystemWorkspaceName();
            updateIndexesStatus(systemWorkspaceName, IndexManager.IndexStatus.ENABLED, IndexManager.IndexStatus.REINDEXING);
            NodeCache systemWorkspaceCache = repoCache.getWorkspaceCache(systemWorkspaceName);
            CachedNode rootNode = systemWorkspaceCache.getNode(repoCache.getSystemKey());
            // Index the system content ...
            logger.debug("Starting reindex of system content in '{0}' repository.", runningState.name());
            if (reindexSystemContent(rootNode, Integer.MAX_VALUE, indexes)) {
                commitChanges(systemWorkspaceName);
            }
            logger.debug("Completed reindex of system content in '{0}' repository.", runningState.name());
            updateIndexesStatus(systemWorkspaceName, IndexManager.IndexStatus.REINDEXING, IndexManager.IndexStatus.ENABLED);
        }

        // Index the non-system workspaces ...
        for (String workspaceName : repoCache.getWorkspaceNames()) {
            // change the status of the indexes to reindexing
            updateIndexesStatus(workspaceName, IndexManager.IndexStatus.ENABLED, IndexManager.IndexStatus.REINDEXING);
            NodeCache workspaceCache = repoCache.getWorkspaceCache(workspaceName);
            CachedNode rootNode = workspaceCache.getNode(workspaceCache.getRootKey());
            logger.debug("Starting reindex of workspace '{0}' content in '{1}' repository.", runningState.name(), workspaceName);
            if (reindexContent(workspaceName, workspaceCache, rootNode, Integer.MAX_VALUE, false, indexes)) {
                commitChanges(workspaceName);
            }
            logger.debug("Completed reindex of workspace '{0}' content in '{1}' repository.", runningState.name(), workspaceName);
            updateIndexesStatus(workspaceName, IndexManager.IndexStatus.REINDEXING, IndexManager.IndexStatus.ENABLED);
        }
    }
440704
function syncFieldsBetweenTabs( currentPageId ) {
		var sourceIndex, targetIndex, sourceField, targetField;

		sourceIndex = currentPageId === 'find' ? 1 : 0;
		targetIndex = 1 - sourceIndex;
		var i,
			l = fieldsMapping.length;
		for ( i = 0; i < l; i++ ) {
			sourceField = this.getContentElement( pages[ sourceIndex ], fieldsMapping[ i ][ sourceIndex ] );
			targetField = this.getContentElement( pages[ targetIndex ], fieldsMapping[ i ][ targetIndex ] );

			targetField.setValue( sourceField.getValue() );
		}
	}
733
void update(long index, Instant instant, Type type) {
    this.index = index;
    this.type = type;
    clock.set(instant);
  }
991097
boolean updateIndexEntry(S userStorable, S oldUserStorable) throws PersistException {
        Storable newIndexEntry = makeIndexEntry(userStorable);

        if (oldUserStorable != null) deleteOldEntry: {
            Storable oldIndexEntry;
            try {
                oldIndexEntry = makeIndexEntry(oldUserStorable);
            } catch (PersistException e) {
                Throwable cause = e.getCause();
                if (cause instanceof IllegalArgumentException) {
                    // Can be caused by a corrupt master record, which is
                    // attempting do assign an illegal value to the index. There's
                    // no way to find the old index entry to delete.
                    break deleteOldEntry;
                }
                throw e;
            }

            if (oldIndexEntry.equalPrimaryKeys(newIndexEntry)) {
                // Index entry didn't change, so nothing to do. If the index
                // entry has a version, it will lag behind the master's version
                // until the index entry changes, at which point the version
                // will again match the master.
                return true;
            }

            oldIndexEntry.tryDelete();
        }

        return insertIndexEntry(userStorable, newIndexEntry);
    }