Package edu.brown.utils

Source Code of edu.brown.utils.PartitionSet$Itr

/***************************************************************************
*   Copyright (C) 2012 by H-Store Project                                 *
*   Brown University                                                      *
*   Massachusetts Institute of Technology                                 *
*   Yale University                                                       *
*                                                                         *
*   Permission is hereby granted, free of charge, to any person obtaining *
*   a copy of this software and associated documentation files (the       *
*   "Software"), to deal in the Software without restriction, including   *
*   without limitation the rights to use, copy, modify, merge, publish,   *
*   distribute, sublicense, and/or sell copies of the Software, and to    *
*   permit persons to whom the Software is furnished to do so, subject to *
*   the following conditions:                                             *
*                                                                         *
*   The above copyright notice and this permission notice shall be        *
*   included in all copies or substantial portions of the Software.       *
*                                                                         *
*   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       *
*   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    *
*   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*
*   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR     *
*   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
*   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
*   OTHER DEALINGS IN THE SOFTWARE.                                       *
***************************************************************************/
package edu.brown.utils;

import java.io.File;
import java.io.IOException;
import java.util.BitSet;
import java.util.Collection;
import java.util.Iterator;
import java.util.regex.Pattern;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONStringer;
import org.voltdb.catalog.Database;
import org.voltdb.messaging.FastDeserializer;
import org.voltdb.messaging.FastSerializable;
import org.voltdb.messaging.FastSerializer;
import org.voltdb.utils.NotImplementedException;

import edu.brown.hstore.HStoreConstants;

/**
* Container class that represents a list of partitionIds
* This is the fastest way to represent a list of partitions in the system.
* @author pavlo
*/
public class PartitionSet implements Collection<Integer>, JSONSerializable, FastSerializable {
   
    private final BitSet inner = new BitSet();
    private boolean contains_null = false;
    private int[] values = null;

    // ----------------------------------------------------------------------------
    // CONSTRUCTORS
    // ----------------------------------------------------------------------------
   
    public PartitionSet() {
        // Nothing...
    }
   
    /**
     * Initialize PartitionSet from Integer Collection
     * @param partitions
     */
    public PartitionSet(Collection<Integer> partitions) {
        this.addAll(partitions);
    }
   
    /**
     * Initialize PartitionSet from an Integer array
     * @param partitions
     */
    public PartitionSet(Integer...partitions) {
        for (Integer partition : partitions)
            this.add(partition);
    }
   
    /**
     * Initialize PartitionSet from an int array
     * @param partitions
     */
    public PartitionSet(int partitions[]) {
        for (int partition : partitions)
            this.add(partition);
    }
   
    /**
     * Copy constructor
     * @param partitions
     */
    public PartitionSet(PartitionSet partitions) {
        this.addAll(partitions);
    }
   
    // ----------------------------------------------------------------------------
    // API METHODS
    // ----------------------------------------------------------------------------

    /**
     * Return a cached int array of the partition ids in this PartitionSet.
     * This is the preferred way (i.e., faster) to iterate over the contents of the set. You will
     * want to use this instead of using its iterator.
     * @return
     */
    public final int[] values() {
        if (this.values == null) {
            int remaining = this.inner.cardinality();
            int size = remaining + (this.contains_null ? 1 : 0);
            this.values = new int[size];
            int idx = 0;
            if (this.contains_null) {
                this.values[idx++] = HStoreConstants.NULL_PARTITION_ID;
            }
            for (int i = 0; idx < size; i++) {
                if (this.inner.get(i)) this.values[idx++] = i;
            } // FOR
        }
        return (this.values);
    }
    /**
     * Return first partition found in this PartitionSet. This is primarily
     * useful for single-partition txns when you just want the only partition in
     * this set.
     * @return
     * @throws IndexOutOfBoundsException
     */
    public int get() throws IndexOutOfBoundsException {
        for (int partition = 0, cnt = this.inner.size(); partition < cnt; partition++) {
            if (this.inner.get(partition)) return (partition);
        } // FOR
        if (this.contains_null) return HStoreConstants.NULL_PARTITION_ID;
        throw new IndexOutOfBoundsException();
    }
   
