org.cloudata.core.tabletserver.ValueCollection.java Source code

Java tutorial

Introduction

Here is the source code for org.cloudata.core.tabletserver.ValueCollection.java

Source

/**
 * 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.cloudata.core.tabletserver;

import java.io.DataOutputStream;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.cloudata.core.client.Cell;
import org.cloudata.core.client.CellFilter;
import org.cloudata.core.client.CellValueMatcher;
import org.cloudata.core.client.Row;
import org.cloudata.core.client.RowFilter;
import org.cloudata.core.common.exception.GetFailException;
import org.cloudata.core.tablet.ColumnValue;

/**
 * Cell.Key? ? ?  .
 * ? Cell.Key?  ? value  ?.
 * ??? value timestamp   timestamp desc ? ?.
 * ???  ?  ? ??  ?.
 * @author babokim
 *
 */
public class ValueCollection implements Iterator<ColumnValue> {
    public static final Log LOG = LogFactory.getLog(ValueCollection.class.getName());

    //  protected Cell.Key columnKey;

    protected SortedSet<ColumnValue> columnValues = new TreeSet<ColumnValue>();

    protected Iterator<ColumnValue> iterator;

    public ValueCollection() {

    }

    //  protected ValueCollection(Cell.Key columnKey) {
    //    this.columnKey = columnKey;
    //  }

    public void clear() {
        columnValues.clear();
        iterator = null;
    }

    public void setColumnRecords(SortedSet<ColumnValue> columnValues) {
        this.columnValues = columnValues;
        iterator = columnValues.iterator();
    }

    public void add(ColumnValue columnValue, int numOfVersion) {
        columnValues.add(columnValue);
        fitToNumOfVersion(numOfVersion);
    }

    private void fitToNumOfVersion(int numOfVersion) {
        //0?  
        if (numOfVersion == 0) {
            return;
        }

        int size = columnValues.size();
        if (size > numOfVersion) {
            for (int i = 0; i < (size - numOfVersion); i++) {
                columnValues.remove(columnValues.last());
            }
        }
    }
    //  public String getValueAsString1() {
    //    if(columnValues.size() > 0) {
    //      return columnValues.first().getValueAsString();
    //    } else {
    //      return "";
    //    }
    //  }

    protected ColumnValue getWithDeleted() {
        return columnValues.isEmpty() ? null : columnValues.first();
    }

    protected ColumnValue[] getWithDeleted(RowFilter scanFilter) {
        if (columnValues.isEmpty()) {
            return null;
        }
        //FIXME filter ????(  ? , Searcher?  ? ????
        ColumnValue columnValue = getWithDeleted();
        if (columnValue == null) {
            return null;
        } else {
            return new ColumnValue[] { columnValue };
        }

        //    if(scanFilter.isEmpty()) {
        //      ColumnValue columnValue = getWithDeleted();
        //      if(columnValue == null) {
        //        return null;
        //      } else {
        //        return new ColumnValue[]{columnValue};
        //      }
        //    }
        //    
        //    List<ColumnValue> result = new ArrayList<ColumnValue>();
        //    for(ColumnValue eachColumnResult: columnValues) {
        //      if(eachColumnResult.match(scanFilter)) {
        //        result.add(eachColumnResult);
        //      }
        //    }
        //    
        //    if(result.size() == 0) {
        //      return null;
        //    } else {
        //      return result.toArray(new ColumnValue[result.size()]);
        //    }
    }

    public ColumnValue get() {
        if (!columnValues.isEmpty()) {
            ColumnValue columnValue = columnValues.first();
            if (columnValue.isDeleted())
                return null;

            return columnValue;
        } else {
            return null;
        }
    }

    //  public ColumnValue[] get(ColumnFilter columnFilter) {
    //    if(columnValues.size() == 0) {
    //      return null;
    //    }
    //    ColumnValue columnValue = get();
    //    if(columnValue == null) {
    //      return null;
    //    } else {
    //      return new ColumnValue[]{columnValue};
    //    }
    //  }

    public ColumnValue[] get(int numVersion) {
        if (columnValues.isEmpty()) {
            return null;
        }

        int size = columnValues.size() > numVersion ? numVersion : columnValues.size();

        ColumnValue[] result = new ColumnValue[size];

        int index = 0;
        for (ColumnValue eachColumnRecord : columnValues) {
            result[index++] = eachColumnRecord;
            if (index >= size)
                break;
        }

        return result;
    }

    public ColumnValue getLast() {
        if (!columnValues.isEmpty()) {
            return columnValues.last();
        } else {
            return null;
        }
    }

