com.aoindustries.aoserv.client.FilesystemCachedTable Maven / Gradle / Ivy
Show all versions of aoserv-client Show documentation
/*
* aoserv-client - Java client for the AOServ platform.
* Copyright (C) 2003-2013, 2016 AO Industries, Inc.
* [email protected]
* 7262 Bull Pen Cir
* Mobile, AL 36695
*
* This file is part of aoserv-client.
*
* aoserv-client 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 3 of the License, or
* (at your option) any later version.
*
* aoserv-client 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 aoserv-client. If not, see .
*/
package com.aoindustries.aoserv.client;
import com.aoindustries.io.FileList;
import com.aoindustries.io.FileListObjectFactory;
import com.aoindustries.util.sort.ComparisonSortAlgorithm;
import com.aoindustries.util.sort.FastQSort;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* A FilesystemCachedTable
stores all of the
* available FilesystemCachedObject
s in a
* temporary file and performs all subsequent data access
* locally. The server notifies the client when a table
* is updated, and the caches are then invalidated. Once
* invalidated, the data is reloaded upon next use.
*
* The file format is a simple fixed record length format.
*
* TODO: It is possible to use the same column sorting technique
* to implement the getIndexedRows method from AOServTable.
*
* @author AO Industries, Inc.
*/
public abstract class FilesystemCachedTable> extends AOServTable implements FileListObjectFactory {
/**
* The last time that the data was loaded, or
* -1
if not yet loaded.
*/
private long lastLoaded=-1;
/**
* One file list may exist per column. Only the unique columns will have a non-null value.
* Once a file is sorted on the specific column, its FileList is wrapped in an
* unmodifiable list. This allows the list to be returned to any number of callers without
* any additional copying. If the data is reloaded, a new FileList will be created, leaving
* the old copy intact for those still using the previous copy.
*/
private List> columnLists;
/**
* The raw list of objects as downloaded from the master.
*/
private FileList tableList;
/**
* This is an unmodifiable list and may be returned to any number of callers without copying.
*/
private List unmodifiableTableList;
protected FilesystemCachedTable(AOServConnector connector, Class clazz) {
super(connector, clazz);
}
abstract int getRecordLength();
/**
* Clears the cache, freeing up memory. The data will be reloaded upon
* next use.
*/
@Override
public void clearCache() {
super.clearCache();
synchronized(this) {
lastLoaded=-1;
tableList=null;
unmodifiableTableList=null;
if(columnLists!=null) columnLists.clear();
}
}
/**
* Reloads the cache if the cache has expired. All accesses are already synchronized.
*/
private void validateCache() throws IOException, SQLException {
long currentTime=System.currentTimeMillis();
if(
// If cache never loaded
lastLoaded==-1
// If the system time was reset to previous time
|| currentTime newTableList=new FileList<>(
schemaTable.getName(),
"table",
getRecordLength(),
this
);
getObjects(true, newTableList, AOServProtocol.CommandID.GET_TABLE, getTableID());
tableList=newTableList;
unmodifiableTableList=Collections.unmodifiableList(tableList);
lastLoaded=currentTime;
if(columnLists!=null) columnLists.clear();
}
}
/**
* Gets the complete list of objects in the table. This list is unmodifiable and will not ever be changed.
* Newer data will be contained in new lists so that any calling code sees a snapshot of the code and may
* safely assume the data is constant as long as the code uses the same reference to List returned
* here.
*/
@Override
public final List getRows() throws IOException, SQLException {
synchronized(this) {
validateCache();
return unmodifiableTableList;
}
}
/**
* FastQSort accesses the disk file less than other algorithms, and does
* not load all the objects into memory at once like the default Java
* merge sort.
*/
@Override
protected ComparisonSortAlgorithm