Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* 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.flink.runtime.state.gemini.engine.page;
import org.apache.flink.runtime.state.gemini.engine.filecache.InfiniteCapacityFileCache;
import org.apache.flink.runtime.state.gemini.engine.page.compress.GCompressAlgorithm;
import org.apache.flink.shaded.guava18.com.google.common.base.MoreObjects;
import static org.apache.flink.runtime.state.gemini.engine.page.PageConstants.NO_PAGE;
/**
* PageAddress.
*/
public class PageAddress {
private static final byte PAGE_VALID_MASK = (byte) 0x01;
private static final byte LOCAL_VALID_MASK = (byte) 0x02;
private static final byte DFS_VALID_MASK = (byte) 0x04;
private DataPage dataPage;
private volatile long dfsAddress;
private volatile long localAddress;
private volatile long requestCount = 0;
//for disk len indicator.
// TODO onMemDataLen and onDiskDataLen will combine to a Long and GCompressAlgorithm.
private final int onMemDataLen;
private final int checksum;
/**
* Currently only the 3 low bits are used, and the other 5 bits are reserved.
* 1. bit 0: the status of page. 0 is invalid(discarded), and 1 is valid. The
* semantic of invalid here is that the page is no longer in page index, and
* we can not access it through page index later, but it's not guaranteed that
* no access to it later because someone may reference it before it's discarded
* and has not released the reference after it's discarded.
* 2. bit 1: the status of local address, 0 is invalid, and 1 is valid.
* 3. bit 2: the status of dfs address, 0 is invalid, and 1 is valid.
* The semantic of invalid for local/dfs address is that the data pointed by the
* address exists on some storage. It's the duty of file cache to set the status
* of page address. When the page is flushed successfully, it should be set valid,
* when it was evicted or the file contains the data is deleted, it should be set
* invalid. But actually, we may not explicitly set the status to invalid, at least
* in {@link InfiniteCapacityFileCache},
* that's once the status is set valid, it will never been set back to invalid,
* because it's much complicated to find the pages which use the file to be deleted.
* So we need other ways to guarantee the safety:
* 1. if the address status is invalid, do not access the data pointed by the address
* 2. if the status of page and address are both valid, it's safe because we'll not
* release the reference of file and file will not be deleted
* 3. if the status of page is invalid and the address is valid, we use MVCC (access number)
* to delay the deletion of file to ensure the safety.
*/
private volatile byte status;
public PageAddress(long requestCount, DataPage dataPage) {
this.dataPage = dataPage;
this.onMemDataLen = dataPage.getSize();
this.requestCount = requestCount;
// init status: page is used, local and dfs address are both invalid
this.status = 0x01;
this.checksum = dataPage.getCheckSum();
}
public PageAddress(int onMemDataLen, int onDiskDataLen, byte dataLenType, int checksum, long requestCount) {
// TODO: #SR how to set requestCount???
this.status = 0x01;
//TODO we should snapshot this.
this.onMemDataLen = onMemDataLen;
this.requestCount = requestCount;
this.checksum = checksum;
//TODO support compressing when flush.
}
public DataPage getDataPage() {
if (dataPage != null) {
dataPage.addReferenceCount();
}
return dataPage;
}
public DataPage getDataPageNoReference() {
return dataPage;
}
public boolean hasDataPage() {
return dataPage != null;
}
public long getDfsAddress() {
return dfsAddress;
}
public long getLocalAddress() {
return localAddress;
}
public long getVersion() {
return dataPage != null ? dataPage.getVersion() : NO_PAGE;
}
public void setDataPage(DataPage dataPage) {
this.dataPage = dataPage;
}
public void setDfsAddress(long dfsAddress) {
this.dfsAddress = dfsAddress;
}
public void setLocalAddress(long localAddress) {
this.localAddress = localAddress;
}
/**
* Set status of page, true is valid, and false is invalid.
*/
public void setPageStatus(boolean flag) {
byte st = status;
this.status = (byte) (flag ? (st | PAGE_VALID_MASK) : (st & (~PAGE_VALID_MASK)));
}
public boolean isPageValid() {
return (status & PAGE_VALID_MASK) != 0;
}
/**
* Set status of local address, true is valid, and false is invalid.
*/
public void setLocalStatus(boolean flag) {
byte st = status;
this.status = (byte) (flag ? (st | LOCAL_VALID_MASK) : (st & (~LOCAL_VALID_MASK)));
}
public boolean isLocalValid() {
return (status & LOCAL_VALID_MASK) != 0;
}
/**
* Set status of dfs address, true is valid, and false is invalid.
*/
public void setDfsStatus(boolean flag) {
byte st = status;
this.status = (byte) (flag ? (st | DFS_VALID_MASK) : (st & (~DFS_VALID_MASK)));
}
public boolean isDfsValid() {
return (status & DFS_VALID_MASK) != 0;
}
@Override
public String toString() {
MoreObjects.ToStringHelper helper = MoreObjects.toStringHelper(this).
add("dataPage", dataPage).
add("dfsAddress", dfsAddress).
add("localAddress", localAddress).
add("compressCode", getOndiskDataCompressionAlgorithm()).
add("onDiskDataLen", onMemDataLen).
add("onMemDataLen", onMemDataLen).
add("requestCount", this.requestCount);
if (dataPage != null) {
helper.add("compactionCount", dataPage.getCompactionCount());
}
return helper.toString();
}
public int getDataLen() {
return this.onMemDataLen;
}
public int getOnDiskDataLen() {
return onMemDataLen;
}
public GCompressAlgorithm getOndiskDataCompressionAlgorithm() {
return GCompressAlgorithm.None;
}
public void afterFlush(int onDiskDataLen, GCompressAlgorithm gCompressAlgorithm) {
//need lock outside.
//TODO support compressing when flush.
}
public long getRequestCount() {
return this.requestCount;
}
public void addRequestCount(int i) {
this.requestCount += i;
}
public int getChecksum() {
return checksum;
}
}