001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.regionserver;
019
020import java.io.IOException;
021import java.util.ArrayList;
022import java.util.List;
023import org.apache.hadoop.conf.Configuration;
024import org.apache.hadoop.hbase.CellComparator;
025import org.apache.hadoop.hbase.ExtendedCell;
026import org.apache.yetus.audience.InterfaceAudience;
027
028/**
029 * A singleton store segment factory. Generate concrete store segments.
030 */
031@InterfaceAudience.Private
032public final class SegmentFactory {
033
034  private SegmentFactory() {
035  }
036
037  private static SegmentFactory instance = new SegmentFactory();
038
039  public static SegmentFactory instance() {
040    return instance;
041  }
042
043  // create composite immutable segment from a list of segments
044  // for snapshot consisting of multiple segments
045  public CompositeImmutableSegment createCompositeImmutableSegment(final CellComparator comparator,
046    List<ImmutableSegment> segments) {
047    return new CompositeImmutableSegment(comparator, segments);
048  }
049
050  // create new flat immutable segment from compacting old immutable segments
051  // for compaction
052  public ImmutableSegment createImmutableSegmentByCompaction(final Configuration conf,
053    final CellComparator comparator, MemStoreSegmentsIterator iterator, int numOfCells,
054    CompactingMemStore.IndexType idxType, MemStoreCompactionStrategy.Action action)
055    throws IOException {
056
057    MemStoreLAB memStoreLAB = MemStoreLAB.newInstance(conf);
058    return createImmutableSegment(conf, comparator, iterator, memStoreLAB, numOfCells, action,
059      idxType);
060  }
061
062  /**
063   * create empty immutable segment for initializations This ImmutableSegment is used as a place
064   * holder for snapshot in Memstore. It won't flush later, So it is not necessary to record the
065   * initial size for it.
066   * @param comparator comparator
067   */
068  public ImmutableSegment createImmutableSegment(CellComparator comparator) {
069    MutableSegment segment = generateMutableSegment(null, comparator, null, null);
070    return createImmutableSegment(segment, null);
071  }
072
073  // create not-flat immutable segment from mutable segment
074  public ImmutableSegment createImmutableSegment(MutableSegment segment,
075    MemStoreSizing memstoreSizing) {
076    return new CSLMImmutableSegment(segment, memstoreSizing);
077  }
078
079  // create mutable segment
080  public MutableSegment createMutableSegment(final Configuration conf, CellComparator comparator,
081    MemStoreSizing memstoreSizing) {
082    MemStoreLAB memStoreLAB = MemStoreLAB.newInstance(conf);
083    return generateMutableSegment(conf, comparator, memStoreLAB, memstoreSizing);
084  }
085
086  // create new flat immutable segment from merging old immutable segments
087  // for merge
088  public ImmutableSegment createImmutableSegmentByMerge(final Configuration conf,
089    final CellComparator comparator, MemStoreSegmentsIterator iterator, int numOfCells,
090    List<ImmutableSegment> segments, CompactingMemStore.IndexType idxType,
091    MemStoreCompactionStrategy.Action action) throws IOException {
092
093    MemStoreLAB memStoreLAB = getMergedMemStoreLAB(conf, segments);
094    return createImmutableSegment(conf, comparator, iterator, memStoreLAB, numOfCells, action,
095      idxType);
096
097  }
098
099  // create flat immutable segment from non-flat immutable segment
100  // for flattening
101  public ImmutableSegment createImmutableSegmentByFlattening(CSLMImmutableSegment segment,
102    CompactingMemStore.IndexType idxType, MemStoreSizing memstoreSizing,
103    MemStoreCompactionStrategy.Action action) {
104    ImmutableSegment res = null;
105    switch (idxType) {
106      case CHUNK_MAP:
107        res = new CellChunkImmutableSegment(segment, memstoreSizing, action);
108        break;
109      case CSLM_MAP:
110        assert false; // non-flat segment can not be the result of flattening
111        break;
112      case ARRAY_MAP:
113        res = new CellArrayImmutableSegment(segment, memstoreSizing, action);
114        break;
115    }
116    return res;
117  }
118
119  // ****** private methods to instantiate concrete store segments **********//
120  private ImmutableSegment createImmutableSegment(final Configuration conf,
121    final CellComparator comparator, MemStoreSegmentsIterator iterator, MemStoreLAB memStoreLAB,
122    int numOfCells, MemStoreCompactionStrategy.Action action,
123    CompactingMemStore.IndexType idxType) {
124
125    ImmutableSegment res = null;
126    switch (idxType) {
127      case CHUNK_MAP:
128        res = new CellChunkImmutableSegment(comparator, iterator, memStoreLAB, numOfCells, action);
129        break;
130      case CSLM_MAP:
131        assert false; // non-flat segment can not be created here
132        break;
133      case ARRAY_MAP:
134        res = new CellArrayImmutableSegment(comparator, iterator, memStoreLAB, numOfCells, action);
135        break;
136    }
137    return res;
138  }
139
140  private MutableSegment generateMutableSegment(final Configuration conf, CellComparator comparator,
141    MemStoreLAB memStoreLAB, MemStoreSizing memstoreSizing) {
142    // TBD use configuration to set type of segment
143    CellSet<ExtendedCell> set = new CellSet<>(comparator);
144    return new MutableSegment(set, comparator, memStoreLAB, memstoreSizing);
145  }
146
147  private MemStoreLAB getMergedMemStoreLAB(Configuration conf, List<ImmutableSegment> segments) {
148    List<MemStoreLAB> mslabs = new ArrayList<>();
149    if (!conf.getBoolean(MemStoreLAB.USEMSLAB_KEY, MemStoreLAB.USEMSLAB_DEFAULT)) {
150      return null;
151    }
152    for (ImmutableSegment segment : segments) {
153      mslabs.add(segment.getMemStoreLAB());
154    }
155    return new ImmutableMemStoreLAB(mslabs);
156  }
157}