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.yetus.audience.InterfaceAudience;
026
027/**
028 * A singleton store segment factory. Generate concrete store segments.
029 */
030@InterfaceAudience.Private
031public final class SegmentFactory {
032
033  private SegmentFactory() {
034  }
035
036  private static SegmentFactory instance = new SegmentFactory();
037
038  public static SegmentFactory instance() {
039    return instance;
040  }
041
042  // create composite immutable segment from a list of segments
043  // for snapshot consisting of multiple segments
044  public CompositeImmutableSegment createCompositeImmutableSegment(final CellComparator comparator,
045    List<ImmutableSegment> segments) {
046    return new CompositeImmutableSegment(comparator, segments);
047  }
048
049  // create new flat immutable segment from compacting old immutable segments
050  // for compaction
051  public ImmutableSegment createImmutableSegmentByCompaction(final Configuration conf,
052    final CellComparator comparator, MemStoreSegmentsIterator iterator, int numOfCells,
053    CompactingMemStore.IndexType idxType, MemStoreCompactionStrategy.Action action)
054    throws IOException {
055
056    MemStoreLAB memStoreLAB = MemStoreLAB.newInstance(conf);
057    return createImmutableSegment(conf, comparator, iterator, memStoreLAB, numOfCells, action,
058      idxType);
059  }
060
061  /**
062   * create empty immutable segment for initializations This ImmutableSegment is used as a place
063   * holder for snapshot in Memstore. It won't flush later, So it is not necessary to record the
064   * initial size for it.
065   * @param comparator comparator
066   */
067  public ImmutableSegment createImmutableSegment(CellComparator comparator) {
068    MutableSegment segment = generateMutableSegment(null, comparator, null, null);
069    return createImmutableSegment(segment, null);
070  }
071
072  // create not-flat immutable segment from mutable segment
073  public ImmutableSegment createImmutableSegment(MutableSegment segment,
074    MemStoreSizing memstoreSizing) {
075    return new CSLMImmutableSegment(segment, memstoreSizing);
076  }
077
078  // create mutable segment
079  public MutableSegment createMutableSegment(final Configuration conf, CellComparator comparator,
080    MemStoreSizing memstoreSizing) {
081    MemStoreLAB memStoreLAB = MemStoreLAB.newInstance(conf);
082    return generateMutableSegment(conf, comparator, memStoreLAB, memstoreSizing);
083  }
084
085  // create new flat immutable segment from merging old immutable segments
086  // for merge
087  public ImmutableSegment createImmutableSegmentByMerge(final Configuration conf,
088    final CellComparator comparator, MemStoreSegmentsIterator iterator, int numOfCells,
089    List<ImmutableSegment> segments, CompactingMemStore.IndexType idxType,
090    MemStoreCompactionStrategy.Action action) throws IOException {
091
092    MemStoreLAB memStoreLAB = getMergedMemStoreLAB(conf, segments);
093    return createImmutableSegment(conf, comparator, iterator, memStoreLAB, numOfCells, action,
094      idxType);
095
096  }
097
098  // create flat immutable segment from non-flat immutable segment
099  // for flattening
100  public ImmutableSegment createImmutableSegmentByFlattening(CSLMImmutableSegment segment,
101    CompactingMemStore.IndexType idxType, MemStoreSizing memstoreSizing,
102    MemStoreCompactionStrategy.Action action) {
103    ImmutableSegment res = null;
104    switch (idxType) {
105      case CHUNK_MAP:
106        res = new CellChunkImmutableSegment(segment, memstoreSizing, action);
107        break;
108      case CSLM_MAP:
109        assert false; // non-flat segment can not be the result of flattening
110        break;
111      case ARRAY_MAP:
112        res = new CellArrayImmutableSegment(segment, memstoreSizing, action);
113        break;
114    }
115    return res;
116  }
117
118  // ****** private methods to instantiate concrete store segments **********//
119  private ImmutableSegment createImmutableSegment(final Configuration conf,
120    final CellComparator comparator, MemStoreSegmentsIterator iterator, MemStoreLAB memStoreLAB,
121    int numOfCells, MemStoreCompactionStrategy.Action action,
122    CompactingMemStore.IndexType idxType) {
123
124    ImmutableSegment res = null;
125    switch (idxType) {
126      case CHUNK_MAP:
127        res = new CellChunkImmutableSegment(comparator, iterator, memStoreLAB, numOfCells, action);
128        break;
129      case CSLM_MAP:
130        assert false; // non-flat segment can not be created here
131        break;
132      case ARRAY_MAP:
133        res = new CellArrayImmutableSegment(comparator, iterator, memStoreLAB, numOfCells, action);
134        break;
135    }
136    return res;
137  }
138
139  private MutableSegment generateMutableSegment(final Configuration conf, CellComparator comparator,
140    MemStoreLAB memStoreLAB, MemStoreSizing memstoreSizing) {
141    // TBD use configuration to set type of segment
142    CellSet set = new CellSet(comparator);
143    return new MutableSegment(set, comparator, memStoreLAB, memstoreSizing);
144  }
145
146  private MemStoreLAB getMergedMemStoreLAB(Configuration conf, List<ImmutableSegment> segments) {
147    List<MemStoreLAB> mslabs = new ArrayList<>();
148    if (!conf.getBoolean(MemStoreLAB.USEMSLAB_KEY, MemStoreLAB.USEMSLAB_DEFAULT)) {
149      return null;
150    }
151    for (ImmutableSegment segment : segments) {
152      mslabs.add(segment.getMemStoreLAB());
153    }
154    return new ImmutableMemStoreLAB(mslabs);
155  }
156}