001/*
002 * jPOS Project [http://jpos.org]
003 * Copyright (C) 2000-2026 jPOS Software SRL
004 *
005 * This program is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU Affero General Public License as
007 * published by the Free Software Foundation, either version 3 of the
008 * License, or (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013 * GNU Affero General Public License for more details.
014 *
015 * You should have received a copy of the GNU Affero General Public License
016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
017 */
018
019package org.jpos.space;
020
021import java.util.ArrayList;
022import java.util.List;
023
024/**
025 * Space related helper methods
026 *
027 * @author Alejandro Revilla
028 * @version $Revision$ $Date$
029 * @since 1.4.7
030 */
031
032@SuppressWarnings("unchecked")
033public class SpaceUtil {
034    /** Default constructor; no instance state to initialise. */
035    public SpaceUtil() {}
036    /**
037     * return all entries under a given key
038     *
039     * @param sp the Space
040     * @param key Entry's key
041     * @return array containing all entries under key
042     */
043    public static Object[] inpAll (Space sp, Object key) {
044        List list = new ArrayList();
045        Object value;
046        do {
047            value = sp.inp (key);
048            if (value != null) {
049                list.add (value);
050            }
051        } while (value != null);
052        return list.toArray();
053    }
054
055    /**
056     * Remove all entries under key
057     *
058     * @param sp the Space
059     * @param key Entry's key
060     */
061    public static void wipe (Space sp, Object key) {
062        while (sp.inp (key) != null)
063            ; // NOPMD
064    }
065
066    /**
067     * @param sp the Space
068     * @param key entry's key
069     * @param value entry's value
070     * @deprecated Use space.put instead
071     */
072    @Deprecated
073    public static void wipeAndOut  (Space sp, Object key, Object value) {
074        sp.put(key, value);
075    }
076
077    /**
078     * @param sp the Space
079     * @param key entry's key
080     * @param value entry's value
081     * @param timeout entry lifespan in milliseconds
082     * @deprecated use space.put instead
083     */
084    @Deprecated
085    public static void wipeAndOut  (Space sp, Object key, Object value, long timeout) {
086        sp.out(key, value, timeout);
087    }
088    /**
089     * Atomically increments and returns the long counter stored under {@code key}.
090     *
091     * @param sp the Space
092     * @param key counter's key
093     * @return the new counter value
094     */
095    public static long nextLong (Space sp, Object key) {
096        long l = 0L;
097        synchronized (sp) {
098            Object obj = sp.inp (key);
099            wipe (sp, key); // just in case
100            if (obj instanceof Long)
101                l = (Long) obj;
102            sp.out (key, ++l);
103        }
104        return l;
105    }
106    /**
107     * Writes {@code value} only when the slot at {@code key} is empty after an {@code nrd} probe.
108     *
109     * @param sp the Space
110     * @param key entry's key
111     * @param value entry's value
112     * @param nrdTimeout how long {@code nrd} waits for the slot to become non-empty
113     * @param outTimeout entry lifespan once written
114     * @return {@code true} if the value was written, {@code false} if the slot was already populated
115     */
116    public static boolean outIfEmpty (Space sp, Object key, Object value, long nrdTimeout, long outTimeout) {
117        synchronized (sp) {
118            if (sp.nrd(key, nrdTimeout) == null) {
119                sp.out(key, value, outTimeout);
120                return true;
121            }
122        }
123        return false;
124    }
125    /**
126     * Blocks until the slot at {@code key} is empty, then writes {@code value} with the given lifespan.
127     *
128     * @param sp the Space
129     * @param key entry's key
130     * @param value entry's value
131     * @param timeout entry lifespan once written
132     */
133    public static void outWhenEmpty (Space sp, Object key, Object value, long timeout) {
134        synchronized (sp) {
135            sp.nrd(key);
136            sp.out(key, value, timeout);
137        }
138    }
139    /**
140     * Blocks until the slot at {@code key} is empty, then writes {@code value}.
141     *
142     * @param sp the Space
143     * @param key entry's key
144     * @param value entry's value
145     */
146    public static void outWhenEmpty (Space sp, Object key, Object value) {
147        synchronized (sp) {
148            sp.nrd(key);
149            sp.out(key, value);
150        }
151    }
152}