    public int write(DataOutputStream dataOut) throws IOException {
        int writeBytes = 0;
        //FIXME Map ??   ? ? (, )
        for (ColumnValue eachColumnValue : columnValues) {
            MapFileColumnValue mapFileColumnValue = new MapFileColumnValue();
            copyMapFileColumnValue(eachColumnValue, mapFileColumnValue);
            mapFileColumnValue.write(dataOut);
            writeBytes += mapFileColumnValue.size();
        }
        return writeBytes;
    }

    // ?
    public int getByteSize() throws IOException {
        int writeBytes = 0;
        for (ColumnValue eachColumnValue : columnValues) {
            MapFileColumnValue mapFileColumnValue = new MapFileColumnValue();
            copyMapFileColumnValue(eachColumnValue, mapFileColumnValue);
            writeBytes += mapFileColumnValue.size();
        }
        return writeBytes;
    }

    public static void copyMapFileColumnValue(ColumnValue columnValue, MapFileColumnValue mapFileColumnValue) {
        mapFileColumnValue.setRowKey(columnValue.getRowKey());
        mapFileColumnValue.setCellKey(columnValue.getCellKey());
        mapFileColumnValue.setValue(columnValue.getValue());
        mapFileColumnValue.setTimestamp(columnValue.getTimestamp());
        mapFileColumnValue.setDeleted(columnValue.isDeleted());
    }

    public void addAll(ValueCollection collection, int numOfVersion) {
        if (collection == null)
            return;
        columnValues.addAll(collection.getColumnValues());
        fitToNumOfVersion(numOfVersion);
    }

    public SortedSet<ColumnValue> getColumnValues() {
        return columnValues;
    }

    public boolean isEmpty() {
        return columnValues.isEmpty();
    }

    public int getValueSize() {
        return columnValues.size();
    }

    public void print() {
        System.out.println("\t\t\t-------------------------");
        for (ColumnValue record : columnValues) {
            System.out.println("\t\t\t" + record);
        }
        System.out.println("\t\t\t-------------------------");
    }

    //  public ValueCollection copy(long timestamp) {
    //    ValueCollection copyedValue = new ValueCollection();
    //    if(columnValues.size() == 0) {
    //      return copyedValue;
    //    }
    //    ColumnValue firstRecord = columnValues.first();
    //    ColumnValue filterColumnRecord = new ColumnValue(firstRecord.getRowKey(), firstRecord.getCell.Key(), null, timestamp);
    //
    //    SortedSet<ColumnValue> copyedColumnRecords = columnValues.tailSet(filterColumnRecord);
    //    
    //    copyedValue.setColumnRecords(copyedColumnRecords);
    //    
    //    return copyedValue;
    //  }

    class CellFilterMatcher {
        CellFilter filter;
        boolean saveValueSize;
        int columnValueSize;
        CellValueMatcher valueMatcher;

        CellFilterMatcher(CellFilter filter, boolean saveValueSize) throws IOException {
            this.filter = filter;
            this.saveValueSize = saveValueSize;
            if (saveValueSize) {
                this.columnValueSize = columnValues.size();
            }

            valueMatcher = filter.getCellValueMatcher();
        }

        void saveMatchedResultsTo(List<ColumnValue> result) throws IOException {
            if (filter.getNumOfVersions() > 1) {
                processMultipleVersions(result);
            } else if (filter.hasTimestampFilter()) {
                processTimeStampFilter(result);
            } else {
                processDefaultCellFilter(result);
            }
        }

        void processTimeStampFilter(List<ColumnValue> result) {
            long startTime = filter.getStartTimestamp();
            long endTime = filter.getEndTimestamp();

            for (ColumnValue columnValue : columnValues) {
                long valueTimestamp = columnValue.getTimestamp();
                if (valueTimestamp >= startTime && valueTimestamp <= endTime) {
                    if (!checkPaging(columnValue)) {
                        continue;
                    }
                    if (saveValueSize) {
                        columnValue.setNumOfValues(columnValueSize);
                    }
                    result.add(columnValue);
                }
            }
        }

