/* * Copyright 2015 Edward Capriolo * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package io.teknek.nibiru.engine; import io.teknek.nibiru.Store; import io.teknek.nibiru.TimeSource; import io.teknek.nibiru.TimeSourceImpl; import io.teknek.nibiru.Token; import io.teknek.nibiru.engine.atom.AtomKey; import io.teknek.nibiru.engine.atom.AtomValue; import io.teknek.nibiru.engine.atom.ColumnValue; import io.teknek.nibiru.io.CountingBufferedOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.HashMap; import java.util.Map; public class CommitLog { public static final char END_TOKEN = '\1'; private final Store columnFamily; private final String tableId; private CountingBufferedOutputStream ssOutputStream; private long lastOffset = 0; private File sstableFile; private TimeSource timeSource = new TimeSourceImpl(); public static final String EXTENSION = "commitlog"; public CommitLog(Store cf){ this.columnFamily = cf; tableId = String.valueOf(timeSource.getTimeInMillis()); } public static File getCommitLogDirectoryForColumnFamily(Store columnFamily){ return new File(columnFamily.getKeyspace().getConfiguration() .getCommitlogDirectory(), columnFamily.getStoreMetadata() .getName()); } public void open() throws FileNotFoundException { if (!getCommitLogDirectoryForColumnFamily(columnFamily).exists()){ boolean mkdir = getCommitLogDirectoryForColumnFamily(columnFamily).mkdirs(); if (!mkdir){ throw new RuntimeException("Could not create directory " + getCommitLogDirectoryForColumnFamily(columnFamily) ); } } sstableFile = new File(getCommitLogDirectoryForColumnFamily(columnFamily), tableId + "." + EXTENSION); ssOutputStream = new CountingBufferedOutputStream(new FileOutputStream(sstableFile)); } public synchronized void write(Token rowkey, AtomKey column, String value, long stamp, long ttl) throws IOException { Map<AtomKey, AtomValue> columns = new HashMap<>(); ColumnValue v = new ColumnValue(value, stamp, System.currentTimeMillis(), ttl); columns.put(column, v); ssOutputStream.writeAndCount(SsTableReader.START_RECORD); SsTableStreamWriter.writeToken(rowkey, ssOutputStream); SsTableStreamWriter.writeRowkey(rowkey, ssOutputStream); SsTableStreamWriter.writeColumns(columns, ssOutputStream); if (columnFamily.getStoreMetadata().getCommitlogFlushBytes() > 0 && ssOutputStream.getWrittenOffset() - lastOffset > columnFamily.getStoreMetadata().getCommitlogFlushBytes()){ ssOutputStream.flush(); lastOffset = ssOutputStream.getWrittenOffset(); } } public void delete() throws IOException { ssOutputStream.close(); sstableFile.delete(); } public void close() throws IOException { ssOutputStream.close(); } }