Ignore:
Timestamp:
01/28/20 10:19:55 (5 years ago)
Author:
bart
Message:

Update 28 jan 2020

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/main/java/geniusweb/profilesserver/websocket/GetProfileSocket.java

    r1 r8  
    22
    33import java.io.IOException;
     4import java.math.BigInteger;
     5import java.util.Arrays;
     6import java.util.Collections;
     7import java.util.HashMap;
     8import java.util.HashSet;
     9import java.util.List;
     10import java.util.Map;
     11import java.util.Random;
     12import java.util.Set;
     13import java.util.stream.Collectors;
    414
    515import javax.websocket.OnClose;
     
    1020import javax.websocket.server.ServerEndpoint;
    1121
    12 import com.fasterxml.jackson.databind.ObjectMapper;
    13 
     22import geniusweb.bidspace.AllBidsList;
     23import geniusweb.bidspace.BidsWithUtility;
     24import geniusweb.issuevalue.Bid;
     25import geniusweb.profile.DefaultPartialOrdering;
     26import geniusweb.profile.PartialOrdering;
    1427import geniusweb.profile.Profile;
     28import geniusweb.profile.utilityspace.LinearAdditive;
     29import geniusweb.profilesserver.Jackson;
    1530import geniusweb.profilesserver.ProfilesFactory;
    1631import geniusweb.profilesserver.events.ChangeEvent;
     32import tudelft.utilities.immutablelist.FixedList;
     33import tudelft.utilities.immutablelist.ImmutableList;
    1734import tudelft.utilities.listener.Listener;
    1835
     
    2239 * profiles is sent. For each new websocket the server will create one of this
    2340 * but they all share one {@link ProfilesFactory}.
     41 *
     42 * <p>
     43 * Query string: the websocket allows query strings.
     44 * <ul>
     45 * <li>partial</li> a query key that is assigned a natural number N (0 or
     46 * larger). If set, the profile is converted into a Partial Profile with the
     47 * given number of points. If N>0, the maximum utility bid is included .If N>1,
     48 * the minimum utility bid is included. The other bids are picked at random.
     49 * This filtering mechanism only works if the profile is {@link LinearAdditive}
     50 * space.
    2451 */
    2552@ServerEndpoint("/websocket/get/{domain}/{profile}")
    2653public class GetProfileSocket {
    27         private final static ObjectMapper jackson = new ObjectMapper();
    2854        private Profile prof = null; // the latest that we sent to client.
    2955
     
    3359        private Listener<ChangeEvent> changeListener;
    3460        private Session session;
     61        private Map<String, String> params = Collections.emptyMap();
    3562
    3663        @OnOpen
     
    4067                this.profilename = domain + "/" + profile;
    4168
     69                if (session.getQueryString() != null) {
     70                        List<String> paramstrings = Arrays
     71                                        .asList(session.getQueryString().split("&"));
     72                        params = paramstrings.stream().map(str -> str.split("=")).collect(
     73                                        Collectors.toMap(vals -> vals[0], vals -> vals[1]));
     74                }
    4275                changeListener = new Listener<ChangeEvent>() {
    4376                        @Override
     
    5689                        prof = newprof;
    5790                        try {
    58                                 session.getBasicRemote()
    59                                                 .sendText(jackson.writeValueAsString(prof));
     91                                session.getBasicRemote().sendText(
     92                                                Jackson.instance().writeValueAsString(filter(prof)));
    6093                        } catch (Exception e) {
    6194                                e.printStackTrace();
    6295                        }
    6396                }
     97        }
     98
     99        private Profile filter(Profile prof1) {
     100                String partial = params.get("partial");
     101                if (partial == null) {
     102                        return prof1;
     103                }
     104                if (!(prof1 instanceof PartialOrdering))
     105                        throw new IllegalArgumentException(
     106                                        "profile must be partialordering but got " + prof);
     107                PartialOrdering profile = (PartialOrdering) prof1;
     108                final int numbids = Integer.parseInt(partial);
     109                if (numbids < 0)
     110                        throw new IllegalArgumentException("parameter partial must be >=0");
     111
     112                ImmutableList<Bid> allbids;
     113                if (profile instanceof DefaultPartialOrdering)
     114                        allbids = new FixedList<Bid>(
     115                                        ((DefaultPartialOrdering) profile).getBids());
     116                else
     117                        allbids = new AllBidsList(prof.getDomain());
     118
     119                if (BigInteger.valueOf(numbids).compareTo(allbids.size()) > 0)
     120                        throw new IllegalArgumentException("Request for " + numbids
     121                                        + " exceeds number of bids in the space " + allbids.size());
     122
     123                BidsWithUtility info = new BidsWithUtility((LinearAdditive) prof);
     124                Set<Bid> selected = new HashSet<>();
     125                if (numbids > 0) {
     126                        selected.add(info.getExtremeBid(true));
     127                }
     128                if (numbids > 1) {
     129                        selected.add(info.getExtremeBid(false));
     130                }
     131                Random random = new Random();
     132                for (int nr = 2; nr < numbids; nr++) {
     133                        int attempt = 0;
     134                        Bid bid;
     135                        do {
     136                                long i = random.nextInt(allbids.size().intValue());
     137                                bid = allbids.get(BigInteger.valueOf(i));
     138                        } while (attempt++ < 10 && selected.contains(bid));
     139                        selected.add(bid);
     140                }
     141
     142                // put comparison info for these bids in the map
     143                Map<Bid, Set<Bid>> isBetterMap = new HashMap<>();
     144                for (Bid bid : selected) {
     145                        Set<Bid> worse = selected.stream().filter(
     146                                        otherbid -> profile.isPreferredOrEqual(bid, otherbid)
     147                                                        && !profile.isPreferredOrEqual(otherbid, bid))
     148                                        .collect(Collectors.toSet());
     149                        isBetterMap.put(bid, worse);
     150                }
     151                return new DefaultPartialOrdering(
     152                                prof.getName() + "-partial-" + numbids, prof.getDomain(),
     153                                prof.getReservationBid(), isBetterMap);
    64154        }
    65155
Note: See TracChangeset for help on using the changeset viewer.