001package org.cache2k.impl;
002
003/*
004 * #%L
005 * cache2k core package
006 * %%
007 * Copyright (C) 2000 - 2015 headissue GmbH, Munich
008 * %%
009 * This program is free software: you can redistribute it and/or modify
010 * it under the terms of the GNU General Public License as
011 * published by the Free Software Foundation, either version 3 of the 
012 * License, or (at your option) any later version.
013 * 
014 * This program is distributed in the hope that it will be useful,
015 * but WITHOUT ANY WARRANTY; without even the implied warranty of
016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
017 * GNU General Public License for more details.
018 * 
019 * You should have received a copy of the GNU General Public 
020 * License along with this program.  If not, see
021 * <http://www.gnu.org/licenses/gpl-3.0.html>.
022 * #L%
023 */
024
025import java.util.ArrayList;
026import java.util.List;
027
028/**
029 * Used to record and check the integrity. We support to record 64 different
030 * constraints to produce a single long state value.
031 *
032 * @author Jens Wilke; created: 2013-07-11
033 */
034@SuppressWarnings("unused")
035public class IntegrityState {
036
037  List<String> failingTests = new ArrayList<String>();
038  long state = 0;
039  long bitNr = 0;
040  int stringsHashCode = 0;
041
042  IntegrityState check(boolean f) {
043    check(null, f);
044    return this;
045  }
046
047  /**
048   *
049   * @param _check Name of the test. Used when we build an exception.
050   * @param f test outcome, true when success
051   */
052  protected IntegrityState check(String _check, String _note, boolean f) {
053    if (_check == null || _check.length() == 0) {
054      _check = "test#" + bitNr;
055    }
056    stringsHashCode = stringsHashCode * 31 + _check.hashCode();
057    if (!f) {
058      if (_note != null) {
059        failingTests.add('"' + _check + "\" => " + _note);
060      } else {
061        failingTests.add('"' + _check+ '"');
062      }
063      state |= 1 << bitNr;
064    }
065    bitNr++;
066    return this;
067  }
068
069  public IntegrityState check(String _check, boolean f) {
070    check(_check, null, f);
071    return this;
072  }
073
074  public IntegrityState checkEquals(String _check, int v1, int v2) {
075    if (v1 == v2) {
076      check(_check, null, true);
077    } else {
078      check(_check, v1 + "==" + v2, false);
079    }
080    return this;
081  }
082
083  public IntegrityState checkEquals(String _check, long v1, long v2) {
084    if (v1 == v2) {
085      check(_check, null, true);
086    } else {
087      check(_check, v1 + "==" + v2, false);
088    }
089    return this;
090  }
091
092  public IntegrityState checkLessOrEquals(String _check, int v1, int v2) {
093    if (v1 <= v2) {
094      check(_check, null, true);
095    } else {
096      check(_check, v1 + "<=" + v2, false);
097    }
098    return this;
099  }
100
101  public IntegrityState checkLess(String _check, int v1, int v2) {
102    if (v1 < v2) {
103      check(_check, null, true);
104    } else {
105      check(_check, v1 + "<" + v2, false);
106    }
107    return this;
108  }
109
110  public IntegrityState checkGreaterOrEquals(String _check, int v1, int v2) {
111    if (v1 >= v2) {
112      check(_check, null, true);
113    } else {
114      check(_check, v1 + ">=" + v2, false);
115    }
116    return this;
117  }
118
119  public IntegrityState checkGreater(String _check, int v1, int v2) {
120    if (v1 > v2) {
121      check(_check, null, true);
122    } else {
123      check(_check, v1 + ">" + v2, false);
124    }
125    return this;
126  }
127
128  public String getStateDescriptor() {
129    return Long.toHexString(state) + '.' + bitNr + '.' + Integer.toHexString(stringsHashCode);
130  }
131
132  public long getStateFlags() { return state; }
133
134  public String getFailingChecks() { return failingTests.toString(); }
135
136  public void throwIfNeeded() {
137    if (state > 0) {
138      throw new IllegalStateException("Integrity test failed: " + failingTests.toString());
139    }
140  }
141
142}