blob: 111dfaaa061dfe26ee51704d91f8c9c0925974c1 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.iotdb.db.schemaengine.schemaregion.mtree.impl.pbtree.schemafile;
import org.apache.iotdb.commons.exception.MetadataException;
import org.apache.iotdb.commons.utils.TestOnly;
import org.apache.iotdb.db.exception.metadata.schemafile.SegmentNotFoundException;
import org.apache.tsfile.utils.ReadWriteIOUtils;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* {@link SchemaFile} manages a collection of SchemaPages, which acts like a segment of index entry
* {@link ISegment} or a collection of wrapped segments.
*/
public abstract class SchemaPage implements ISchemaPage {
// All other attributes are to describe this ByteBuffer
protected final ByteBuffer pageBuffer;
protected final AtomicInteger refCnt;
protected final ReadWriteLock lock;
protected int pageIndex; // only change when register buffer as a new page
protected short spareOffset; // bound of the variable length part in a slotted structure
protected short spareSize; // traces spare space size simultaneously
protected short memberNum; // amount of the member, definition depends on implementation
protected boolean dirtyFlag = false; // any modification turns it true
/** for replacement page state transfer * */
protected SchemaPage(ByteBuffer pageBuffer, AtomicInteger ai, ReadWriteLock rwl) {
this.pageBuffer = pageBuffer;
this.pageBuffer
.limit(this.pageBuffer.capacity())
.position(SchemaFileConfig.PAGE_HEADER_INDEX_OFFSET);
refCnt = ai;
lock = rwl;
pageIndex = ReadWriteIOUtils.readInt(this.pageBuffer);
spareOffset = ReadWriteIOUtils.readShort(this.pageBuffer);
spareSize = ReadWriteIOUtils.readShort(this.pageBuffer);
memberNum = ReadWriteIOUtils.readShort(this.pageBuffer);
}
/** compatible constructor with no existing ref or lock */
protected SchemaPage(ByteBuffer pageBuffer) {
this(pageBuffer, new AtomicInteger(), new ReentrantReadWriteLock());
}
@Override
public AtomicInteger getRefCnt() {
return refCnt;
}
@Override
public int incrementAndGetRefCnt() {
return refCnt.incrementAndGet();
}
@Override
public int decrementAndGetRefCnt() {
return refCnt.decrementAndGet();
}
@Override
public ReadWriteLock getLock() {
return lock;
}
@Override
public void syncPageBuffer() {
this.pageBuffer.limit(this.pageBuffer.capacity());
this.pageBuffer.position(SchemaFileConfig.PAGE_HEADER_INDEX_OFFSET);
ReadWriteIOUtils.write(pageIndex, pageBuffer);
ReadWriteIOUtils.write(spareOffset, pageBuffer);
ReadWriteIOUtils.write(spareSize, pageBuffer);
ReadWriteIOUtils.write(memberNum, pageBuffer);
}
@Override
public void flushPageToChannel(FileChannel channel) throws IOException {
this.pageBuffer.clear();
channel.write(pageBuffer, SchemaFile.getPageAddress(pageIndex));
dirtyFlag = false;
}
@Override
public boolean isDirtyPage() {
return dirtyFlag;
}
@Override
public void setDirtyFlag() {
this.dirtyFlag = true;
}
@Override
public void flushPageToStream(OutputStream stream) throws IOException {
if (pageIndex < 0) {
// mark as check point
stream.write(new byte[] {(byte) pageIndex});
return;
}
this.pageBuffer.clear();
stream.write(pageBuffer.array());
}
@Override
public int getPageIndex() {
return pageIndex;
}
@Override
public void setPageIndex(int pid) {
pageIndex = pid;
this.pageBuffer.clear();
this.pageBuffer.position(SchemaFileConfig.PAGE_HEADER_INDEX_OFFSET);
ReadWriteIOUtils.write(pageIndex, pageBuffer);
this.pageBuffer.clear();
}
@Override
public int getSubIndex() {
return -1;
}
@Override
public void setSubIndex(int pid) {}
@Override
public ISegment<Integer, Integer> getAsInternalPage() {
return null;
}
@Override
public ISegment<String, String> getAsAliasIndexPage() {
return null;
}
@Override
public ISegmentedPage getAsSegmentedPage() {
return null;
}
// for better performance when split
@Override
public ByteBuffer getEntireSegmentSlice() throws MetadataException {
return null;
}
@Override
@TestOnly
public WrappedSegment getSegmentOnTest(short idx) throws SegmentNotFoundException {
return null;
}
@Override
@TestOnly
public void getPageBuffer(ByteBuffer dstBuffer) {
syncPageBuffer();
this.pageBuffer.clear();
dstBuffer.put(this.pageBuffer);
}
}