        void processMultipleVersions(List<ColumnValue> result) throws IOException {
            int versionCount = 0;
            int numOfVersion = filter.getNumOfVersions();

            for (ColumnValue columnValue : columnValues) {
                if (!checkPaging(columnValue)) {
                    continue;
                }
                if (valueMatcher != null) {
                    try {
                        if (!valueMatcher.match(columnValue.getValue(), columnValue.getTimestamp(),
                                filter.getFilterParams())) {
                            continue;
                        }
                    } catch (Exception e) {
                        throw new GetFailException(e);
                    }
                }
                if (saveValueSize) {
                    columnValue.setNumOfValues(columnValueSize);
                }
                result.add(columnValue);
                versionCount++;
                if (versionCount >= numOfVersion) {
                    break;
                }
            }
        }

        void processDefaultCellFilter(List<ColumnValue> result) throws IOException {
            ColumnValue columnValue = get();
            if (columnValue != null) {
                try {
                    if (valueMatcher != null && !valueMatcher.match(columnValue.getValue(),
                            columnValue.getTimestamp(), filter.getFilterParams())) {
                        return;
                    }
                } catch (Exception e) {
                    throw new GetFailException(e);
                }
                if (!checkPaging(columnValue)) {
                    return;
                }
                if (saveValueSize) {
                    columnValue.setNumOfValues(columnValueSize);
                }
                result.add(columnValue);
            }
        }

        boolean checkPaging(ColumnValue columnValue) {
            //targetCellKey ?  pagingTimestamp? ? 
            Cell.Key targetCellKey = filter.getTargetCellKey();
            if (targetCellKey != null && columnValue.getCellKey().equals(targetCellKey)) {
                long pagingTimestamp = filter.getPagingTimestamp();
                if (columnValue.getTimestamp() < pagingTimestamp) {
                    return false;
                }
            }

            return true;
        }
    }

    public void moveMatchedValues(CellFilter cellFilter, List<ColumnValue> result) throws IOException {
        if (columnValues.isEmpty()) {
            return;
        }

        new CellFilterMatcher(cellFilter, true).saveMatchedResultsTo(result);
    }

    public List<ColumnValue> get(CellFilter cellFilter) throws IOException {
        //columnFilter  , ?    .
        if (columnValues.isEmpty()) {
            return null;
        }

        List<ColumnValue> result = new ArrayList<ColumnValue>();

        new CellFilterMatcher(cellFilter, false).saveMatchedResultsTo(result);

        return result;
    }

    public boolean isDeleted() {
        if (columnValues.size() > 0) {
            return columnValues.first().isDeleted();
        } else {
            return true;
        }
    }

    public boolean hasNext() {
        if (iterator == null)
            return false;
        return iterator.hasNext();
    }

    public ColumnValue next() {
        return iterator.next();
    }

    public void remove() {
    }

    public static void main(String[] args) throws IOException {
        //?? 
        TreeMap<Cell.Key, ValueCollection> values = new TreeMap<Cell.Key, ValueCollection>();

        int size = 10485;
        //    int size = 100;
        ColumnValue[] columnValues = new ColumnValue[size];
        DecimalFormat df = new DecimalFormat("0000000000");
        String value = "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789";
        Row.Key rowKey = new Row.Key(df.format(100));

        byte[] valueBytes = value.getBytes();
        for (int i = 0; i < size; i++) {
            columnValues[i] = new ColumnValue();
            columnValues[i].setRowKey(rowKey);
            columnValues[i].setCellKey(new Cell.Key(df.format(i)));
            columnValues[i].setValue(valueBytes);
        }

        long startTime = System.currentTimeMillis();
        for (int i = 0; i < size; i++) {
            ValueCollection valueCollection = new ValueCollection();
            //      SortedSet<ColumnValue> set = new TreeSet<ColumnValue>();
            //      set.add(columnValues[i]);
            valueCollection.add(columnValues[i], 1);
        }
        long endTime = System.currentTimeMillis();
        //    System.out.println(">>>>" + (endTime - startTime));

        startTime = System.currentTimeMillis();
        long tatalNano = 0;
        for (int i = 0; i < size; i++) {
            long nano1 = System.nanoTime();
            ValueCollection valueCollection = values.get(columnValues[i].getCellKey());
            long nano2 = System.nanoTime();
            if (valueCollection == null) {
                valueCollection = new ValueCollection();
                values.put(columnValues[i].getCellKey(), valueCollection);
            }
            long nano3 = System.nanoTime();
            valueCollection.add(columnValues[i], 1);
            long nano4 = System.nanoTime();
            tatalNano += (nano3 - nano2);
            //      System.out.println((nano4-nano3) + "," + (nano3-nano2) + "," + (nano2-nano1));
        }
        endTime = System.currentTimeMillis();

        //System.out.println(">>>>" + (endTime - startTime) + ">" + (tatalNano/size));
    }
}