Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.hbase.classification.InterfaceAudience;


/**
* Class for determining the "size" of a class, an attempt to calculate the
* actual bytes that an object of this class will occupy in memory
Expand Down Expand Up @@ -83,6 +84,18 @@ public class ClassSize {
/** Overhead for ConcurrentSkipListMap Entry */
public static final int CONCURRENT_SKIPLISTMAP_ENTRY;

/** Overhead for CellArrayMap */
public static final int CELL_ARRAY_MAP;

/** Overhead for CellArrayMap */
public static final int CELL_CHUNK_MAP;

/** Overhead for Cell Array Entry */
public static final int CELL_ARRAY_MAP_ENTRY;

/** Overhead for CellChunkMap Entry */
public static final int CELL_CHUNK_MAP_ENTRY;

/** Overhead for ReentrantReadWriteLock */
public static final int REENTRANT_LOCK;

Expand All @@ -108,7 +121,7 @@ public class ClassSize {
public static final int TIMERANGE_TRACKER;

/** Overhead for CellSkipListSet */
public static final int CELL_SKIPLIST_SET;
public static final int CELL_SET;

public static final int STORE_SERVICES;

Expand Down Expand Up @@ -174,10 +187,20 @@ public class ClassSize {
// The size changes from jdk7 to jdk8, estimate the size rather than use a conditional
CONCURRENT_SKIPLISTMAP = (int) estimateBase(ConcurrentSkipListMap.class, false);

CELL_ARRAY_MAP = align(2*OBJECT + Bytes.SIZEOF_LONG + Bytes.SIZEOF_BOOLEAN
+ 2*Bytes.SIZEOF_INT + REFERENCE);

CELL_CHUNK_MAP = align(2*OBJECT + Bytes.SIZEOF_LONG + Bytes.SIZEOF_BOOLEAN
+ 4*Bytes.SIZEOF_INT + 2*REFERENCE);

CONCURRENT_SKIPLISTMAP_ENTRY = align(
align(OBJECT + (3 * REFERENCE)) + /* one node per entry */
align((OBJECT + (3 * REFERENCE))/2)); /* one index per two entries */

CELL_ARRAY_MAP_ENTRY = align(OBJECT + 2*REFERENCE + 2*Bytes.SIZEOF_INT);

CELL_CHUNK_MAP_ENTRY = align(3*Bytes.SIZEOF_INT);

REENTRANT_LOCK = align(OBJECT + (3 * REFERENCE));

ATOMIC_LONG = align(OBJECT + Bytes.SIZEOF_LONG);
Expand All @@ -194,7 +217,7 @@ public class ClassSize {

TIMERANGE_TRACKER = align(ClassSize.OBJECT + Bytes.SIZEOF_LONG * 2);

CELL_SKIPLIST_SET = align(OBJECT + REFERENCE);
CELL_SET = align(OBJECT + REFERENCE);

STORE_SERVICES = align(OBJECT + REFERENCE + ATOMIC_LONG);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,14 @@ public abstract class AbstractMemStore implements MemStore {

public final static long DEEP_OVERHEAD = ClassSize.align(FIXED_OVERHEAD +
2 * (ClassSize.ATOMIC_LONG + ClassSize.TIMERANGE_TRACKER +
ClassSize.CELL_SKIPLIST_SET + ClassSize.CONCURRENT_SKIPLISTMAP));
ClassSize.CELL_SET + ClassSize.CONCURRENT_SKIPLISTMAP));


protected AbstractMemStore(final Configuration conf, final CellComparator c) {
this.conf = conf;
this.comparator = c;
resetCellSet();
this.snapshot = SegmentFactory.instance().createImmutableSegment(conf, c, 0);
this.snapshot = SegmentFactory.instance().createImmutableSegment(c, 0);
this.snapshotId = NO_SNAPSHOT_ID;
}

Expand Down Expand Up @@ -206,7 +206,8 @@ public long heapSize() {
*/
@Override
public List<KeyValueScanner> getScanners(long readPt) throws IOException {
return Collections.<KeyValueScanner> singletonList(new MemStoreScanner(this, readPt));
return Collections.<KeyValueScanner> singletonList(
new MemStoreScanner(getComparator(), getListOfScanners(readPt)));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/**
*
* 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, Cellersion 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 CellIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.hadoop.hbase.regionserver;

import java.util.Comparator;
import org.apache.hadoop.hbase.Cell;

/**
* CellArrayMap is a simple array of Cells and can be allocated only using on-heap.
* In contrast, CellChunkMap can be also allocated off-heap.
* As all java arrays CellArrayMap's array of references pointing to Cell objects.
*/
public class CellArrayMap extends CellFlatMap {

private final Cell[] block;

/* The Cells Array is created only when CellArrayMap is created, all sub-CellBlocks use
* boundary indexes. The given Cell array must be ordered. */
public CellArrayMap(Comparator<? super Cell> comparator, Cell[] b, int min, int max, boolean d) {
super(comparator,min,max,d);
this.block = b;
}

/* To be used by base class only to create a sub-CellFlatMap */
@Override
protected CellFlatMap createSubCellFlatMap(Comparator<? super Cell> comparator, int min, int max,
boolean d) {
return new CellArrayMap(comparator,this.block,min,max,d);
}

@Override
protected Cell getCell(int i) {
if(i<minCellIdx && i>=maxCellIdx) return null;
return block[i];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/**
*
* 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, Cellersion 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 CellIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.hadoop.hbase.regionserver;

import java.util.Comparator;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.util.Bytes;



/**
* CellChunkMap is a byte array holding all that is needed to access a Cell, which
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great documentation!

* is actually saved on another deeper byte array.
* Per Cell we have a reference to this deeper byte array B, offset in bytes in B (integer),
* and length in bytes in B (integer). In order to save reference to byte array we use the Chunk's
* indexes given by MSLAB (also integer).
*
* The CellChunkMap memory layout relevant to a deeper byte array B:
*
* <----------------- first Cell ---------------------> <-------------- second Cell --- ...
* ------------------------------------------------------------------------------------- ...
* | integer = x bytes | integer = x bytes | integer = x bytes | integer = x bytes |
* | reference to B | offset in B where | length of Cell's | reference to may be| ...
* | holding Cell data | Cell's data starts| data in B | another byte array |
* ------------------------------------------------------------------------------------- ...
*/
public class CellChunkMap extends CellFlatMap {
// TODO: once Chunk class is out of HeapMemStoreLAB class we are going to use MemStoreLAB and
// not HeapMemStoreLAB
private final HeapMemStoreLAB.Chunk[] chunks;
private final HeapMemStoreLAB memStoreLAB;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment here TBD do required changes to use MemStoreLAB instead of HeapMSLAB

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think taking Chunk out of MSLAB should be done in this round? Meanwhile just added a TODO comment there...

private final int numOfCellsInsideChunk;
public static final int BYTES_IN_CELL = 3*(Integer.SIZE / Byte.SIZE); // each Cell requires 3 integers

/* C-tor for increasing map starting from index zero */
/* The given Cell array on given Chunk array must be ordered. */
public CellChunkMap(Comparator<? super Cell> comparator, HeapMemStoreLAB memStoreLAB,
HeapMemStoreLAB.Chunk[] chunks, int max, int chunkSize) {
super(comparator,0,max,false);
this.chunks = chunks;
this.memStoreLAB = memStoreLAB;
this.numOfCellsInsideChunk = chunkSize / BYTES_IN_CELL;
}

/* The given Cell array on given Chunk array must be ordered. */
public CellChunkMap(Comparator<? super Cell> comparator, HeapMemStoreLAB memStoreLAB,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add a c'tor with less parameters , e.g. min and d that can get default values 0 and false

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

HeapMemStoreLAB.Chunk[] chunks, int min, int max, int chunkSize, boolean d) {
super(comparator,min,max, d);
this.chunks = chunks;
this.memStoreLAB = memStoreLAB;
this.numOfCellsInsideChunk = chunkSize / BYTES_IN_CELL;
}

/* To be used by base class only to create a sub-CellFlatMap */
@Override
protected CellFlatMap createSubCellFlatMap(Comparator<? super Cell> comparator, int min, int max,
boolean d) {
return new CellChunkMap(comparator, this.memStoreLAB, this.chunks, min, max,
this.numOfCellsInsideChunk* BYTES_IN_CELL, d);
}

@Override
protected Cell getCell(int i) {
if(i<minCellIdx && i>=maxCellIdx) return null;

// find correct chunk
int chunkIndex = (i / numOfCellsInsideChunk);
byte[] block = chunks[chunkIndex].getData();
i = i - chunkIndex*numOfCellsInsideChunk;

// find inside chunk
int offsetInBytes = i* BYTES_IN_CELL;
int chunkId = Bytes.toInt(block,offsetInBytes);
int offsetOfCell = Bytes.toInt(block,offsetInBytes+(Integer.SIZE / Byte.SIZE));
int lengthOfCell = Bytes.toInt(block,offsetInBytes+2*(Integer.SIZE / Byte.SIZE));
byte[] chunk = memStoreLAB.translateIdToChunk(chunkId).getData();

Cell result = new KeyValue(chunk, offsetOfCell, lengthOfCell);
return result;
}
}
Loading