Android Open Source - InMemoryDb In Memory Db Array List






From Project

Back to project page InMemoryDb.

License

The source code is released under:

Apache License

If you think the Android project InMemoryDb listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package org.gawst.asyncdb;
// ww  w .  j av a 2s  . c o m
import org.gawst.asyncdb.adapter.InMemoryFilteredAdapter;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * a basic helper class to keep the content of a flat database in an {@link ArrayList}
 * <p>
 * you should use the {@link #mDataLock} when iterating through the {@link ArrayList}
 * @author Steve Lhomme
 *
 * @param <E> the type of items stored in memory by the {@link InMemoryDbArrayList}
 */
public abstract class InMemoryDbArrayList<E, INSERT_ID> extends InMemoryDbList<E, ArrayList<E>, INSERT_ID> implements InMemoryFilteredAdapter.InMemoryFilter.InMemoryFilterable<E> {

  /**
   * the array where the data are stored, locked when writing on it
   */
  private ArrayList<E> mData;

  /**
   * Field to tell when the data are being reloaded from the DB
   */
  private boolean mIsLoading;

  /**
   * ReentrantLock used to protect {@link #mData} when reading/writing/iterating it
   */
  protected ReentrantLock mDataLock;

  /**
   * Condition to block the {@link #mData} access before the data are loaded
   */
  private Condition dataLoaded;

  /**
   * @param db The already created {@link android.database.sqlite.SQLiteOpenHelper} to use as storage
   * @param name Database name for logs
   * @param logger The {@link Logger} to use for all logs (can be null for the default Android logs)
   */
  protected InMemoryDbArrayList(DataSource<E, INSERT_ID> db, String name, Logger logger) {
    super(db, name, logger, null);
  }

  /**
   * @param db The already created {@link android.database.sqlite.SQLiteOpenHelper} to use as storage
   * @param name Database name for logs
   * @param logger The {@link Logger} to use for all logs (can be null for the default Android logs)
   * @param initCookie Cookie to pass to {@link AsynchronousDbHelper#preloadInit(Object)}
   */
  protected InMemoryDbArrayList(DataSource<E, INSERT_ID> db, String name, Logger logger, Object initCookie) {
    super(db, name, logger, initCookie);
  }
  
  @Override
  protected void preloadInit(Object cookie) {
    mDataLock = new ReentrantLock();
    dataLoaded = mDataLock.newCondition();
    super.preloadInit(cookie);
    mData = new ArrayList<E>();
  }

  @Override
  protected ArrayList<E> getList() {
    if (!mDataLock.isHeldByCurrentThread()) throw new IllegalStateException("we need a lock on mDataLock to access mData in "+this);
    if (!isDataLoaded() && !mIsLoading)
      try {
        // we're trying to read the data but they are not loading yet
        LogManager.logger.v(STARTUP_TAG, "waiting data loaded in "+this);
        long now = System.currentTimeMillis();
        dataLoaded.await(10, TimeUnit.SECONDS);
        LogManager.logger.v(STARTUP_TAG, "waiting data loaded in "+this+" finished after "+(System.currentTimeMillis()-now));
      } catch (InterruptedException ignored) {
        LogManager.logger.w(STARTUP_TAG, "timed out waiting for data loaded in "+this);
      }
    return mData;
  }

  @Override
  protected void startLoadingInMemory() {
    mDataLock.lock();
    mData.clear();
    mIsLoading = true;
    super.startLoadingInMemory();
  }

  @Override
  protected void finishLoadingInMemory() {
    super.finishLoadingInMemory();
    mIsLoading = false;
    dataLoaded.signalAll();
    mDataLock.unlock();
  }

  @Override
  public void startLoadingAllItems(int elementCount) {
    super.startLoadingAllItems(elementCount);
    getList().ensureCapacity(elementCount);
  }

  public boolean add(E item) {
    // protect the data coherence
    mDataLock.lock();
    try {
      return super.add(item);
    } finally {
      mDataLock.unlock();
    }
  }

  public boolean addAll(Collection<? extends E> items) {
    // protect the data coherence
    mDataLock.lock();
    try {
      return super.addAll(items);
    } finally {
      mDataLock.unlock();
    }
  }

  public boolean remove(E item) {
    // protect the data coherence
    mDataLock.lock();
    try {
      return super.remove(item);
    } finally {
      mDataLock.unlock();
    }
  }

  @Override
  public boolean remove(int index) {
    // protect the data coherence
    mDataLock.lock();
    try {
      return super.remove(index);
    } finally {
      mDataLock.unlock();
    }
  }

  public void notifyItemChanged(E item) {
    // protect the data coherence
    mDataLock.lock();
    try {
      super.notifyItemChanged(item);
    } finally {
      mDataLock.unlock();
    }
  }

  @Override
  protected void clearDataInMemory() {
    // protect the data coherence
    mDataLock.lock();
    try {
      super.clearDataInMemory();
    } finally {
      mDataLock.unlock();
    }
  }
  
  public int getCount() {
    mDataLock.lock();
    try {
      return null==mData ? 0 : mData.size();
    } finally {
      mDataLock.unlock();
    }
  }

  @Override
  public E get(int position) {
    mDataLock.lock();
    try {
      return super.get(position);
    } finally {
      mDataLock.unlock();
    }
  }

  @Override
  public int indexOf(E item) {
    mDataLock.lock();
    try {
      return super.indexOf(item);
    } finally {
      mDataLock.unlock();
    }
  }

  @Override
  public E findItem(E similar) {
    mDataLock.lock();
    try {
      return super.findItem(similar);
    } finally {
      mDataLock.unlock();
    }
  }

  @Override
  public boolean replace(int index, E newData) {
    mDataLock.lock();
    try {
      return super.replace(index, newData);
    } finally {
      mDataLock.unlock();
    }
  }

  @Override
  public boolean swap(int positionA, int positionB) {
    mDataLock.lock();
    try {
      return super.swap(positionA, positionB);
    } finally {
      mDataLock.unlock();
    }
  }

  @Override
  public void waitForDataLoaded() {
    mDataLock.lock();
    try {
      getList();
        super.waitForDataLoaded();
    } finally {
      mDataLock.unlock();
    }
  }

  @Override
  public java.util.List<E> getListCopy() {
    mDataLock.lock();
    try {
      return Collections.unmodifiableList(new ArrayList<E>(getList()));
    } finally {
      mDataLock.unlock();
    }
  }

  @Override
  public void onReplaceItemFailed(AsynchronousDbHelper<E, ?> db, E original, E replacement, Throwable cause) {
    mDataLock.lock();
    try {
      super.onReplaceItemFailed(db, original, replacement, cause);
    } finally {
      mDataLock.unlock();
    }
  }
}




Java Source Code List

org.gawst.asyncdb.AsyncDatabaseHandler.java
org.gawst.asyncdb.AsyncDbHelperHandler.java
org.gawst.asyncdb.AsyncQueryHandler.java
org.gawst.asyncdb.AsynchronousDatabase.java
org.gawst.asyncdb.AsynchronousDbErrorHandler.java
org.gawst.asyncdb.AsynchronousDbHelper.java
org.gawst.asyncdb.AsynchronousDbOperation.java
org.gawst.asyncdb.DataSource.java
org.gawst.asyncdb.InMemoryDbArrayList.java
org.gawst.asyncdb.InMemoryDbCopyOnWriteArrayList.java
org.gawst.asyncdb.InMemoryDbList.java
org.gawst.asyncdb.InMemoryDbListener.java
org.gawst.asyncdb.InMemoryDbMap.java
org.gawst.asyncdb.InMemoryDbSet.java
org.gawst.asyncdb.InMemoryDbTreeSet.java
org.gawst.asyncdb.InMemoryHashmapDb.java
org.gawst.asyncdb.InMemoryLruCache.java
org.gawst.asyncdb.InvalidDbEntry.java
org.gawst.asyncdb.InvalidEntry.java
org.gawst.asyncdb.LogManager.java
org.gawst.asyncdb.Logger.java
org.gawst.asyncdb.LruCache.java
org.gawst.asyncdb.MapDataSource.java
org.gawst.asyncdb.MapDatabaseElementHandler.java
org.gawst.asyncdb.MapEntry.java
org.gawst.asyncdb.adapter.InMemoryArrayListAdapter.java
org.gawst.asyncdb.adapter.InMemoryFilteredAdapter.java
org.gawst.asyncdb.adapter.InMemoryFilteredListAdapter.java
org.gawst.asyncdb.adapter.InMemoryFilteredTreeAdapter.java
org.gawst.asyncdb.adapter.InMemoryTreeSetAdapter.java
org.gawst.asyncdb.adapter.UIHandler.java
org.gawst.asyncdb.purge.DatabasePurgerMaxDate.java
org.gawst.asyncdb.purge.DatabaseSourcePurgerMax.java
org.gawst.asyncdb.purge.DatabaseSourcePurger.java
org.gawst.asyncdb.purge.PurgeHandler.java
org.gawst.asyncdb.source.ContentProviderDataSource.java
org.gawst.asyncdb.source.CursorDataSource.java
org.gawst.asyncdb.source.DatabaseElementHandler.java
org.gawst.asyncdb.source.DatabaseSource.java
org.gawst.asyncdb.source.SqliteDataSource.java
org.gawst.asyncdb.source.SqliteMapDataSource.java
org.gawst.asyncdb.source.typed.TypedContentProviderDataSource.java
org.gawst.asyncdb.source.typed.TypedCursorDataSource.java
org.gawst.asyncdb.source.typed.TypedDatabaseElementHandler.java
org.gawst.asyncdb.source.typed.TypedDatabaseSource.java
org.gawst.asyncdb.source.typed.TypedSqliteDataSource.java
org.gawst.asyncdb.source.typed.TypedSqliteMapDataSource.java