/hazelcast/src/main/java/com/hazelcast/impl/base/DistributedSemaphore.java

https://bitbucket.org/gabral6_gmailcom/hazelcast · Java · 124 lines · 90 code · 19 blank · 15 comment · 15 complexity · 41e657dbacd292d7a5402eb00d01c19b MD5 · raw file

  1. /*
  2. * Copyright (c) 2008-2013, Hazelcast, Inc. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.hazelcast.impl.base;
  17. import com.hazelcast.nio.Address;
  18. import com.hazelcast.nio.DataSerializable;
  19. import java.io.DataInput;
  20. import java.io.DataOutput;
  21. import java.io.IOException;
  22. import java.util.HashMap;
  23. import java.util.Map;
  24. public class DistributedSemaphore implements DataSerializable {
  25. Map<Address, Integer> attachedPermits = new HashMap<Address, Integer>();
  26. int available;
  27. public DistributedSemaphore() {
  28. }
  29. public DistributedSemaphore(int initialPermits) {
  30. available = initialPermits;
  31. }
  32. public void readData(DataInput in) throws IOException {
  33. Address address;
  34. attachedPermits.clear();
  35. available = in.readInt();
  36. int entries = in.readInt();
  37. while (entries-- > 0) {
  38. (address = new Address()).readData(in);
  39. attachedPermits.put(address, in.readInt());
  40. }
  41. }
  42. public void writeData(DataOutput out) throws IOException {
  43. out.writeInt(available);
  44. out.writeInt(attachedPermits.size());
  45. for (Map.Entry<Address, Integer> entry : attachedPermits.entrySet()) {
  46. entry.getKey().writeData(out);
  47. out.writeInt(entry.getValue());
  48. }
  49. }
  50. public void attachDetach(Integer permitsDelta, Address address) {
  51. if (permitsDelta != 0 && address != null) {
  52. int newValue = permitsDelta + getAttached(address);
  53. if (newValue != 0) {
  54. attachedPermits.put(address, newValue);
  55. } else {
  56. attachedPermits.remove(address);
  57. }
  58. }
  59. }
  60. public int drain() {
  61. int drained = available;
  62. available = 0;
  63. return drained;
  64. }
  65. public int getAttached() {
  66. int total = 0;
  67. for (Integer permits : attachedPermits.values()) {
  68. total += permits;
  69. }
  70. return total;
  71. }
  72. public int getAttached(Address address) {
  73. return attachedPermits.containsKey(address) ? attachedPermits.get(address) : 0;
  74. }
  75. public int getAvailable() {
  76. return available;
  77. }
  78. public void reduce(int permits) {
  79. available -= permits;
  80. }
  81. public void release(int permits, Address address) {
  82. available += permits;
  83. attachDetach(permits, address);
  84. }
  85. public boolean tryAcquire(int permits, Address address) {
  86. if (available >= permits) {
  87. available -= permits;
  88. attachDetach(permits, address);
  89. return true;
  90. }
  91. return false;
  92. }
  93. public boolean onDisconnect(Address deadAddress) {
  94. Integer attached = attachedPermits.remove(deadAddress);
  95. if (attached != null && attached != 0) {
  96. available += attached;
  97. return true;
  98. }
  99. return false;
  100. }
  101. @Override
  102. public String toString() {
  103. return String.format("Semahpore{available=%d, global attached=%d}", available, getAttached());
  104. }
  105. }