All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.greenrobot.daocompat.query.AbstractQueryData Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2011-2017 Markus Junginger, greenrobot (http://greenrobot.org)
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.greenrobot.daocompat.query;

import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import org.greenrobot.daocompat.AbstractDao;
import org.greenrobot.daocompat.query.QueryBuilder.Condition;
import org.greenrobot.daocompat.query.QueryBuilder.Order;

abstract class AbstractQueryData> {
    final AbstractDao dao;
    final Condition[] conditions;
    final Order[] orders;
    final Integer limit;
    final Integer offset;
    final Map> queriesForThreads;

    AbstractQueryData(AbstractDao dao, Condition[] conditions, Order[] orders, Integer limit,
                      Integer offset) {
        this.dao = dao;
        this.conditions = conditions;
        this.orders = orders;
        this.limit = limit;
        this.offset = offset;
        queriesForThreads = new HashMap<>();
    }

    /**
     * Just an optimized version, which performs faster if the current thread is already the query's owner thread.
     * Note: all parameters are reset to their initial values specified in {@link QueryBuilder}.
     */
    Q forCurrentThread(Q query) {
        if (Thread.currentThread() == query.ownerThread) {
            // reset parameters by building new objectbox query
            query.objectBoxQuery = buildObjectBoxQuery();
            return query;
        } else {
            return forCurrentThread();
        }
    }

    /**
     * Note: all parameters are reset to their initial values specified in {@link QueryBuilder}.
     */
    Q forCurrentThread() {
        // Process.myTid() seems to have issues on some devices (see Github #376) and Robolectric (#171):
        // We use currentThread().getId() instead (unfortunately return a long, can not use SparseArray).
        // PS.: thread ID may be reused, which should be fine because old thread will be gone anyway.
        long threadId = Thread.currentThread().getId();
        synchronized (queriesForThreads) {
            WeakReference queryRef = queriesForThreads.get(threadId);
            Q query = queryRef != null ? queryRef.get() : null;
            if (query == null) {
                gc();
                query = createQuery();
                queriesForThreads.put(threadId, new WeakReference<>(query));
            } else {
                // reset parameters by building new objectbox query
                query.objectBoxQuery = buildObjectBoxQuery();
            }
            return query;
        }
    }

    protected io.objectbox.query.Query buildObjectBoxQuery() {
        io.objectbox.query.QueryBuilder queryBuilder = dao.getBox().query();
        for (Condition condition : conditions) {
            // Note: no longer can supply string order here, is supplied as part of creating condition.
            condition.queryCondition.apply(queryBuilder);
        }
        for (Order order : orders) {
            queryBuilder.order(order.property, order.orderFlag);
        }
        return queryBuilder.build();
    }

    abstract protected Q createQuery();

    void gc() {
        synchronized (queriesForThreads) {
            Iterator>> iterator = queriesForThreads.entrySet().iterator();
            while (iterator.hasNext()) {
                Entry> entry = iterator.next();
                if (entry.getValue().get() == null) {
                    iterator.remove();
                }
            }
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy