@Override public int size(Response response) { return JsonUtils.size(response.getEntityData()); }
public static int size(TranslatedDoc doc) { return JsonUtils.size(doc.doc.getRoot()); }
@Override public int size(Response response) { return JsonUtils.size(response.getEntityData()); }
public static int size(JsonDoc doc) { return JsonUtils.size(doc.getRoot()); }
/** * An approximation of how much space will a JsonNode take in memory. Does not take jvm optimizations * or architecture into account. Useful only to compare JsonNodes with each other. * * @param node * @return */ public static int size(JsonNode node) { if (node == null) { return 0; } int size = 0; if (node instanceof ArrayNode) { for (Iterator<JsonNode> elements = ((ArrayNode) node).elements(); elements.hasNext();) { size += size(elements.next()); } } else if (node instanceof ObjectNode) { for (Iterator<Map.Entry<String, JsonNode>> fields = ((ObjectNode) node).fields(); fields.hasNext();) { Map.Entry<String, JsonNode> field = fields.next(); size += field.getKey().length(); size += size(field.getValue()); } } else if (node instanceof NumericNode) { size += 4; } else { size += node.asText().length(); } return size; }
/** * An approximation of how much space will a JsonNode take in memory. Does not take jvm optimizations * or architecture into account. Useful only to compare JsonNodes with each other. * * @param node * @return */ public static int size(JsonNode node) { if (node == null) { return 0; } int size = 0; if (node instanceof ArrayNode) { for (Iterator<JsonNode> elements = ((ArrayNode) node).elements(); elements.hasNext();) { size += size(elements.next()); } } else if (node instanceof ObjectNode) { for (Iterator<Map.Entry<String, JsonNode>> fields = ((ObjectNode) node).fields(); fields.hasNext();) { Map.Entry<String, JsonNode> field = fields.next(); size += field.getKey().length(); size += size(field.getValue()); } } else if (node instanceof NumericNode) { size += 4; } else { size += node.asText().length(); } return size; }
public void setResultSizeThresholds(int maxResultSetSizeB, int warnResultSetSizeB, final QueryExpression forQuery) { this.memoryMonitor = new MemoryMonitor<>((doc) -> { int size = JsonUtils.size(doc.getRoot()); // account for docs copied by DocCtx.startModifications() if (doc.getOriginalDocument() != null) { size += JsonUtils.size(doc.getOriginalDocument().getRoot()); } if (doc.getUpdatedDocument() != null) { size += JsonUtils.size(doc.getUpdatedDocument().getRoot()); } return size; }); memoryMonitor.registerMonitor(new ThresholdMonitor<DocCtx>(maxResultSetSizeB, (current, threshold, doc) -> { throw Error.get(MongoCrudConstants.ERROR_RESULT_SIZE_TOO_LARGE, current+"B > "+threshold+"B"); })); memoryMonitor.registerMonitor(new ThresholdMonitor<DocCtx>(warnResultSetSizeB, (current, threshold, doc) -> { LOGGER.warn("{}: query={}, responseDataSizeB={}", MongoCrudConstants.WARN_RESULT_SIZE_LARGE,forQuery, current); })); }
/** * Threshold is expressed in bytes. This is just an approximation, see @{link {@link JsonUtils#size(JsonNode)} for details. * * @param maxResultSetSizeB error when this threshold is breached * @param warnResultSetSizeB log a warning when this threshold is breached * @param forRequest request which resulted in this response, for logging purposes * @param initialDataSizeB initial size in memory (memory occupied by prior operations) */ public void setQueuedHooksSizeThresholds(int maxQueuedHooksSizeB, int warnQueuedHooksSizeB, final QueryExpression query, int initialDataSizeB) { this.monitor = new MemoryMonitor<>((node) -> JsonUtils.size(node), initialDataSizeB); this.monitor.registerMonitor(new ThresholdMonitor<>(warnQueuedHooksSizeB, (current, threshold, node) -> { LOGGER.warn("crud:ResultSizeIsLarge: query={}, queuedHooksSizeB={} threshold={}", query, current, threshold); })); this.monitor.registerMonitor(new ThresholdMonitor<>(maxQueuedHooksSizeB, (current, threshold, node) -> { throw Error.get(Response.ERR_RESULT_SIZE_TOO_LARGE, current+"B > "+threshold+"B (during hook processing)"); })); }
/** * Threshold is expressed in bytes. This is just an approximation, see @{link {@link JsonUtils#size(JsonNode)} for details. * * @param maxResultSetSizeB error when this threshold is breached * @param warnResultSetSizeB log a warning when this threshold is breached * @param forRequest request which resulted in this response, for logging purposes * @param initialDataSizeB initial size in memory (memory occupied by prior operations) */ public void setQueuedHooksSizeThresholds(int maxQueuedHooksSizeB, int warnQueuedHooksSizeB, final QueryExpression query, int initialDataSizeB) { this.monitor = new MemoryMonitor<>((node) -> JsonUtils.size(node), initialDataSizeB); this.monitor.registerMonitor(new ThresholdMonitor<>(warnQueuedHooksSizeB, (current, threshold, node) -> { LOGGER.warn("crud:ResultSizeIsLarge: query={}, queuedHooksSizeB={} threshold={}", query, current, threshold); })); this.monitor.registerMonitor(new ThresholdMonitor<>(maxQueuedHooksSizeB, (current, threshold, node) -> { throw Error.get(Response.ERR_RESULT_SIZE_TOO_LARGE, current+"B > "+threshold+"B (during hook processing)"); })); }
/** * Result set size threshold is expressed in bytes. This is just an approximation, see @{link {@link JsonUtils#size(JsonNode)} for details. * * @param maxResultSetSizeB error when this threshold is breached * @param warnResultSetSizeB log a warning when this threshold is breached * @param forRequest request which resulted in this response, for logging purposes */ public void setResultSizeThresholds(int maxResultSetSizeB, int warnResultSetSizeB, final Request forRequest) { this.memoryMonitor = new MemoryMonitor<>((jsonNode) -> JsonUtils.size(jsonNode)); // Order is significant – warn first for request in log output. memoryMonitor.registerMonitor(new ThresholdMonitor<JsonNode>(warnResultSetSizeB, (current, threshold, doc) -> { LOGGER.warn("crud:ResultSizeIsLarge: request={}, responseDataSizeB={} threshold={}", forRequest, current, threshold); })); memoryMonitor.registerMonitor(new ThresholdMonitor<JsonNode>(maxResultSetSizeB, (current, threshold, doc) -> { // empty data // returning incomplete result set could be useful, but also confusing and thus dangerous // the counts - matchCount, modifiedCount - are unmodified setEntityData(JsonNodeFactory.instance.arrayNode()); setStatus(OperationStatus.ERROR); throw Error.get(ERR_RESULT_SIZE_TOO_LARGE, current + "B > " + threshold + "B"); })); }
/** * Result set size threshold is expressed in bytes. This is just an approximation, see @{link {@link JsonUtils#size(JsonNode)} for details. * * @param maxResultSetSizeB error when this threshold is breached * @param warnResultSetSizeB log a warning when this threshold is breached * @param forRequest request which resulted in this response, for logging purposes */ public void setResultSizeThresholds(int maxResultSetSizeB, int warnResultSetSizeB, final Request forRequest) { this.memoryMonitor = new MemoryMonitor<>((jsonNode) -> JsonUtils.size(jsonNode)); // Order is significant – warn first for request in log output. memoryMonitor.registerMonitor(new ThresholdMonitor<JsonNode>(warnResultSetSizeB, (current, threshold, doc) -> { LOGGER.warn("crud:ResultSizeIsLarge: request={}, responseDataSizeB={} threshold={}", forRequest, current, threshold); })); memoryMonitor.registerMonitor(new ThresholdMonitor<JsonNode>(maxResultSetSizeB, (current, threshold, doc) -> { // empty data // returning incomplete result set could be useful, but also confusing and thus dangerous // the counts - matchCount, modifiedCount - are unmodified setEntityData(JsonNodeFactory.instance.arrayNode()); setStatus(OperationStatus.ERROR); throw Error.get(ERR_RESULT_SIZE_TOO_LARGE, current + "B > " + threshold + "B"); })); }