181e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng/*
281e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng * Copyright (C) 2012 The Android Open Source Project
381e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng *
481e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng * Licensed under the Apache License, Version 2.0 (the "License");
581e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng * you may not use this file except in compliance with the License.
681e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng * You may obtain a copy of the License at
781e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng *
881e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng *      http://www.apache.org/licenses/LICENSE-2.0
981e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng *
1081e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng * Unless required by applicable law or agreed to in writing, software
1181e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng * distributed under the License is distributed on an "AS IS" BASIS,
1281e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1381e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng * See the License for the specific language governing permissions and
1481e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng * limitations under the License.
1581e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng */
1681e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng
1781e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Chengpackage com.android.contacts.common.util;
1881e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng
1981e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Chengimport android.util.Log;
2081e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng
2181e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Chengimport com.google.common.collect.Lists;
2281e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng
2381e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Chengimport java.util.ArrayList;
2481e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng
2581e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng/**
2681e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng * A {@link StopWatch} records start, laps and stop, and print them to logcat.
2781e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng */
2881e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Chengpublic class StopWatch {
2981e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng
3081e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng    private final String mLabel;
3181e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng
3281e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng    private final ArrayList<Long> mTimes = Lists.newArrayList();
3381e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng    private final ArrayList<String> mLapLabels = Lists.newArrayList();
3481e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng
3581e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng    private StopWatch(String label) {
3681e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng        mLabel = label;
3781e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng        lap("");
3881e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng    }
3981e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng
4081e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng    /**
4181e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng     * Create a new instance and start it.
4281e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng     */
4381e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng    public static StopWatch start(String label) {
4481e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng        return new StopWatch(label);
4581e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng    }
4681e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng
4781e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng    /**
4881e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng     * Record a lap.
4981e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng     */
5081e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng    public void lap(String lapLabel) {
5181e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng        mTimes.add(System.currentTimeMillis());
5281e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng        mLapLabels.add(lapLabel);
5381e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng    }
5481e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng
5581e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng    /**
5681e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng     * Stop it and log the result, if the total time >= {@code timeThresholdToLog}.
5781e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng     */
5881e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng    public void stopAndLog(String TAG, int timeThresholdToLog) {
5981e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng
6081e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng        lap("");
6181e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng
6281e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng        final long start = mTimes.get(0);
6381e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng        final long stop = mTimes.get(mTimes.size() - 1);
6481e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng
6581e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng        final long total = stop - start;
6681e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng        if (total < timeThresholdToLog) return;
6781e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng
6881e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng        final StringBuilder sb = new StringBuilder();
6981e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng        sb.append(mLabel);
7081e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng        sb.append(",");
7181e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng        sb.append(total);
7281e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng        sb.append(": ");
7381e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng
7481e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng        long last = start;
7581e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng        for (int i = 1; i < mTimes.size(); i++) {
7681e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng            final long current = mTimes.get(i);
7781e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng            sb.append(mLapLabels.get(i));
7881e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng            sb.append(",");
7981e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng            sb.append((current - last));
8081e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng            sb.append(" ");
8181e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng            last = current;
8281e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng        }
8381e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng        Log.v(TAG, sb.toString());
8481e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng    }
8581e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng
8681e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng    /**
8781e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng     * Return a dummy instance that does no operations.
8881e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng     */
8981e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng    public static StopWatch getNullStopWatch() {
9081e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng        return NullStopWatch.INSTANCE;
9181e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng    }
9281e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng
9381e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng    private static class NullStopWatch extends StopWatch {
9481e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng        public static final NullStopWatch INSTANCE = new NullStopWatch();
9581e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng
9681e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng        public NullStopWatch() {
9781e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng            super(null);
9881e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng        }
9981e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng
10081e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng        @Override
10181e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng        public void lap(String lapLabel) {
10281e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng            // noop
10381e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng        }
10481e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng
10581e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng        @Override
10681e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng        public void stopAndLog(String TAG, int timeThresholdToLog) {
10781e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng            // noop
10881e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng        }
10981e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng    }
11081e755d9bd36eb7e022f9b897539d55b053ce0d8Chiao Cheng}
111