    @Override
    public boolean equals(Object obj) {
        if (obj instanceof PartitionSet) {
            return this.inner.equals(((PartitionSet)obj).inner);
        }
        else if (obj instanceof Collection<?>) {
            Collection<?> other = (Collection<?>)obj;
            if (this.inner.size() != other.size()) return (false);
            return (this.containsAll(other));
        }
        return (false);
    }
    @Override
    public int hashCode() {
        return this.inner.hashCode();
    }
    @Override
    public String toString() {
        String s = this.inner.toString();
        // HACK
        if (this.contains_null) {
            s = s.substring(0, 1) +
                HStoreConstants.NULL_PARTITION_ID + ", " +
                s.substring(1);
        }
        return (s);
    }
    @Override
    public int size() {
        return (this.contains_null ? 1 : 0) + this.inner.cardinality();
        // return (this.values().length);
    }
    @Override
    public void clear() {
        this.contains_null = false;
        this.inner.clear();
        this.values = null;
    }
    @Override
    public boolean isEmpty() {
        return (this.contains_null == false && this.inner.isEmpty());
    }
    @Override
    public boolean contains(Object o) {
        if (o instanceof Integer) {
            return this.contains(((Integer)o).intValue());
        }
        return (false);
    }
    public boolean contains(Integer partition) {
        return this.contains(partition.intValue());
    }
    public boolean contains(int partition) {
        if (partition == HStoreConstants.NULL_PARTITION_ID) {
            return (this.contains_null);
        }
        return (this.inner.get(partition));
    }
    @Override
    public Object[] toArray() {
        int length = this.inner.cardinality();
        Object arr[] = new Object[length];
        int idx = 0;
        for (Integer partition : this) {
            arr[idx++] = partition;
        }
        return (arr);
    }
    @SuppressWarnings("unchecked")
    @Override
    public <T> T[] toArray(T[] a) {
        int length = this.inner.cardinality();
        if (a.length != length) {
            a = (T[])new Object[length];
        }
        int idx = 0;
        for (Integer partition : this) {
            a[idx++] = (T)partition;
        } // FOR
        return (a);
    }
    @Override
    public boolean add(Integer e) {
        return (this.add(e.intValue()));
    }
    public boolean add(int partition) {
        if (partition == HStoreConstants.NULL_PARTITION_ID) {
            this.contains_null = true;
        } else {
            this.inner.set(partition);
        }
        this.values = null;
        return (true);
    }
    @Override
    public boolean remove(Object o) {
        if (o instanceof Integer) {
            Integer partition = (Integer)o;
            return (this.remove(partition.intValue()));
        }
        return (false);
    }
    public boolean remove(int partition) {
        boolean ret = false;
        if (partition == HStoreConstants.NULL_PARTITION_ID) {
            ret = this.contains_null;
            this.contains_null = false;
        } else if (this.inner.get(partition)) {
            ret = true;
            this.inner.set(partition, false);           
        }
        this.values = null;
        return (ret);
    }
    @Override
    public boolean containsAll(Collection<?> c) {
        for (Object o : c) {
            if (this.contains(o) == false) {
                return (false);
            }
        } // FOR
        return (true);
    }
    public boolean containsAll(PartitionSet partitions) {
        if (this.contains_null != partitions.contains_null) return (false);
        if (this.inner.intersects(partitions.inner)) {
            for (int partition = 0, cnt = partitions.inner.size(); partition < cnt; partition++) {
                if (partitions.inner.get(partition) && this.inner.get(partition) == false) return (false);
            } // FOR
            return (true);
        }
        return (false);
    }
    public boolean addAll(int partitions[]) {
        boolean ret = true;
        for (int partition : partitions) {
            ret = this.add(partition) && ret;
        } // FOR
        return (ret);
    }
    @Override
    public boolean addAll(Collection<? extends Integer> partitions) {
        boolean ret = true;
        for (Integer partition : partitions) {
            ret = this.add(partition.intValue()) && ret;
        } // FOR
        return (ret);
    }
    public boolean addAll(PartitionSet partitions) {
        if (partitions.contains_null) this.contains_null = true;
        this.inner.or(partitions.inner);
        return (true);
    }
    @Override
    public boolean removeAll(Collection<?> c) {
        boolean ret = false;
        for (Object o : c) {
            if (o instanceof Number) {
                ret = this.remove(((Number)o).intValue()) || ret;
            }
        } // FOR
        return (ret);
    }
    public boolean removeAll(PartitionSet partitions) {
        boolean ret = false;
        if (partitions.contains_null) {
            ret = this.contains_null;
            this.contains_null = false;
        }
        if (this.inner.intersects(partitions.inner)) {
            this.inner.andNot(partitions.inner);
            ret = true;
        }
        return (ret);
    }
    @Override
    public boolean retainAll(Collection<?> c) {
        for (Integer partition : this) {
            if (c.contains(partition) == false) {
                this.remove(partition);
            }
        } // FOR
        return (true);
    }
    public boolean retainAll(PartitionSet partitions) {
        if (this.contains_null != partitions.contains_null) this.contains_null = false;
        this.inner.and(partitions.inner);
        return (true);
    }
    @Override
    public Iterator<Integer> iterator() {
        return new Itr();
    }
   
