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