Mercurial > jhg
comparison src/org/tmatesoft/hg/internal/DataAccessProvider.java @ 456:909306e412e2
Refactor LogFacility and SessionContext, better API for both
| author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
|---|---|
| date | Mon, 18 Jun 2012 16:54:00 +0200 |
| parents | 299870249a28 |
| children | 2743641f2f12 |
comparison
equal
deleted
inserted
replaced
| 454:36fd1fd06492 | 456:909306e412e2 |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (c) 2010-2011 TMate Software Ltd | 2 * Copyright (c) 2010-2012 TMate Software Ltd |
| 3 * | 3 * |
| 4 * This program is free software; you can redistribute it and/or modify | 4 * This program is free software; you can redistribute it and/or modify |
| 5 * it under the terms of the GNU General Public License as published by | 5 * it under the terms of the GNU General Public License as published by |
| 6 * the Free Software Foundation; version 2 of the License. | 6 * the Free Software Foundation; version 2 of the License. |
| 7 * | 7 * |
| 13 * For information on how to redistribute this software under | 13 * For information on how to redistribute this software under |
| 14 * the terms of a license other than GNU General Public License | 14 * the terms of a license other than GNU General Public License |
| 15 * contact TMate Software at support@hg4j.com | 15 * contact TMate Software at support@hg4j.com |
| 16 */ | 16 */ |
| 17 package org.tmatesoft.hg.internal; | 17 package org.tmatesoft.hg.internal; |
| 18 | |
| 19 import static org.tmatesoft.hg.util.LogFacility.Severity.Error; | |
| 20 import static org.tmatesoft.hg.util.LogFacility.Severity.Warn; | |
| 18 | 21 |
| 19 import java.io.File; | 22 import java.io.File; |
| 20 import java.io.FileInputStream; | 23 import java.io.FileInputStream; |
| 21 import java.io.IOException; | 24 import java.io.IOException; |
| 22 import java.nio.ByteBuffer; | 25 import java.nio.ByteBuffer; |
| 44 private static final int DEFAULT_MAPIO_LIMIT = 100 * 1024; // 100 kB | 47 private static final int DEFAULT_MAPIO_LIMIT = 100 * 1024; // 100 kB |
| 45 private static final int DEFAULT_FILE_BUFFER = 8 * 1024; // 8 kB | 48 private static final int DEFAULT_FILE_BUFFER = 8 * 1024; // 8 kB |
| 46 private static final int DEFAULT_MAPIO_BUFFER = DEFAULT_MAPIO_LIMIT; // same as default boundary | 49 private static final int DEFAULT_MAPIO_BUFFER = DEFAULT_MAPIO_LIMIT; // same as default boundary |
| 47 | 50 |
| 48 private final int mapioMagicBoundary; | 51 private final int mapioMagicBoundary; |
| 49 private final int bufferSize; | 52 private final int bufferSize, mapioBufSize; |
| 50 private final SessionContext context; | 53 private final SessionContext context; |
| 51 | 54 |
| 52 public DataAccessProvider(SessionContext ctx) { | 55 public DataAccessProvider(SessionContext ctx) { |
| 53 this(ctx, getConfigOption(ctx, CFG_PROPERTY_MAPIO_LIMIT, DEFAULT_MAPIO_LIMIT), getConfigOption(ctx, CFG_PROPERTY_FILE_BUFFER_SIZE, DEFAULT_FILE_BUFFER)); | 56 context = ctx; |
| 57 PropertyMarshal pm = new PropertyMarshal(ctx); | |
| 58 mapioMagicBoundary = pm.getInt(CFG_PROPERTY_MAPIO_LIMIT, DEFAULT_MAPIO_LIMIT); | |
| 59 bufferSize = pm.getInt(CFG_PROPERTY_FILE_BUFFER_SIZE, DEFAULT_FILE_BUFFER); | |
| 60 mapioBufSize = pm.getInt(CFG_PROPERTY_MAPIO_BUFFER_SIZE, DEFAULT_MAPIO_BUFFER); | |
| 54 } | 61 } |
| 55 | 62 |
| 56 private static int getConfigOption(SessionContext ctx, String optName, int defaultValue) { | 63 public DataAccessProvider(SessionContext ctx, int mapioBoundary, int regularBufferSize, int mapioBufferSize) { |
| 57 Object v = ctx.getProperty(optName, defaultValue); | |
| 58 if (false == v instanceof Number) { | |
| 59 v = Integer.parseInt(v.toString()); | |
| 60 } | |
| 61 return ((Number) v).intValue(); | |
| 62 } | |
| 63 | |
| 64 public DataAccessProvider(SessionContext ctx, int mapioBoundary, int regularBufferSize) { | |
| 65 context = ctx; | 64 context = ctx; |
| 66 mapioMagicBoundary = mapioBoundary == 0 ? Integer.MAX_VALUE : mapioBoundary; | 65 mapioMagicBoundary = mapioBoundary == 0 ? Integer.MAX_VALUE : mapioBoundary; |
| 67 bufferSize = regularBufferSize; | 66 bufferSize = regularBufferSize; |
| 67 mapioBufSize = mapioBufferSize; | |
| 68 } | 68 } |
| 69 | 69 |
| 70 public DataAccess create(File f) { | 70 public DataAccess create(File f) { |
| 71 if (!f.exists()) { | 71 if (!f.exists()) { |
| 72 return new DataAccess(); | 72 return new DataAccess(); |
| 74 try { | 74 try { |
| 75 FileChannel fc = new FileInputStream(f).getChannel(); | 75 FileChannel fc = new FileInputStream(f).getChannel(); |
| 76 long flen = fc.size(); | 76 long flen = fc.size(); |
| 77 if (flen > mapioMagicBoundary) { | 77 if (flen > mapioMagicBoundary) { |
| 78 // TESTS: bufLen of 1024 was used to test MemMapFileAccess | 78 // TESTS: bufLen of 1024 was used to test MemMapFileAccess |
| 79 int mapioBufSize = getConfigOption(context, CFG_PROPERTY_MAPIO_BUFFER_SIZE, DEFAULT_MAPIO_BUFFER); | |
| 80 return new MemoryMapFileAccess(fc, flen, mapioBufSize, context.getLog()); | 79 return new MemoryMapFileAccess(fc, flen, mapioBufSize, context.getLog()); |
| 81 } else { | 80 } else { |
| 82 // XXX once implementation is more or less stable, | 81 // XXX once implementation is more or less stable, |
| 83 // may want to try ByteBuffer.allocateDirect() to see | 82 // may want to try ByteBuffer.allocateDirect() to see |
| 84 // if there's any performance gain. | 83 // if there's any performance gain. |
| 86 // TESTS: bufferSize of 100 was used to check buffer underflow states when readBytes reads chunks bigger than bufSize | 85 // TESTS: bufferSize of 100 was used to check buffer underflow states when readBytes reads chunks bigger than bufSize |
| 87 return new FileAccess(fc, flen, bufferSize, useDirectBuffer, context.getLog()); | 86 return new FileAccess(fc, flen, bufferSize, useDirectBuffer, context.getLog()); |
| 88 } | 87 } |
| 89 } catch (IOException ex) { | 88 } catch (IOException ex) { |
| 90 // unlikely to happen, we've made sure file exists. | 89 // unlikely to happen, we've made sure file exists. |
| 91 context.getLog().error(getClass(), ex, null); | 90 context.getLog().dump(getClass(), Error, ex, null); |
| 92 } | 91 } |
| 93 return new DataAccess(); // non-null, empty. | 92 return new DataAccess(); // non-null, empty. |
| 94 } | 93 } |
| 95 | 94 |
| 96 private static class MemoryMapFileAccess extends DataAccess { | 95 private static class MemoryMapFileAccess extends DataAccess { |
| 175 if (i == 2) { | 174 if (i == 2) { |
| 176 throw ex; | 175 throw ex; |
| 177 } | 176 } |
| 178 if (i == 0) { | 177 if (i == 0) { |
| 179 // if first attempt failed, try to free some virtual memory, see Issue 30 for details | 178 // if first attempt failed, try to free some virtual memory, see Issue 30 for details |
| 180 logFacility.warn(getClass(), ex, "Memory-map failed, gonna try gc() to free virtual memory"); | 179 logFacility.dump(getClass(), Warn, ex, "Memory-map failed, gonna try gc() to free virtual memory"); |
| 181 } | 180 } |
| 182 try { | 181 try { |
| 183 buffer = null; | 182 buffer = null; |
| 184 System.gc(); | 183 System.gc(); |
| 185 Thread.sleep((1+i) * 1000); | 184 Thread.sleep((1+i) * 1000); |
| 186 } catch (Throwable t) { | 185 } catch (Throwable t) { |
| 187 logFacility.error(getClass(), t, "Bad luck"); | 186 logFacility.dump(getClass(), Error, t, "Bad luck"); |
| 188 } | 187 } |
| 189 } | 188 } |
| 190 } | 189 } |
| 191 } | 190 } |
| 192 | 191 |
| 228 buffer = null; | 227 buffer = null; |
| 229 if (fileChannel != null) { | 228 if (fileChannel != null) { |
| 230 try { | 229 try { |
| 231 fileChannel.close(); | 230 fileChannel.close(); |
| 232 } catch (IOException ex) { | 231 } catch (IOException ex) { |
| 233 logFacility.debug(getClass(), ex, null); | 232 logFacility.dump(getClass(), Warn, ex, null); |
| 234 } | 233 } |
| 235 fileChannel = null; | 234 fileChannel = null; |
| 236 } | 235 } |
| 237 } | 236 } |
| 238 } | 237 } |
| 362 } | 361 } |
| 363 if (fileChannel != null) { | 362 if (fileChannel != null) { |
| 364 try { | 363 try { |
| 365 fileChannel.close(); | 364 fileChannel.close(); |
| 366 } catch (IOException ex) { | 365 } catch (IOException ex) { |
| 367 logFacility.debug(getClass(), ex, null); | 366 logFacility.dump(getClass(), Warn, ex, null); |
| 368 } | 367 } |
| 369 fileChannel = null; | 368 fileChannel = null; |
| 370 } | 369 } |
| 371 } | 370 } |
| 372 } | 371 } |