    // ----------------------------------------------------------------------------
    // STATIC METHODS
    // ----------------------------------------------------------------------------
   
    public static PartitionSet singleton(int partition) {
        PartitionSet ret = new PartitionSet();
        ret.add(partition);
        return (ret);
    }
   
    /**
     * Convert a bitmap into a PartitionSet and print it out
     * @param bitmap
     * @return
     */
    public static String toString(boolean bitmap[]) {
        PartitionSet ps = new PartitionSet();
        for (int i = 0; i < bitmap.length; i++) {
            if (bitmap[i]) ps.add(i);
        } // FOR
        return (ps.toString());
    }
   
    /**
     * Parse a description of partition ids and populate a PartitionSet.
     * This supports comma-separated lists (e.g., "1,2,3,4") and
     * ranges (e.g., "1-4"). You can also mix and match them together
     * (e.g., "1,2-3,4").
     * @param partitionList
     * @return
     */
    public static PartitionSet parse(String partitionList) {
        Pattern HYPHEN_SPLIT = Pattern.compile(Pattern.quote("-"));
       
        // Partition Ranges
        PartitionSet partitions = new PartitionSet();
        for (String p : StringUtil.splitList(partitionList)) {
            int start = -1;
            int stop = -1;
            String range[] = HYPHEN_SPLIT.split(p);
            if (range.length == 2) {
                start = Integer.parseInt(range[0].trim());
                stop = Integer.parseInt(range[1].trim());
            } else {
                start = Integer.parseInt(p.trim());
                stop = start;
            }
            for (int partition = start; partition < stop + 1; partition++) {
                partitions.add(partition);
            } // FOR
        } // FOR
        return (partitions);
    }
   
    // ----------------------------------------------------------------------------
    // ITERATOR
    // ----------------------------------------------------------------------------
   
    private class Itr implements Iterator<Integer> {
        int idx = 0;
        boolean shown_null = false;
        boolean need_seek = true;
        @Override
        public boolean hasNext() {
            this.need_seek = false;
            if (contains_null && this.shown_null == false) {
                return (true);
            }
            for (int cnt = inner.size(); this.idx < cnt; this.idx++) {
                if (inner.get(this.idx)) {
                    return (true);
                }
            } // FOR
            return (false);
        }
        @Override
        public Integer next() {
            if (this.need_seek) {
                if (this.hasNext() == false) return (null);
            }
            if (contains_null && this.shown_null == false) {
                this.shown_null = true;
                return (HStoreConstants.NULL_PARTITION_ID);
            }
            return Integer.valueOf(this.idx++);
        }
        @Override
        public void remove() {
            throw new NotImplementedException("PartitionSet Iterator remove is not implemented");
        }
    }
   
    // ----------------------------------------------------------------------------
    // SERIALIZATION METHODS
    // ----------------------------------------------------------------------------


    @Override
    public void readExternal(FastDeserializer in) throws IOException {
        this.clear();
        this.contains_null = in.readBoolean();
        int cnt = in.readShort();
        for (int i = 0; i < cnt; i++) {
            int partition = in.readInt();
            this.add(partition);
        } // FOR
    }

    @Override
    public void writeExternal(FastSerializer out) throws IOException {
        out.writeBoolean(this.contains_null);
        out.writeShort(this.inner.cardinality());
        for (Integer partition : this) {
            out.writeInt(partition.intValue());
        } // FOR
    }
   
   
    @Override
    public void load(File input_path, Database catalog_db) throws IOException {
        JSONUtil.load(this, catalog_db, input_path);
    }

    @Override
    public void save(File output_path) throws IOException {
        JSONUtil.save(this, output_path);
    }

    @Override
    public String toJSONString() {
        return (JSONUtil.toJSONString(this));
    }

    @Override
    public void toJSON(JSONStringer stringer) throws JSONException {
        stringer.key("P").array();
        for (Integer partition : this) {
            stringer.value(partition);
        } // FOR
        stringer.endArray();
    }

    @Override
    public void fromJSON(JSONObject json_object, Database catalog_db) throws JSONException {
        JSONArray json_arr = json_object.getJSONArray("P");
        for (int i = 0, cnt = json_arr.length(); i < cnt; i++) {
            this.inner.set(json_arr.getInt(i));
        }
    }
}
TOP

Related Classes of edu.brown.utils.PartitionSet$Itr

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.