Calculating size of Google Firestore documents - size

Firestore docs give details of how to manually calculate the stored size of a document, but there does not seem to be a function provided for this on any of document reference, snapshot, or metadata.
Before I attempt to use my own calculation, does anyone know of an official or unofficial function for this?
Here is my (completely untested) first cut for such a function from my interpretation of the docs at https://firebase.google.com/docs/firestore/storage-size
function calcFirestoreDocSize(collectionName, docId, docObject) {
let docNameSize = encodedLength(collectionName) + 1 + 16
let docIdType = typeof(docId)
if(docIdType === 'string') {
docNameSize += encodedLength(docId) + 1
} else {
docNameSize += 8
}
let docSize = docNameSize + calcObjSize(docObject)
return docSize
}
function encodedLength(str) {
var len = str.length;
for (let i = str.length - 1; i >= 0; i--) {
var code = str.charCodeAt(i);
if (code > 0x7f && code <= 0x7ff) {
len++;
} else if (code > 0x7ff && code <= 0xffff) {
len += 2;
} if (code >= 0xDC00 && code <= 0xDFFF) {
i--;
}
}
return len;
}
function calcObjSize(obj) {
let key;
let size = 0;
let type = typeof obj;
if(!obj) {
return 1
} else if(type === 'number') {
return 8
} else if(type === 'string') {
return encodedLength(obj) + 1
} else if(type === 'boolean') {
return 1
} else if (obj instanceof Date) {
return 8
} else if(obj instanceof Array) {
for(let i = 0; i < obj.length; i++) {
size += calcObjSize(obj[i])
}
return size
} else if(type === 'object') {
for(key of Object.keys(obj)) {
size += encodedLength(key) + 1
size += calcObjSize(obj[key])
}
return size += 32
}
}

In Android, if you want to check the size of a document against the maximum of 1 MiB (1,048,576 bytes), there is a library that can help you with that:
https://github.com/alexmamo/FirestoreDocument-Android/tree/master/firestore-document
In this way, you'll be able to always stay below the limit. The algorithm behind this library is the one that is explained in the official documentation regarding the Storage Size.

Related

Variable interator in for cycle

This is my example
for (i in array.indices)
{
if (array[i] == 10)
{
i -= 2//have error here
}
}
How can i make 'i' variable mutable?
You can't. Use while loop instead:
var i = 0
while (i < array.size) {
if (array[i] == 10) {
i -= 2
}
...
i++
}

How do I use a script to fill-color-yellow all of certain numbers I choose in google sheets?

I want to fill-color-yellow all of the prime numbers (within a certain range) in a google spreadsheet that I am working on. I don't even know where to begin.
function isPrime(value) {
for(var i = 2; i < value; i++) {
if(value % i === 0) {
return false;
}
}
return value > 1;
}
function testcolorPrimes()
{
colorPrimes('#ffff00');
}
function colorPrimes(color)
{
var ss=SpreadsheetApp.getActiveSpreadsheet();
var sht=ss.getSheetByName('colorprimes');
var rng=sht.getDataRange();
var rngA=rng.getValues();
for(var i=0;i<rngA.length;i++)
{
for(var j=0;j<rngA[i].length;j++)
{
if(!isNaN(rngA[i][j]))
{
if(isPrime(rngA[i][j]))
{
var range = sht.getRange(i+1, j+1).setBackground(color);
}
}
}
}
SpreadsheetApp.flush();
}

OQL syntax to refer to an object?

I find required objects in visualvm v1.3.8:
filter(heap.objects("java.lang.String"), "/hibernate\\.ejb\\.naming/(it.toString())")
they shown as:
java.lang.String#32669 - hibernate.ejb.naming_strategy_delegator
java.lang.String#34021 - hibernate.ejb.naming_strategy
java.lang.String#39522 - hibernate.ejb.naming_strategy_delegator
How can I refer to individual object from result set in OQL syntax? My attempts fail:
select heap.findObject("java.lang.String#34021")
select heap.findObject("#34021")
select heap.findObject("34021")
I may use trick with objectid(...):
map(filter(heap.objects("java.lang.String"),
"/hibernate\\.ejb\\.naming/.test(it.toString())"),
"{id: objectid(it), ref: it}")
and then reuse id with heap.findObject(4077522088) like syntax.
UPDATE 2022 Seems VisualVM enumerates each type separately and consistently so iteration of heap.objects("...", false) should lead to the right object:
function objectnum(clazz, num) {
if (typeof clazz !== 'string') { return undefined; }
if (Math.floor(num) !== num) {
var split = clazz.split("#");
if (split.length != 2) { return undefined; }
clazz = split[0];
num = parseInt(split[1]);
}
if (num < 1) { return undefined; }
var iter = heap.objects(clazz, false);
var i = 0;
while (iter.hasMoreElements()) {
i += 1;
var next = iter.nextElement();
if (num === i) { return next; }
}
return null;
}
// Usage:
objectnum("byte[]#123");
objectnum("char[]", 456);
objectnum("java.lang.String#789");

