private static synchronized void deleteFile(DataHandler handler, String fileName) { // synchronize on the database, to avoid concurrent temp file creation / // deletion / backup synchronized (handler.getLobSyncObject()) { FileUtils.delete(fileName); } }
private static String[] getFileList(DataHandler h, String dir) { SmallLRUCache<String, String[]> cache = h.getLobFileListCache(); String[] list; if (cache == null) { list = FileUtils.newDirectoryStream(dir).toArray(new String[0]); } else { synchronized (cache) { list = cache.get(dir); if (list == null) { list = FileUtils.newDirectoryStream(dir).toArray(new String[0]); cache.put(dir, list); } } } return list; }
/** * Rename a map. * * @param map the map * @param newName the new name */ public synchronized void renameMap(BTreeMap<?, ?> map, String newName) { // TODO if (map.isInMemory()) return; checkOpen(); String oldName = map.getName(); if (oldName.equals(newName)) { return; } String fileName = (String) map.config.get("storageName"); if (fileName != null) { fileName = fileName + File.separator + newName; if (!FileUtils.exists(fileName)) FileUtils.createDirectories(fileName); close(); FileUtils.move(btreeStorageName, fileName); // btreeStorageName = fileName; } }
private static String getFileNamePrefix(String path, int objectId) { String name; int f = objectId % SysProperties.LOB_FILES_PER_DIRECTORY; if (f > 0) { name = SysProperties.FILE_SEPARATOR + objectId; } else { name = ""; } objectId /= SysProperties.LOB_FILES_PER_DIRECTORY; while (objectId > 0) { f = objectId % SysProperties.LOB_FILES_PER_DIRECTORY; name = SysProperties.FILE_SEPARATOR + f + Constants.SUFFIX_LOBS_DIRECTORY + name; objectId /= SysProperties.LOB_FILES_PER_DIRECTORY; } name = FileUtils.toRealPath(path + Constants.SUFFIX_LOBS_DIRECTORY + name); return name; }
/** * Create and open the storage. * * @param map the map to use * @throws IllegalStateException if the file is corrupt, or an exception occurred while opening * @throws IllegalArgumentException if the directory does not exist */ protected BTreeStorage(BTreeMap<Object, Object> map) { this.map = map; btreeStorageName = map.getBTreeStorageName(); Map<String, Object> config = map.config; Object value = config.get("retentionTime"); retentionTime = value == null ? 45000 : (Long) value; value = config.get("versionsToKeep"); versionsToKeep = value == null ? 5 : (Integer) value; reuseSpace = config.containsKey("reuseSpace"); value = config.get("pageSplitSize"); pageSplitSize = value != null ? (Integer) value : (map.isInMemory() ? 4 * 1024 : 16 * 1024); backgroundExceptionHandler = (UncaughtExceptionHandler) config.get("backgroundExceptionHandler"); if (map.isInMemory()) { cache = null; compressionLevel = 0; autoCompactFillRate = 0; autoCommitMemory = 0; createVersion = 0; creationTime = getTimeAbsolute(); return; } value = config.get("cacheSize"); int mb = value == null ? 16 : (Integer) value; if (mb > 0) { CacheLongKeyLIRS.Config cc = new CacheLongKeyLIRS.Config(); cc.maxMemory = mb * 1024L * 1024L; cache = new CacheLongKeyLIRS<BTreePage>(cc); } else { cache = null; } value = config.get("compress"); compressionLevel = value == null ? 0 : (Integer) value; value = config.get("autoCompactFillRate"); autoCompactFillRate = value == null ? 50 : (Integer) value; value = config.get("autoCommitBufferSize"); int kb = value == null ? 1024 : (Integer) value; // 19 KB memory is about 1 KB storage autoCommitMemory = kb * 1024 * 19; lastChunkId = 0; long createVersion = Long.MAX_VALUE; if (!FileUtils.exists(btreeStorageName)) FileUtils.createDirectories(btreeStorageName); String[] files = new File(btreeStorageName).list(); if (files != null && files.length > 0) { for (String f : files) { int id = Integer.parseInt(f.substring(0, f.length() - AOStorage.SUFFIX_AO_FILE_LENGTH)); if (id > lastChunkId) lastChunkId = id; if (id < createVersion) createVersion = id; } } if (createVersion == Long.MAX_VALUE) createVersion = 0; this.createVersion = createVersion; try { if (lastChunkId > 0) readLastChunk(); } catch (IllegalStateException e) { panic(e); } if (lastChunk != null) creationTime = lastChunk.creationTime; else creationTime = getTimeAbsolute(); lastCommitTime = getTimeSinceCreation(); }
private static synchronized void renameFile(DataHandler handler, String oldName, String newName) { synchronized (handler.getLobSyncObject()) { FileUtils.move(oldName, newName); } }
private static int getNewObjectId(DataHandler h) { String path = h.getDatabasePath(); if ((path != null) && (path.length() == 0)) { path = new File(Utils.getProperty("java.io.tmpdir", "."), SysProperties.PREFIX_TEMP_FILE) .getAbsolutePath(); } int newId = 0; int lobsPerDir = SysProperties.LOB_FILES_PER_DIRECTORY; while (true) { String dir = getFileNamePrefix(path, newId); String[] list = getFileList(h, dir); int fileCount = 0; boolean[] used = new boolean[lobsPerDir]; for (String name : list) { if (name.endsWith(Constants.SUFFIX_DB_FILE)) { name = FileUtils.getName(name); String n = name.substring(0, name.indexOf('.')); int id; try { id = Integer.parseInt(n); } catch (NumberFormatException e) { id = -1; } if (id > 0) { fileCount++; used[id % lobsPerDir] = true; } } } int fileId = -1; if (fileCount < lobsPerDir) { for (int i = 1; i < lobsPerDir; i++) { if (!used[i]) { fileId = i; break; } } } if (fileId > 0) { newId += fileId; invalidateFileList(h, dir); break; } if (newId > Integer.MAX_VALUE / lobsPerDir) { // this directory path is full: start from zero newId = 0; dirCounter = MathUtils.randomInt(lobsPerDir - 1) * lobsPerDir; } else { // calculate the directory. // start with 1 (otherwise we don't know the number of // directories). // it doesn't really matter what directory is used, it might as // well be random (but that would generate more directories): // int dirId = RandomUtils.nextInt(lobsPerDir - 1) + 1; int dirId = (dirCounter++ / (lobsPerDir - 1)) + 1; newId = newId * lobsPerDir; newId += dirId * lobsPerDir; } } return newId; }