Patch to make FastLoad Service return the previous URI selected when selecting a new one, as well as fixing a few issues relating to dependencies on non-existent files. Patch from brendan, r=dbaron, sr=waterson
This commit is contained in:
ben%netscape.com 2002-05-03 02:59:42 +00:00
Родитель 197f887b3d
Коммит f084944245
4 изменённых файлов: 90 добавлений и 27 удалений

Просмотреть файл

@ -307,7 +307,8 @@ nsFastLoadFileReader::SetChecksum(PRUint32 aChecksum)
}
struct nsStringMapEntry : public PLDHashEntryHdr {
const char* mString; // key, must come first
const char* mString; // key, must come first
nsISupports* mURI; // for SelectMuxedDocument return value
};
struct nsDocumentMapEntry : public nsStringMapEntry {
@ -340,6 +341,7 @@ strmap_ClearEntry(PLDHashTable *aTable, PLDHashEntryHdr *aHdr)
if (entry->mString)
nsMemory::Free((void*) entry->mString);
NS_IF_RELEASE(entry->mURI);
PL_DHashClearEntryStub(aTable, aHdr);
}
@ -417,6 +419,8 @@ nsFastLoadFileReader::StartMuxedDocument(nsISupports* aURI, const char* aURISpec
if (uriMapEntry->mDocMapEntry)
return NS_ERROR_UNEXPECTED;
docMapEntry->mURI = aURI;
NS_ADDREF(docMapEntry->mURI);
uriMapEntry->mObject = key;
NS_ADDREF(uriMapEntry->mObject);
uriMapEntry->mDocMapEntry = docMapEntry;
@ -425,7 +429,8 @@ nsFastLoadFileReader::StartMuxedDocument(nsISupports* aURI, const char* aURISpec
}
NS_IMETHODIMP
nsFastLoadFileReader::SelectMuxedDocument(nsISupports* aURI)
nsFastLoadFileReader::SelectMuxedDocument(nsISupports* aURI,
nsISupports** aResult)
{
nsresult rv;
@ -443,9 +448,9 @@ nsFastLoadFileReader::SelectMuxedDocument(nsISupports* aURI)
// If we're interrupting another document's segment, save its offset so
// we can seek back when it's reselected.
nsDocumentMapReadEntry* docMapEntry = mCurrentDocumentMapEntry;
if (docMapEntry && docMapEntry->mBytesLeft) {
rv = Tell(&docMapEntry->mSaveOffset);
nsDocumentMapReadEntry* prevDocMapEntry = mCurrentDocumentMapEntry;
if (prevDocMapEntry && prevDocMapEntry->mBytesLeft) {
rv = Tell(&prevDocMapEntry->mSaveOffset);
if (NS_FAILED(rv))
return rv;
}
@ -454,7 +459,7 @@ nsFastLoadFileReader::SelectMuxedDocument(nsISupports* aURI)
// non-blocking hunks of data from the parser that are devoid of scripts.
// As more data gets FastLoaded, the number of these useless selects will
// decline.
docMapEntry = uriMapEntry->mDocMapEntry;
nsDocumentMapReadEntry* docMapEntry = uriMapEntry->mDocMapEntry;
if (docMapEntry == mCurrentDocumentMapEntry) {
TRACE_MUX(('r', "select prev %s same as current!\n",
docMapEntry->mString));
@ -474,6 +479,9 @@ nsFastLoadFileReader::SelectMuxedDocument(nsISupports* aURI)
return rv;
}
*aResult = prevDocMapEntry ? prevDocMapEntry->mURI : nsnull;
NS_IF_ADDREF(*aResult);
mCurrentDocumentMapEntry = docMapEntry;
#ifdef DEBUG_MUX
PRUint32 currentSegmentOffset;
@ -498,6 +506,11 @@ nsFastLoadFileReader::EndMuxedDocument(nsISupports* aURI)
if (PL_DHASH_ENTRY_IS_FREE(uriMapEntry))
return NS_ERROR_NOT_AVAILABLE;
// Drop our ref to the URI object that was passed to StartMuxedDocument,
// we no longer need it, and we do not want to extend its lifetime.
if (uriMapEntry->mDocMapEntry)
NS_RELEASE(uriMapEntry->mDocMapEntry->mURI);
// Shrink the table if half the entries are removed sentinels.
PRUint32 size = PL_DHASH_TABLE_SIZE(&mFooter.mURIMap);
if (mFooter.mURIMap.removedCount >= (size >> 2))
@ -681,6 +694,8 @@ nsFastLoadFileReader::ReadFooter(nsFastLoadFooter *aFooter)
entry->mReadObject = nsnull;
entry->mSkipOffset = 0;
entry->mSaveStrongRefCnt = entry->mStrongRefCnt;
entry->mSaveWeakRefCnt = entry->mWeakRefCnt;
}
if (!PL_DHashTableInit(&aFooter->mDocumentMap, &strmap_DHashTableOps,
@ -716,6 +731,7 @@ nsFastLoadFileReader::ReadFooter(nsFastLoadFooter *aFooter)
NS_ASSERTION(!entry->mString, "duplicate URISpec in MuxedDocumentMap");
entry->mString = info.mURISpec;
entry->mURI = nsnull;
entry->mInitialSegmentOffset = info.mInitialSegmentOffset;
entry->mNextSegmentOffset = info.mInitialSegmentOffset;
entry->mBytesLeft = 0;
@ -1327,6 +1343,8 @@ nsFastLoadFileWriter::StartMuxedDocument(nsISupports* aURI,
if (!spec)
return NS_ERROR_OUT_OF_MEMORY;
docMapEntry->mString = NS_REINTERPRET_CAST(const char*, spec);
docMapEntry->mURI = aURI;
NS_ADDREF(docMapEntry->mURI);
nsCOMPtr<nsISupports> key(do_QueryInterface(aURI));
nsURIMapWriteEntry* uriMapEntry =
@ -1350,7 +1368,8 @@ nsFastLoadFileWriter::StartMuxedDocument(nsISupports* aURI,
}
NS_IMETHODIMP
nsFastLoadFileWriter::SelectMuxedDocument(nsISupports* aURI)
nsFastLoadFileWriter::SelectMuxedDocument(nsISupports* aURI,
nsISupports** aResult)
{
// Avoid repeatedly QI'ing to nsISeekableStream as we tell and seek.
nsCOMPtr<nsISeekableStream> seekable(do_QueryInterface(mOutputStream));
@ -1397,6 +1416,8 @@ nsFastLoadFileWriter::SelectMuxedDocument(nsISupports* aURI)
if (prevDocMapEntry == docMapEntry) {
TRACE_MUX(('w', "select prev %s same as current!\n",
prevDocMapEntry->mString));
*aResult = docMapEntry->mURI;
NS_ADDREF(*aResult);
return NS_OK;
}
@ -1460,6 +1481,9 @@ nsFastLoadFileWriter::SelectMuxedDocument(nsISupports* aURI)
if (NS_FAILED(rv))
return rv;
*aResult = prevDocMapEntry ? prevDocMapEntry->mURI : nsnull;
NS_IF_ADDREF(*aResult);
mCurrentDocumentMapEntry = docMapEntry;
TRACE_MUX(('w', "select %p (%p) offset %lu\n",
aURI, key.get(), currentSegmentOffset));
@ -1470,15 +1494,24 @@ NS_IMETHODIMP
nsFastLoadFileWriter::EndMuxedDocument(nsISupports* aURI)
{
nsCOMPtr<nsISupports> key(do_QueryInterface(aURI));
#ifdef NS_DEBUG
nsURIMapWriteEntry* uriMapEntry =
NS_STATIC_CAST(nsURIMapWriteEntry*,
PL_DHashTableOperate(&mURIMap, key, PL_DHASH_LOOKUP));
NS_ASSERTION(uriMapEntry && uriMapEntry->mDocMapEntry,
NS_ASSERTION(uriMapEntry->mDocMapEntry,
"unknown aURI passed to EndMuxedDocument!");
#endif
PL_DHashTableOperate(&mURIMap, key, PL_DHASH_REMOVE);
// Drop our ref to the URI object that was passed to StartMuxedDocument,
// we no longer need it, and we do not want to extend its lifetime.
if (uriMapEntry->mDocMapEntry)
NS_RELEASE(uriMapEntry->mDocMapEntry->mURI);
// Shrink the table if half the entries are removed sentinels.
PRUint32 size = PL_DHASH_TABLE_SIZE(&mURIMap);
if (mURIMap.removedCount >= (size >> 2))
PL_DHashTableOperate(&mURIMap, key, PL_DHASH_REMOVE);
else
PL_DHashTableRawRemove(&mURIMap, uriMapEntry);
TRACE_MUX(('w', "end %p (%p)\n", aURI, key.get()));
return NS_OK;
}
@ -1507,7 +1540,19 @@ nsFastLoadFileWriter::AddDependency(nsIFile* aFile)
if (!tmp)
return NS_ERROR_OUT_OF_MEMORY;
entry->mString = tmp;
// If we can't get the last modified time from aFile, assume it does
// not exist, or is otherwise inaccessible to us (due to permissions),
// remove the dependency, and suppress the failure.
//
// Otherwise, we would end up aborting the fastload process due to a
// missing .js or .xul or other file on every startup.
rv = aFile->GetLastModifiedTime(&entry->mLastModified);
if (NS_FAILED(rv)) {
PL_DHashTableOperate(&mDependencyMap, path.get(), PL_DHASH_REMOVE);
rv = NS_OK;
}
}
return rv;
}
@ -2229,6 +2274,7 @@ nsFastLoadFileUpdater::CopyReadDocumentMapEntryToUpdater(PLDHashTable *aTable,
}
writeEntry->mString = NS_REINTERPRET_CAST(const char*, spec);
writeEntry->mURI = nsnull;
writeEntry->mInitialSegmentOffset = readEntry->mInitialSegmentOffset;
writeEntry->mCurrentSegmentOffset = 0;
return PL_DHASH_NEXT;
@ -2284,12 +2330,13 @@ nsFastLoadFileUpdater::Open(nsFastLoadFileReader* aReader)
NS_IF_ADDREF(obj);
writeEntry->mObject = NS_REINTERPRET_CAST(nsISupports*, key);
writeEntry->mOID = oid;
writeEntry->mInfo = *NS_STATIC_CAST(nsFastLoadSharpObjectInfo*,
readEntry);
writeEntry->mInfo.mCIDOffset = readEntry->mCIDOffset;
writeEntry->mInfo.mStrongRefCnt = readEntry->mSaveStrongRefCnt;
writeEntry->mInfo.mWeakRefCnt = readEntry->mSaveWeakRefCnt;
}
// Copy URI spec string and initial segment offset in FastLoad file from
// nsDocumentMapReadEntry in reader to mDocumentMapWriteEntry in updater.
// nsDocumentMapReadEntry in reader to nsDocumentMapWriteEntry in updater.
// If we didn't enumerate all entries, we ran out of memory.
n = PL_DHashTableEnumerate(&aReader->mFooter.mDocumentMap,
CopyReadDocumentMapEntryToUpdater,

Просмотреть файл

@ -284,6 +284,8 @@ class nsFastLoadFileReader
struct nsObjectMapEntry : public nsFastLoadSharpObjectInfo {
nsCOMPtr<nsISupports> mReadObject;
PRUint32 mSkipOffset;
PRUint16 mSaveStrongRefCnt; // saved for an Update
PRUint16 mSaveWeakRefCnt; // after a Read
};
/**

Просмотреть файл

@ -75,10 +75,16 @@ interface nsIFastLoadFileControl : nsISupports
* some (but not all, at first, or for a while during development) of the
* results of parsing and compiling various inputs can be multiplexed to
* or from a FastLoad file.
*
* Note: Select returns the previously selected URI object in case the
* caller is synchronously selecting and writing data to the FastLoad
* file, so the caller can reselect the previous URI and return to code
* the continues to write FastLoad data for the previous URI, unaware of
* the nested select/write/reselect.
*/
void startMuxedDocument(in nsISupports aURI, in string aURISpec);
void selectMuxedDocument(in nsISupports aURI);
void endMuxedDocument(in nsISupports aURI);
void startMuxedDocument(in nsISupports aURI, in string aURISpec);
nsISupports selectMuxedDocument(in nsISupports aURI);
void endMuxedDocument(in nsISupports aURI);
};
[scriptable, uuid(652ecec6-d40b-45b6-afef-641d6c63a35b)]

Просмотреть файл

@ -72,24 +72,32 @@ interface nsIFastLoadService : nsISupports
readonly attribute PRInt32 direction;
/**
* These methods associate a URI object with its spec, for faster select
* using the object pointer as a key, rather than the spec string. The
* selectMuxedDocument method returns the previously selected URI object,
* in case a caller needs to reselect the previous after muxing data for
* a given URI synchronously. For the non-blocking or "asynchronous" i/o
* case, the caller must select the source URI from the FastLoad multiplex
* before writing a new burst of data parsed from the slow-loaded source.
*
* Clients of inputStream and outputStream should try to demultiplex data
* from the input stream only if fastLoadService->StartMuxedDocument(uri,
* urispec, NS_FASTLOAD_READ) succeeds. If StartMuxedDocument fails with
* NS_ERROR_NOT_AVAILABLE, callers should slow-load the documents, muxing
* their data to the current output stream.
*/
void startMuxedDocument(in nsISupports aURI,
in string aURISpec,
in PRInt32 aDirectionFlags);
void selectMuxedDocument(in nsISupports aURI);
void endMuxedDocument(in nsISupports aURI);
void startMuxedDocument(in nsISupports aURI,
in string aURISpec,
in PRInt32 aDirectionFlags);
nsISupports selectMuxedDocument(in nsISupports aURI);
void endMuxedDocument(in nsISupports aURI);
void addDependency(in nsIFile aFile);
void addDependency(in nsIFile aFile);
PRUint32 computeChecksum(in nsIFile aFile,
in nsIFastLoadReadControl aControl);
void cacheChecksum(in nsIFile aFile,
in nsIObjectOutputStream aStream);
PRUint32 computeChecksum(in nsIFile aFile,
in nsIFastLoadReadControl aControl);
void cacheChecksum(in nsIFile aFile,
in nsIObjectOutputStream aStream);
[noscript] void getFastLoadReferent(inout nsISupports aPtr);