Error #2006: The supplied index is out of bounds

I keep getting
Error #2006: The supplied index is out of bounds.
at flash.display::DisplayObjectContainer/getChildAt()
at Main/onFrame()
This is mostly referring to this part of my code
else if (comp) //if completion is true
{
var animation = char.getChildAt(2); //
if (animation.currentFrame == animation.totalFrames)
{
animation.stop();
addChild(end);
My animation that I am pulling at the second frame also isn't running at all, though I have checked the symbol and the frames within it, and it should work fine. I'm pretty new to code and this is what I have been taught so far.
This is the rest of my code here.
We are supposed to make a basic game where our character walks to a power up and does a power up animation, followed by an end game title.
package
{
import flash.display.MovieClip;
import fl.motion.easing.Back;
import flash.sampler.Sample;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
public class Main extends MovieClip
{
var bg:Background;
var b:Bubbles;
var b2:Bubbles;
var s:Seaweed;
var pressingRight:Boolean = false;
var pressingLeft:Boolean = false;
var comp:Boolean = false;
var speed:int = 10;
var char:Character;
var pu:PowerUp;
var hit:hit1
var end:EndGame;
public function Main()
{
bg = new Background;
addChild(bg);
char = new Character();
addChild(char);
char.x = stage.stageWidth/2;
char.y = 488;
b = new Bubbles();
addChild(b);
b2 = new Bubbles();
addChild(b2);
b2.y = +b2.height;
s = new Seaweed();
addChild(s);
pu = new PowerUp();
addChild(pu);
pu.x = 200;
pu.y = 450;
pu.height = 50;
pu.scaleX = pu.scaleY;
pu.gotoAndStop("SPIN");
hit = new hit1;
addChild(hit);
hit.x = char.x
hit.y = char.y - 50
end = new EndGame();
end.x = stage.stageWidth/2;
end.y = stage.stageHeight/2;
stage.addEventListener(Event.ENTER_FRAME, onFrame);
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
stage.addEventListener(KeyboardEvent.KEY_UP, keyReleased);
}//main()
public function onFrame(e:Event)
{
if (!comp)
//Bubble Movement
b.y -= 1;
b2.y -= 1;
if (b.y >= stage.stageHeight)
{
b.y = b2.y + bg.height;
}
else if (b2.y >= stage.stageHeight)
{
b2.y = b.y + b2.height;
}
//Background & Character Movement
if (pressingRight && char.x < stage.stageWidth/2)
{
char.x += speed * 0.4
}
else if (pressingRight == true && (bg.width + bg.x) > stage.stageWidth)
{
bg.x -= speed * 0.4;
s.x -= speed * 0.6;
pu.x -= speed * 0.4;
}
else if (pressingRight == true)
{
char.x += speed * 0.4;
}
if (pressingLeft == true && char.x > stage.stageWidth/2)
{
char.x -= speed * 0.4;
}
else if (pressingLeft == true && bg.x <0)
{
bg.x += speed * 0.4;
s.x += speed * 0.6;
pu.x += speed * 0.4;
}
else if (pressingLeft)
{
char.x -= speed * 0.4;
}
//Boundaries
if (char.x > stage.stageWidth)
{
char.x = stage.stageWidth;
}
else if (char.x < 0)
{
char.x = 0;
}
//Character Looking Directions
if (pressingLeft == true)
{
char.scaleX = -1;
hit.x = char.x
}
if (pressingRight == true)
{
char.scaleX = 1;
hit.x = char.x
}
//Character Movements
if (pressingRight || pressingLeft)
{
char.gotoAndStop("WALK");
}
else if (!pressingRight || !pressingLeft)
{
char.gotoAndStop("IDLE");
}
//Getting the Power up
if (pu.hitTestObject(hit))
{
char.gotoAndStop("POWER");
comp = true;
pu.gotoAndStop("GONE");
}
// !end
else if (comp) //if completion is true
{
var animation = char.getChildAt(2); //
if (animation.currentFrame == animation.totalFrames)
{
animation.stop();
addChild(end);
}
}//Comp
}//onFrame
public function keyPressed(k:KeyboardEvent)
{
if (k.keyCode == Keyboard.RIGHT)
{
pressingRight = true;
}
else if (k.keyCode == Keyboard.LEFT)
{
pressingLeft = true;
}
} // keyPressed()
public function keyReleased(k:KeyboardEvent)
{
if (k.keyCode == Keyboard.RIGHT)
{
pressingRight = false;
}
else if (k.keyCode == Keyboard.LEFT)
{
pressingLeft = false;
}
} // keyReleased()
}//public class()
}//package()
If you're using a language with zero-based indexing (where array indexes start at 0, not 1) Then this could be the problem.
Frame 1 would be at index [0] and frame 2 would be at index [1].
If you have 2 frames for example and try to access the frame at index[2] you are stepping beyond the bounds of your array and this is probably why you are getting that error message.

How to access Topic name from pdfs using poppler?

I am using poppler, and I want to access topic or headings of a particular page number using poppler, so please tell me how to do this using poppler.
Using the glib API. Don't know which API you want.
I'm pretty sure there is no topic/heading stored with a particular page.
You have to walk the index, if there is one.
Walk the index with backtracking. If you are lucky, each index node contains a PopplerActionGotoDest (check type!).
You can grab the title from the PopplerAction object (gchar *title) and get the page number from the included PopplerDest (int page_num).
page_num should be the first page of the section.
Assuming your PDF has an index containing PopplerActionGotoDest objects.
Then you simply walk it, checking for the page_num.
If page_num > searched_num, go back one step.
When you are at the correct parent, walk the childs. This should give you the best match.
I just made some code for it:
gchar* getTitle(PopplerIndexIter *iter, int num, PopplerIndexIter *last,PopplerDocument *doc)
{
int cur_num = 0;
int next;
PopplerAction * action;
PopplerDest * dest;
gchar * title = NULL;
PopplerIndexIter * last_tmp;
do
{
action = poppler_index_iter_get_action(iter);
if (action->type != POPPLER_ACTION_GOTO_DEST) {
printf("No GOTO_DEST!\n");
return NULL;
}
//get page number of current node
if (action->goto_dest.dest->type == POPPLER_DEST_NAMED) {
dest = poppler_document_find_dest (doc, action->goto_dest.dest->named_dest);
cur_num = dest->page_num;
poppler_dest_free(dest);
} else {
cur_num = action->goto_dest.dest->page_num;
}
//printf("cur_num: %d, %d\n",cur_num,num);
//free action, as we don't need it anymore
poppler_action_free(action);
//are there nodes following this one?
last_tmp = poppler_index_iter_copy(iter);
next = poppler_index_iter_next (iter);
//descend
if (!next || cur_num > num) {
if ((!next && cur_num < num) || cur_num == num) {
//descend current node
if (last) {
poppler_index_iter_free(last);
}
last = last_tmp;
}
//descend last node (backtracking)
if (last) {
/* Get the the action and do something with it */
PopplerIndexIter *child = poppler_index_iter_get_child (last);
gchar * tmp = NULL;
if (child) {
tmp = getTitle(child,num,last,doc);
poppler_index_iter_free (child);
} else {
action = poppler_index_iter_get_action(last);
if (action->type != POPPLER_ACTION_GOTO_DEST) {
tmp = NULL;
} else {
tmp = g_strdup (action->any.title);
}
poppler_action_free(action);
poppler_index_iter_free (last);
}
return tmp;
} else {
return NULL;
}
}
if (cur_num > num || (next && cur_num != 0)) {
// free last index_iter
if (last) {
poppler_index_iter_free(last);
}
last = last_tmp;
}
}
while (next);
return NULL;
}
getTitle gets called by:
for (i = 0; i < num_pages; i++) {
iter = poppler_index_iter_new (document);
title = getTitle(iter,i,NULL,document);
poppler_index_iter_free (iter);
if (title) {
printf("title of %d: %s\n",i, title);
g_free(title);
} else {
printf("%d: no title\n",i);
}
}