| /* |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| */ |
| package org.apache.qpid.proton.messenger.impl; |
| |
| import java.util.List; |
| import java.util.LinkedList; |
| import java.util.Map; |
| import java.util.HashMap; |
| import java.util.Collection; |
| import java.util.Iterator; |
| |
| import org.apache.qpid.proton.messenger.Status; |
| import org.apache.qpid.proton.messenger.Messenger; |
| import org.apache.qpid.proton.engine.Delivery; |
| import org.apache.qpid.proton.amqp.messaging.Accepted; |
| import org.apache.qpid.proton.amqp.messaging.Rejected; |
| |
| /** |
| * @deprecated Messenger will be removed from upcoming proton-j releases. |
| */ |
| class Store |
| { |
| private static final Accepted ACCEPTED = Accepted.getInstance(); |
| private static final Rejected REJECTED = new Rejected(); |
| |
| private LinkedList<StoreEntry> _store = new LinkedList<StoreEntry>(); |
| private HashMap<String, LinkedList<StoreEntry>> _stream = new HashMap<String, LinkedList<StoreEntry>>(); |
| |
| // for incoming/outgoing window tracking |
| int _window; |
| int _lwm; |
| int _hwm; |
| private HashMap<Integer, StoreEntry> _tracked = new HashMap<Integer, StoreEntry>(); |
| |
| Store() |
| { |
| } |
| |
| private boolean isTracking( Integer id ) |
| { |
| return id != null && (id.intValue() - _lwm >= 0) && (_hwm - id.intValue() > 0); |
| } |
| |
| int size() |
| { |
| return _store.size(); |
| } |
| |
| int getWindow() |
| { |
| return _window; |
| } |
| |
| void setWindow(int window) |
| { |
| _window = window; |
| } |
| |
| StoreEntry put(String address) |
| { |
| if (address == null) address = ""; |
| StoreEntry entry = new StoreEntry(this, address); |
| _store.add( entry ); |
| LinkedList<StoreEntry> list = _stream.get( address ); |
| if (list != null) { |
| list.add( entry ); |
| } else { |
| list = new LinkedList<StoreEntry>(); |
| list.add( entry ); |
| _stream.put( address, list ); |
| } |
| entry.stored(); |
| return entry; |
| } |
| |
| StoreEntry get(String address) |
| { |
| if (address != null) { |
| LinkedList<StoreEntry> list = _stream.get( address ); |
| if (list != null) return list.peekFirst(); |
| } else { |
| return _store.peekFirst(); |
| } |
| return null; |
| } |
| |
| StoreEntry getEntry(int id) |
| { |
| return _tracked.get(id); |
| } |
| |
| Iterator<StoreEntry> trackedEntries() |
| { |
| return _tracked.values().iterator(); |
| } |
| |
| void freeEntry(StoreEntry entry) |
| { |
| if (entry.isStored()) { |
| _store.remove( entry ); |
| LinkedList<StoreEntry> list = _stream.get( entry.getAddress() ); |
| if (list != null) list.remove( entry ); |
| entry.notStored(); |
| } |
| // note well: may still be in _tracked map if still in window! |
| } |
| |
| public int trackEntry(StoreEntry entry) |
| { |
| assert( entry.getStore() == this ); |
| entry.setId(_hwm++); |
| _tracked.put(entry.getId(), entry); |
| slideWindow(); |
| return entry.getId(); |
| } |
| |
| private void slideWindow() |
| { |
| if (_window >= 0) |
| { |
| while (_hwm - _lwm > _window) |
| { |
| StoreEntry old = getEntry(_lwm); |
| if (old != null) |
| { |
| _tracked.remove( old.getId() ); |
| Delivery d = old.getDelivery(); |
| if (d != null) { |
| if (d.getLocalState() == null) |
| d.disposition(ACCEPTED); |
| d.settle(); |
| } |
| } |
| _lwm++; |
| } |
| } |
| } |
| |
| int update(int id, Status status, int flags, boolean settle, boolean match ) |
| { |
| if (!isTracking(id)) return 0; |
| |
| int start = (Messenger.CUMULATIVE & flags) != 0 ? _lwm : id; |
| for (int i = start; (id - i) >= 0; i++) |
| { |
| StoreEntry e = getEntry(i); |
| if (e != null) |
| { |
| Delivery d = e.getDelivery(); |
| if (d != null) |
| { |
| if (d.getLocalState() == null) |
| { |
| if (match) |
| { |
| d.disposition(d.getRemoteState()); |
| } |
| else |
| { |
| switch (status) |
| { |
| case ACCEPTED: |
| d.disposition(ACCEPTED); |
| break; |
| case REJECTED: |
| d.disposition(REJECTED); |
| break; |
| default: |
| break; |
| } |
| } |
| e.updated(); |
| } |
| } |
| if (settle) |
| { |
| if (d != null) |
| { |
| d.settle(); |
| } |
| _tracked.remove(e.getId()); |
| } |
| } |
| } |
| |
| while (_hwm - _lwm > 0 && !_tracked.containsKey(_lwm)) |
| { |
| _lwm++; |
| } |
| |
| return 0; |
| } |
| } |
| |
| |