17ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki/*
27ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki * Copyright (C) 2012 The Android Open Source Project
37ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki *
47ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki * Licensed under the Apache License, Version 2.0 (the "License");
57ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki * you may not use this file except in compliance with the License.
67ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki * You may obtain a copy of the License at
77ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki *
87ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki *      http://www.apache.org/licenses/LICENSE-2.0
97ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki *
107ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki * Unless required by applicable law or agreed to in writing, software
117ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki * distributed under the License is distributed on an "AS IS" BASIS,
127ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki * See the License for the specific language governing permissions and
147ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki * limitations under the License.
157ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki */
167ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki
177ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onukipackage com.android.contacts.util;
187ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki
197ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onukiimport android.util.Log;
207ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki
21e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.google.common.collect.Lists;
22e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Cheng
237ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onukiimport java.util.ArrayList;
247ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki
257ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki/**
267ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki * A {@link StopWatch} records start, laps and stop, and print them to logcat.
277ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki */
287ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onukipublic class StopWatch {
297ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki
307ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki    private final String mLabel;
317ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki
327ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki    private final ArrayList<Long> mTimes = Lists.newArrayList();
337ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki    private final ArrayList<String> mLapLabels = Lists.newArrayList();
347ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki
357ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki    private StopWatch(String label) {
367ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki        mLabel = label;
377ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki        lap("");
387ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki    }
397ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki
407ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki    /**
417ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki     * Create a new instance and start it.
427ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki     */
437ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki    public static StopWatch start(String label) {
447ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki        return new StopWatch(label);
457ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki    }
467ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki
477ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki    /**
487ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki     * Record a lap.
497ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki     */
507ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki    public void lap(String lapLabel) {
517ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki        mTimes.add(System.currentTimeMillis());
527ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki        mLapLabels.add(lapLabel);
537ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki    }
547ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki
557ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki    /**
567ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki     * Stop it and log the result, if the total time >= {@code timeThresholdToLog}.
577ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki     */
587ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki    public void stopAndLog(String TAG, int timeThresholdToLog) {
597ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki
607ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki        lap("");
617ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki
627ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki        final long start = mTimes.get(0);
637ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki        final long stop = mTimes.get(mTimes.size() - 1);
647ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki
657ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki        final long total = stop - start;
667ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki        if (total < timeThresholdToLog) return;
677ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki
687ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki        final StringBuilder sb = new StringBuilder();
697ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki        sb.append(mLabel);
707ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki        sb.append(",");
717ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki        sb.append(total);
727ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki        sb.append(": ");
737ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki
747ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki        long last = start;
757ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki        for (int i = 1; i < mTimes.size(); i++) {
767ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki            final long current = mTimes.get(i);
777ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki            sb.append(mLapLabels.get(i));
787ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki            sb.append(",");
797ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki            sb.append((current - last));
807ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki            sb.append(" ");
817ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki            last = current;
827ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki        }
837ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki        Log.v(TAG, sb.toString());
847ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki    }
85dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki
86dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki    /**
87dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki     * Return a dummy instance that does no operations.
88dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki     */
89dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki    public static StopWatch getNullStopWatch() {
90dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki        return NullStopWatch.INSTANCE;
91dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki    }
92dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki
93dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki    private static class NullStopWatch extends StopWatch {
94dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki        public static final NullStopWatch INSTANCE = new NullStopWatch();
95dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki
96dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki        public NullStopWatch() {
97dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki            super(null);
98dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki        }
99dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki
100dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki        @Override
101dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki        public void lap(String lapLabel) {
102dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki            // noop
103dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki        }
104dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki
105dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki        @Override
106dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki        public void stopAndLog(String TAG, int timeThresholdToLog) {
107dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki            // noop
108dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki        }
109dfe8cc82e8aa31929bb85eb68b7de3492b875d57Makoto Onuki    }
1107ca259a8252ef640bb38b3ac0293f737c13cefb8Makoto Onuki}
111