1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/netwerk/test/TestFileInput2.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,480 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "nsIServiceManager.h" 1.10 +#include "nsIComponentRegistrar.h" 1.11 +#include "nsIInputStream.h" 1.12 +#include "nsIOutputStream.h" 1.13 +#include "nsIRunnable.h" 1.14 +#include "nsIThread.h" 1.15 +#include "nsCOMArray.h" 1.16 +#include "nsISimpleEnumerator.h" 1.17 +#include "prinrval.h" 1.18 +#include "nsIFileStreams.h" 1.19 +#include "nsIFileChannel.h" 1.20 +#include "nsIFile.h" 1.21 +#include "nsNetUtil.h" 1.22 +#include <stdio.h> 1.23 + 1.24 +//////////////////////////////////////////////////////////////////////////////// 1.25 + 1.26 +#include <math.h> 1.27 +#include "prprf.h" 1.28 +#include "nsAutoLock.h" 1.29 + 1.30 +class nsTimeSampler { 1.31 +public: 1.32 + nsTimeSampler(); 1.33 + void Reset(); 1.34 + void StartTime(); 1.35 + void EndTime(); 1.36 + void AddTime(PRIntervalTime time); 1.37 + PRIntervalTime LastInterval() { return mLastInterval; } 1.38 + char* PrintStats(); 1.39 +protected: 1.40 + PRIntervalTime mStartTime; 1.41 + double mSquares; 1.42 + double mTotalTime; 1.43 + uint32_t mCount; 1.44 + PRIntervalTime mLastInterval; 1.45 +}; 1.46 + 1.47 +nsTimeSampler::nsTimeSampler() 1.48 +{ 1.49 + Reset(); 1.50 +} 1.51 + 1.52 +void 1.53 +nsTimeSampler::Reset() 1.54 +{ 1.55 + mStartTime = 0; 1.56 + mSquares = 0; 1.57 + mTotalTime = 0; 1.58 + mCount = 0; 1.59 + mLastInterval = 0; 1.60 +} 1.61 + 1.62 +void 1.63 +nsTimeSampler::StartTime() 1.64 +{ 1.65 + mStartTime = PR_IntervalNow(); 1.66 +} 1.67 + 1.68 +void 1.69 +nsTimeSampler::EndTime() 1.70 +{ 1.71 + NS_ASSERTION(mStartTime != 0, "Forgot to call StartTime"); 1.72 + PRIntervalTime endTime = PR_IntervalNow(); 1.73 + mLastInterval = endTime - mStartTime; 1.74 + AddTime(mLastInterval); 1.75 + mStartTime = 0; 1.76 +} 1.77 + 1.78 +void 1.79 +nsTimeSampler::AddTime(PRIntervalTime time) 1.80 +{ 1.81 + nsAutoCMonitor mon(this); 1.82 + mTotalTime += time; 1.83 + mSquares += (double)time * (double)time; 1.84 + mCount++; 1.85 +} 1.86 + 1.87 +char* 1.88 +nsTimeSampler::PrintStats() 1.89 +{ 1.90 + double mean = mTotalTime / mCount; 1.91 + double variance = fabs(mSquares / mCount - mean * mean); 1.92 + double stddev = sqrt(variance); 1.93 + uint32_t imean = (uint32_t)mean; 1.94 + uint32_t istddev = (uint32_t)stddev; 1.95 + return PR_smprintf("%d +/- %d ms", 1.96 + PR_IntervalToMilliseconds(imean), 1.97 + PR_IntervalToMilliseconds(istddev)); 1.98 +} 1.99 + 1.100 +//////////////////////////////////////////////////////////////////////////////// 1.101 + 1.102 +nsTimeSampler gTimeSampler; 1.103 + 1.104 +typedef nsresult (*CreateFun)(nsIRunnable* *result, 1.105 + nsIFile* inPath, 1.106 + nsIFile* outPath, 1.107 + uint32_t bufferSize); 1.108 + 1.109 +//////////////////////////////////////////////////////////////////////////////// 1.110 + 1.111 +nsresult 1.112 +Copy(nsIInputStream* inStr, nsIOutputStream* outStr, 1.113 + char* buf, uint32_t bufSize, uint32_t *copyCount) 1.114 +{ 1.115 + nsresult rv; 1.116 + while (true) { 1.117 + uint32_t count; 1.118 + rv = inStr->Read(buf, bufSize, &count); 1.119 + if (NS_FAILED(rv)) return rv; 1.120 + if (count == 0) break; 1.121 + 1.122 + uint32_t writeCount; 1.123 + rv = outStr->Write(buf, count, &writeCount); 1.124 + if (NS_FAILED(rv)) return rv; 1.125 + NS_ASSERTION(writeCount == count, "didn't write all the data"); 1.126 + *copyCount += writeCount; 1.127 + } 1.128 + rv = outStr->Flush(); 1.129 + return rv; 1.130 +} 1.131 + 1.132 +//////////////////////////////////////////////////////////////////////////////// 1.133 + 1.134 +class FileSpecWorker : public nsIRunnable { 1.135 +public: 1.136 + 1.137 + NS_IMETHOD Run() { 1.138 + nsresult rv; 1.139 + 1.140 + PRIntervalTime startTime = PR_IntervalNow(); 1.141 + PRIntervalTime endTime; 1.142 + nsCOMPtr<nsIInputStream> inStr; 1.143 + nsCOMPtr<nsIOutputStream> outStr; 1.144 + uint32_t copyCount = 0; 1.145 + 1.146 + // Open the input stream: 1.147 + nsCOMPtr<nsIInputStream> fileIn; 1.148 + rv = NS_NewLocalFileInputStream(getter_AddRefs(fileIn), mInPath); 1.149 + if (NS_FAILED(rv)) return rv; 1.150 + 1.151 + rv = NS_NewBufferedInputStream(getter_AddRefs(inStr), fileIn, 65535); 1.152 + if (NS_FAILED(rv)) return rv; 1.153 + 1.154 + // Open the output stream: 1.155 + nsCOMPtr<nsIOutputStream> fileOut; 1.156 + rv = NS_NewLocalFileOutputStream(getter_AddRefs(fileOut), 1.157 + mOutPath, 1.158 + PR_CREATE_FILE | PR_WRONLY | PR_TRUNCATE, 1.159 + 0664); 1.160 + if (NS_FAILED(rv)) return rv; 1.161 + 1.162 + rv = NS_NewBufferedOutputStream(getter_AddRefs(outStr), fileOut, 65535); 1.163 + if (NS_FAILED(rv)) return rv; 1.164 + 1.165 + // Copy from one to the other 1.166 + rv = Copy(inStr, outStr, mBuffer, mBufferSize, ©Count); 1.167 + if (NS_FAILED(rv)) return rv; 1.168 + 1.169 + endTime = PR_IntervalNow(); 1.170 + gTimeSampler.AddTime(endTime - startTime); 1.171 + 1.172 + return rv; 1.173 + } 1.174 + 1.175 + NS_DECL_ISUPPORTS 1.176 + 1.177 + FileSpecWorker() 1.178 + : mInPath(nullptr), mOutPath(nullptr), mBuffer(nullptr), 1.179 + mBufferSize(0) 1.180 + { 1.181 + } 1.182 + 1.183 + nsresult Init(nsIFile* inPath, nsIFile* outPath, 1.184 + uint32_t bufferSize) 1.185 + { 1.186 + mInPath = inPath; 1.187 + mOutPath = outPath; 1.188 + mBuffer = new char[bufferSize]; 1.189 + mBufferSize = bufferSize; 1.190 + return (mInPath && mOutPath && mBuffer) 1.191 + ? NS_OK : NS_ERROR_OUT_OF_MEMORY; 1.192 + } 1.193 + 1.194 + static nsresult Create(nsIRunnable* *result, 1.195 + nsIFile* inPath, 1.196 + nsIFile* outPath, 1.197 + uint32_t bufferSize) 1.198 + { 1.199 + FileSpecWorker* worker = new FileSpecWorker(); 1.200 + if (worker == nullptr) 1.201 + return NS_ERROR_OUT_OF_MEMORY; 1.202 + NS_ADDREF(worker); 1.203 + 1.204 + nsresult rv = worker->Init(inPath, outPath, bufferSize); 1.205 + if (NS_FAILED(rv)) { 1.206 + NS_RELEASE(worker); 1.207 + return rv; 1.208 + } 1.209 + *result = worker; 1.210 + return NS_OK; 1.211 + } 1.212 + 1.213 + virtual ~FileSpecWorker() { 1.214 + delete[] mBuffer; 1.215 + } 1.216 + 1.217 +protected: 1.218 + nsCOMPtr<nsIFile> mInPath; 1.219 + nsCOMPtr<nsIFile> mOutPath; 1.220 + char* mBuffer; 1.221 + uint32_t mBufferSize; 1.222 +}; 1.223 + 1.224 +NS_IMPL_ISUPPORTS(FileSpecWorker, nsIRunnable) 1.225 + 1.226 +//////////////////////////////////////////////////////////////////////////////// 1.227 + 1.228 +#include "nsIIOService.h" 1.229 +#include "nsIChannel.h" 1.230 + 1.231 +class FileChannelWorker : public nsIRunnable { 1.232 +public: 1.233 + 1.234 + NS_IMETHOD Run() { 1.235 + nsresult rv; 1.236 + 1.237 + PRIntervalTime startTime = PR_IntervalNow(); 1.238 + PRIntervalTime endTime; 1.239 + uint32_t copyCount = 0; 1.240 + nsCOMPtr<nsIFileChannel> inCh; 1.241 + nsCOMPtr<nsIFileChannel> outCh; 1.242 + nsCOMPtr<nsIInputStream> inStr; 1.243 + nsCOMPtr<nsIOutputStream> outStr; 1.244 + 1.245 + rv = NS_NewLocalFileChannel(getter_AddRefs(inCh), mInPath); 1.246 + if (NS_FAILED(rv)) return rv; 1.247 + 1.248 + rv = inCh->Open(getter_AddRefs(inStr)); 1.249 + if (NS_FAILED(rv)) return rv; 1.250 + 1.251 + //rv = NS_NewLocalFileChannel(getter_AddRefs(outCh), mOutPath); 1.252 + //if (NS_FAILED(rv)) return rv; 1.253 + 1.254 + //rv = outCh->OpenOutputStream(0, -1, 0, getter_AddRefs(outStr)); 1.255 + //if (NS_FAILED(rv)) return rv; 1.256 + 1.257 + // Copy from one to the other 1.258 + rv = Copy(inStr, outStr, mBuffer, mBufferSize, ©Count); 1.259 + if (NS_FAILED(rv)) return rv; 1.260 + 1.261 + endTime = PR_IntervalNow(); 1.262 + gTimeSampler.AddTime(endTime - startTime); 1.263 + 1.264 + return rv; 1.265 + } 1.266 + 1.267 + NS_DECL_ISUPPORTS 1.268 + 1.269 + FileChannelWorker() 1.270 + : mInPath(nullptr), mOutPath(nullptr), mBuffer(nullptr), 1.271 + mBufferSize(0) 1.272 + { 1.273 + } 1.274 + 1.275 + nsresult Init(nsIFile* inPath, nsIFile* outPath, 1.276 + uint32_t bufferSize) 1.277 + { 1.278 + mInPath = inPath; 1.279 + mOutPath = outPath; 1.280 + mBuffer = new char[bufferSize]; 1.281 + mBufferSize = bufferSize; 1.282 + return (mInPath && mOutPath && mBuffer) 1.283 + ? NS_OK : NS_ERROR_OUT_OF_MEMORY; 1.284 + } 1.285 + 1.286 + static nsresult Create(nsIRunnable* *result, 1.287 + nsIFile* inPath, 1.288 + nsIFile* outPath, 1.289 + uint32_t bufferSize) 1.290 + { 1.291 + FileChannelWorker* worker = new FileChannelWorker(); 1.292 + if (worker == nullptr) 1.293 + return NS_ERROR_OUT_OF_MEMORY; 1.294 + NS_ADDREF(worker); 1.295 + 1.296 + nsresult rv = worker->Init(inPath, outPath, bufferSize); 1.297 + if (NS_FAILED(rv)) { 1.298 + NS_RELEASE(worker); 1.299 + return rv; 1.300 + } 1.301 + *result = worker; 1.302 + return NS_OK; 1.303 + } 1.304 + 1.305 + virtual ~FileChannelWorker() { 1.306 + delete[] mBuffer; 1.307 + } 1.308 + 1.309 +protected: 1.310 + nsCOMPtr<nsIFile> mInPath; 1.311 + nsCOMPtr<nsIFile> mOutPath; 1.312 + char* mBuffer; 1.313 + uint32_t mBufferSize; 1.314 +}; 1.315 + 1.316 +NS_IMPL_ISUPPORTS(FileChannelWorker, nsIRunnable) 1.317 + 1.318 +//////////////////////////////////////////////////////////////////////////////// 1.319 + 1.320 +void 1.321 +Test(CreateFun create, uint32_t count, 1.322 + nsIFile* inDirSpec, nsIFile* outDirSpec, uint32_t bufSize) 1.323 +{ 1.324 + nsresult rv; 1.325 + uint32_t i; 1.326 + 1.327 + nsAutoCString inDir; 1.328 + nsAutoCString outDir; 1.329 + (void)inDirSpec->GetNativePath(inDir); 1.330 + (void)outDirSpec->GetNativePath(outDir); 1.331 + printf("###########\nTest: from %s to %s, bufSize = %d\n", 1.332 + inDir.get(), outDir.get(), bufSize); 1.333 + gTimeSampler.Reset(); 1.334 + nsTimeSampler testTime; 1.335 + testTime.StartTime(); 1.336 + 1.337 + nsCOMArray<nsIThread> threads; 1.338 + 1.339 + nsCOMPtr<nsISimpleEnumerator> entries; 1.340 + rv = inDirSpec->GetDirectoryEntries(getter_AddRefs(entries)); 1.341 + NS_ASSERTION(NS_SUCCEEDED(rv), "GetDirectoryEntries failed"); 1.342 + 1.343 + i = 0; 1.344 + bool hasMore; 1.345 + while (i < count && NS_SUCCEEDED(entries->HasMoreElements(&hasMore)) && hasMore) { 1.346 + nsCOMPtr<nsISupports> next; 1.347 + rv = entries->GetNext(getter_AddRefs(next)); 1.348 + if (NS_FAILED(rv)) goto done; 1.349 + 1.350 + nsCOMPtr<nsIFile> inSpec = do_QueryInterface(next, &rv); 1.351 + if (NS_FAILED(rv)) goto done; 1.352 + 1.353 + nsCOMPtr<nsIFile> outSpec; 1.354 + rv = outDirSpec->Clone(getter_AddRefs(outSpec)); // don't munge the original 1.355 + if (NS_FAILED(rv)) goto done; 1.356 + 1.357 + nsAutoCString leafName; 1.358 + rv = inSpec->GetNativeLeafName(leafName); 1.359 + if (NS_FAILED(rv)) goto done; 1.360 + 1.361 + rv = outSpec->AppendNative(leafName); 1.362 + if (NS_FAILED(rv)) goto done; 1.363 + 1.364 + bool exists; 1.365 + rv = outSpec->Exists(&exists); 1.366 + if (NS_FAILED(rv)) goto done; 1.367 + 1.368 + if (exists) { 1.369 + rv = outSpec->Remove(false); 1.370 + if (NS_FAILED(rv)) goto done; 1.371 + } 1.372 + 1.373 + nsCOMPtr<nsIThread> thread; 1.374 + nsCOMPtr<nsIRunnable> worker; 1.375 + rv = create(getter_AddRefs(worker), 1.376 + inSpec, 1.377 + outSpec, 1.378 + bufSize); 1.379 + if (NS_FAILED(rv)) goto done; 1.380 + 1.381 + rv = NS_NewThread(getter_AddRefs(thread), worker, 0, PR_JOINABLE_THREAD); 1.382 + if (NS_FAILED(rv)) goto done; 1.383 + 1.384 + bool inserted = threads.InsertObjectAt(thread, i); 1.385 + NS_ASSERTION(inserted, "not inserted"); 1.386 + 1.387 + i++; 1.388 + } 1.389 + 1.390 + uint32_t j; 1.391 + for (j = 0; j < i; j++) { 1.392 + nsIThread* thread = threads.ObjectAt(j); 1.393 + thread->Join(); 1.394 + } 1.395 + 1.396 + done: 1.397 + NS_ASSERTION(rv == NS_OK, "failed"); 1.398 + 1.399 + testTime.EndTime(); 1.400 + char* testStats = testTime.PrintStats(); 1.401 + char* workerStats = gTimeSampler.PrintStats(); 1.402 + printf(" threads = %d\n work time = %s,\n test time = %s\n", 1.403 + i, workerStats, testStats); 1.404 + PR_smprintf_free(workerStats); 1.405 + PR_smprintf_free(testStats); 1.406 +} 1.407 + 1.408 +//////////////////////////////////////////////////////////////////////////////// 1.409 + 1.410 +int 1.411 +main(int argc, char* argv[]) 1.412 +{ 1.413 + nsresult rv; 1.414 + 1.415 + if (argc < 2) { 1.416 + printf("usage: %s <in-dir> <out-dir>\n", argv[0]); 1.417 + return -1; 1.418 + } 1.419 + char* inDir = argv[1]; 1.420 + char* outDir = argv[2]; 1.421 + 1.422 + { 1.423 + nsCOMPtr<nsIServiceManager> servMan; 1.424 + NS_InitXPCOM2(getter_AddRefs(servMan), nullptr, nullptr); 1.425 + nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(servMan); 1.426 + NS_ASSERTION(registrar, "Null nsIComponentRegistrar"); 1.427 + if (registrar) 1.428 + registrar->AutoRegister(nullptr); 1.429 + 1.430 + nsCOMPtr<nsIFile> inDirFile; 1.431 + rv = NS_NewNativeLocalFile(nsDependentCString(inDir), false, getter_AddRefs(inDirFile)); 1.432 + if (NS_FAILED(rv)) return rv; 1.433 + 1.434 + nsCOMPtr<nsIFile> outDirFile; 1.435 + rv = NS_NewNativeLocalFile(nsDependentCString(outDir), false, getter_AddRefs(outDirFile)); 1.436 + if (NS_FAILED(rv)) return rv; 1.437 + 1.438 + CreateFun create = FileChannelWorker::Create; 1.439 + Test(create, 1, inDirFile, outDirFile, 16 * 1024); 1.440 +#if 1 1.441 + printf("FileChannelWorker *****************************\n"); 1.442 + Test(create, 20, inDirFile, outDirFile, 16 * 1024); 1.443 + Test(create, 20, inDirFile, outDirFile, 16 * 1024); 1.444 + Test(create, 20, inDirFile, outDirFile, 16 * 1024); 1.445 + Test(create, 20, inDirFile, outDirFile, 16 * 1024); 1.446 + Test(create, 20, inDirFile, outDirFile, 16 * 1024); 1.447 + Test(create, 20, inDirFile, outDirFile, 16 * 1024); 1.448 + Test(create, 20, inDirFile, outDirFile, 16 * 1024); 1.449 + Test(create, 20, inDirFile, outDirFile, 16 * 1024); 1.450 + Test(create, 20, inDirFile, outDirFile, 16 * 1024); 1.451 +#endif 1.452 + create = FileSpecWorker::Create; 1.453 + printf("FileSpecWorker ********************************\n"); 1.454 +#if 1 1.455 + Test(create, 20, inDirFile, outDirFile, 16 * 1024); 1.456 + Test(create, 20, inDirFile, outDirFile, 16 * 1024); 1.457 + Test(create, 20, inDirFile, outDirFile, 16 * 1024); 1.458 + Test(create, 20, inDirFile, outDirFile, 16 * 1024); 1.459 + Test(create, 20, inDirFile, outDirFile, 16 * 1024); 1.460 + Test(create, 20, inDirFile, outDirFile, 16 * 1024); 1.461 + Test(create, 20, inDirFile, outDirFile, 16 * 1024); 1.462 + Test(create, 20, inDirFile, outDirFile, 16 * 1024); 1.463 + Test(create, 20, inDirFile, outDirFile, 16 * 1024); 1.464 +#endif 1.465 +#if 1 1.466 + Test(create, 20, inDirFile, outDirFile, 4 * 1024); 1.467 + Test(create, 20, inDirFile, outDirFile, 4 * 1024); 1.468 + Test(create, 20, inDirFile, outDirFile, 4 * 1024); 1.469 + Test(create, 20, inDirFile, outDirFile, 4 * 1024); 1.470 + Test(create, 20, inDirFile, outDirFile, 4 * 1024); 1.471 + Test(create, 20, inDirFile, outDirFile, 4 * 1024); 1.472 + Test(create, 20, inDirFile, outDirFile, 4 * 1024); 1.473 + Test(create, 20, inDirFile, outDirFile, 4 * 1024); 1.474 + Test(create, 20, inDirFile, outDirFile, 4 * 1024); 1.475 +#endif 1.476 + } // this scopes the nsCOMPtrs 1.477 + // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM 1.478 + rv = NS_ShutdownXPCOM(nullptr); 1.479 + NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed"); 1.480 + return 0; 1.481 +} 1.482 + 1.483 +////////////////////////////////////////////////////////////////////////////////