public void close() { if (shuttingDown.getAndSet(true)) { return; } mutex.lock(); try { while (backgroundCompaction != null) { backgroundCondition.awaitUninterruptibly(); } } finally { mutex.unlock(); } compactionExecutor.shutdown(); try { compactionExecutor.awaitTermination(1, TimeUnit.DAYS); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } try { versions.destroy(); } catch (IOException ignored) { } try { log.close(); } catch (IOException ignored) { } tableCache.close(); dbLock.release(); }
private void finishCompactionOutputFile(CompactionState compactionState) throws IOException { Preconditions.checkNotNull(compactionState, "compactionState is null"); Preconditions.checkArgument(compactionState.outfile != null); Preconditions.checkArgument(compactionState.builder != null); long outputNumber = compactionState.currentFileNumber; Preconditions.checkArgument(outputNumber != 0); long currentEntries = compactionState.builder.getEntryCount(); compactionState.builder.finish(); long currentBytes = compactionState.builder.getFileSize(); compactionState.currentFileSize = currentBytes; compactionState.totalBytes += currentBytes; FileMetaData currentFileMetaData = new FileMetaData( compactionState.currentFileNumber, compactionState.currentFileSize, compactionState.currentSmallest, compactionState.currentLargest); compactionState.outputs.add(currentFileMetaData); compactionState.builder = null; compactionState.outfile.force(true); compactionState.outfile.close(); compactionState.outfile = null; if (currentEntries > 0) { // Verify that the table is usable tableCache.newIterator(outputNumber); } }
private void deleteObsoleteFiles() { Preconditions.checkState(mutex.isHeldByCurrentThread()); // Make a set of all of the live files List<Long> live = newArrayList(this.pendingOutputs); for (FileMetaData fileMetaData : versions.getLiveFiles()) { live.add(fileMetaData.getNumber()); } for (File file : Filename.listFiles(databaseDir)) { FileInfo fileInfo = Filename.parseFileName(file); if (fileInfo == null) continue; long number = fileInfo.getFileNumber(); boolean keep = true; switch (fileInfo.getFileType()) { case LOG: keep = ((number >= versions.getLogNumber()) || (number == versions.getPrevLogNumber())); break; case DESCRIPTOR: // Keep my manifest file, and any newer incarnations' // (in case there is a race that allows other incarnations) keep = (number >= versions.getManifestFileNumber()); break; case TABLE: keep = live.contains(number); break; case TEMP: // Any temp files that are currently being written to must // be recorded in pending_outputs_, which is inserted into "live" keep = live.contains(number); break; case CURRENT: case DB_LOCK: case INFO_LOG: keep = true; break; } if (!keep) { if (fileInfo.getFileType() == FileType.TABLE) { tableCache.evict(number); } // todo info logging system needed // Log(options_.info_log, "Delete type=%d #%lld\n", // int(type), // static_cast < unsigned long long>(number)); file.delete(); } } }
private FileMetaData buildTable(SeekingIterable<InternalKey, Slice> data, long fileNumber) throws IOException { File file = new File(databaseDir, Filename.tableFileName(fileNumber)); try { InternalKey smallest = null; InternalKey largest = null; FileChannel channel = new FileOutputStream(file).getChannel(); try { TableBuilder tableBuilder = new TableBuilder(options, channel, new InternalUserComparator(internalKeyComparator)); for (Entry<InternalKey, Slice> entry : data) { // update keys InternalKey key = entry.getKey(); if (smallest == null) { smallest = key; } largest = key; tableBuilder.add(key.encode(), entry.getValue()); } tableBuilder.finish(); } finally { try { channel.force(true); } finally { channel.close(); } } if (smallest == null) { return null; } FileMetaData fileMetaData = new FileMetaData(fileNumber, file.length(), smallest, largest); // verify table can be opened tableCache.newIterator(fileMetaData); pendingOutputs.remove(fileNumber); return fileMetaData; } catch (IOException e) { file.delete(); throw e; } }