private Frame(int start, int end, int leftbound, int rightbound, Frame parent, int frameId) { this.frameId = frameId; this.start = start; this.end = end; this.leftbound = leftbound; this.rightbound = rightbound; this.parent = parent; }
public Frame(int start, int end) { this.frameId = currentFrameId++; this.start = start; this.end = end; this.leftbound = start; this.rightbound = end; this.parent = null; }
public HashSet<int> AddNewGroup(int origId, int currentId, int k, AnonyGroupEntry anonGroups, Dictionary<int, SubTreeEntry> subtree, ref List<int> swapList) { PrivacyGlobal global = (PrivacyGlobal)Global.getInstance(); HashSet<int> newgroup = new HashSet<int>(); swapList = new List<int>(); int step; //预处理 复制一个相同的数组 HashSet<Frame> lframes = new HashSet<Frame>(); HashSet<Frame> lallframes = new HashSet<Frame>(); List<FrameNode> lnodes = new List<FrameNode>(); //建立映射关系 Dictionary<FrameNode, int> nodeIndexMapping = new Dictionary<FrameNode, int>(); Dictionary<int, int> nodeIdIndexMapping = new Dictionary<int, int>(); Dictionary<int, Frame> frameIdIndexMapping = new Dictionary<int, Frame>(); foreach (Frame frame in allframes) { Frame framecopy = (Frame)frame.Clone(); if (frames.Contains(frame)) { lframes.Add(framecopy); frameIdIndexMapping.Add(frame.frameId, framecopy); } lallframes.Add(framecopy); } for (int i = 0; i < nodes.Count; i++) { lnodes.Add((FrameNode)nodes[i].Clone()); FrameNode node = lnodes[i]; nodeIndexMapping.Add(node, i); nodeIdIndexMapping.Add(node.nodeId, i); } //步骤1 将框内所有已加入k-匿名组的节点置为不可用,这个对框结构没有影响 step = 1; jointNodeIds = new HashSet<int>(); foreach (int c in subtree.Keys) { if (anonGroups.subUnavailAnonyNodes.ContainsKey(c + "-" + k)) { foreach (int nodeId in anonGroups.subUnavailAnonyNodes[c + "-" + k]) jointNodeIds.Add(nodeId); } } STEP2: //步骤2 将非本节点子树的节点去掉,将原始框分割为新的框集,这个会减少框的大小 if (step < 4) step = 2; childNodeIds = new HashSet<int>(); foreach (FrameNode node in lnodes) { int nodeId = node.nodeId; if (subtree.ContainsKey(nodeId) || currentId == nodeId) { childNodeIds.Add(nodeId); continue; } foreach (KeyValuePair<int, SubTreeEntry> pair in subtree) { if (pair.Value.subnodes.Contains(nodeId)) { childNodeIds.Add(nodeId); break; } } } //步骤3 将原始节点放到框的可用最左侧 if(step<4) step = 3; int origIndex = nodeIdIndexMapping[origId]; FrameNode origNode = lnodes[origIndex]; Frame origFrame = frameIdIndexMapping[origNode.belongedFrameId]; for (int i = origFrame.start; i <= origFrame.end; i++) { //如果框内有节点不是自己的子节点,则将请求转发到父节点,否则可能会分裂该框,造成不一致性 if (!IsChild(lnodes[i].nodeId)) return null; } int leftIndex = origFrame.start; do { if ((lnodes[leftIndex].anchor == false || origId == lnodes[leftIndex].nodeId) && IsNodeAvailable(lnodes[leftIndex].nodeId)) break; leftIndex++; } while (leftIndex < origIndex); if (leftIndex < origIndex && IsNodeAvailable(lnodes[leftIndex].nodeId)) { //swap SwapNodes(origIndex, leftIndex, lnodes, nodeIndexMapping, nodeIdIndexMapping); origIndex = nodeIdIndexMapping[origId]; origNode = lnodes[origIndex]; origFrame = frameIdIndexMapping[origNode.belongedFrameId]; Console.WriteLine("swap nodes"); } lnodes[leftIndex].anchor = true; DumpFrames(lframes, lnodes, frameIdIndexMapping, currentId); //如果本节点已在匿名组内,则直接返回。这里不在开始就处理是因为要将其置于框最左侧 foreach (int c in subtree.Keys) { if (anonGroups.subUnavailAnonyNodes.ContainsKey(c + "-" + k) && anonGroups.subUnavailAnonyNodes[c + "-" + k].Contains(origId)) { Console.WriteLine("READER{0} is already in {1}-group", origId, k); Utility.CopyHashSet(newgroup, anonGroups.groups[k]); goto DONE; } } //之前没有判断子树节点,是因为没有确定本节点是否已经在现有匿名组中了 //自己子树的节点小于 if (childNodeIds.Count < k) return null; //如果建组策略为严格的,那么将Ai所在全部匿名组的交集中全部元素为自由节点的框置于Ai所在框后 //if (global.isBuildGroupPolicyStrict == true) //{ //求Ai所在全部匿名组的交集Gmin(Ai) //如果存在Gmin(Ai)的子集构成一个框,且框内所有节点为自由的 //检查交集中每一个框 PrivacyReader origReader = (PrivacyReader)global.readers[origId]; HashSet<int> insection = origReader.GetGroupInsection(); //更正1:不是origNode的匿名组交集,而是其所在框的父框,因为该框和与之交换的框都不能跳出父框 //检查父框中所有框,找出全部为自由节点的框,与其后的非全为自由节点的框交换 //更正2:应该还是交集,新的组不能跳出这个交集外 HashSet<Frame> checkFrames = new HashSet<Frame>(); //foreach (int nodeId in insection) for (int nodeIndex = origFrame.leftbound; nodeIndex <= origFrame.rightbound; ) { FrameNode node = lnodes[nodeIndex]; //FrameNode node = lnodes[nodeIdIndexMapping[nodeId]]; if (!IsNodeAvailable(node.nodeId)) { nodeIndex++; continue; } Frame frame = frameIdIndexMapping[node.belongedFrameId]; //属于同一个框,返回 if (node.belongedFrameId == origFrame.frameId) { nodeIndex = frame.end + 1; continue; } if (checkFrames.Contains(frame)) continue; checkFrames.Add(frame); bool isAllFreeFrame = IsAllFreeFrame(frame, lnodes); //如果该框全部由自由节点构成 //则将该框与Ai所在框后的第一个非全自由节点的框交换 //自由框可利用的前提是同在一个组内 if (isAllFreeFrame == true && frame.leftbound==origFrame.leftbound && frame.rightbound == origFrame.rightbound) { Frame nextNotAllFreeFrame = GetNextNotAllFreeFrame(origFrame, lnodes, lframes, frameIdIndexMapping, origFrame.rightbound); //两框可交换的前提是其均在同一个组内 if (nextNotAllFreeFrame != null && nextNotAllFreeFrame != origFrame && (frame.start - nextNotAllFreeFrame.start) * (nextNotAllFreeFrame.start - origFrame.start) > 0 && nextNotAllFreeFrame.leftbound == frame.leftbound && nextNotAllFreeFrame.rightbound == frame.rightbound) { SwapFrames(nextNotAllFreeFrame, frame, nodeIndexMapping, nodeIdIndexMapping, frameIdIndexMapping, lframes, lnodes); origIndex = nodeIdIndexMapping[origId]; origNode = lnodes[origIndex]; origFrame = frameIdIndexMapping[origNode.belongedFrameId]; DumpFrames(lframes, lnodes, frameIdIndexMapping, currentId); } break; } nodeIndex = frame.end + 1; } /*} else//非严格,将前述交集的条件放宽到全集并执行 { //TODO }*/ //第三步从Ai开始先左后右依次选择k个元素生成新的框I,将其余元素组成新框II,如果被选择节点与Ai同在一个框内,则其匿名组是一致的,直接将其加入 newgroup.Clear(); int xi = origIndex; int start = xi; while (xi >= origFrame.start && newgroup.Count < k) { start = xi; if(IsNodeAvailable(lnodes[xi].nodeId)) newgroup.Add(lnodes[xi].nodeId); xi--; } //还不够,往右走 xi = origIndex; int end = xi; while (xi <= origFrame.end && newgroup.Count < k) { end = xi; if (IsNodeAvailable(lnodes[xi].nodeId) && !newgroup.Contains(lnodes[xi].nodeId)) newgroup.Add(lnodes[xi].nodeId); xi++; } //如果在origFrame中还是没有足够的节点,但origFrame后面还有全部为自由节点的框,可与之组合成新组,则也加进来 Frame lastFrame = null; lastFrame = frameIdIndexMapping[lnodes[end].belongedFrameId]; for (int nodeIndex = origFrame.end + 1; nodeIndex<lnodes.Count&& newgroup.Count < k; ) { Frame currentFrame = frameIdIndexMapping[lnodes[nodeIndex].belongedFrameId]; //如果两个frame不在同一个父frame中,则放弃 if (currentFrame.parent != lastFrame.parent) break; //否则如果非全部是自由节点,放弃 if (IsAllFreeFrame(currentFrame, lnodes) == false //&& GetAvailFrameNodeCount(currentFrame, lnodes, k)+newgroup.Count<k ) break; //否则可添加节点 xi = nodeIndex; while (xi <= currentFrame.end && newgroup.Count < k) { end = xi; if (IsNodeAvailable(lnodes[xi].nodeId) && !newgroup.Contains(lnodes[xi].nodeId)) newgroup.Add(lnodes[xi].nodeId); xi++; } lastFrame = currentFrame.parent; nodeIndex = currentFrame.end + 1; } //如果第三步不成功,说明原框中没有足够的可用节点,则进行第四步:选择有最多可用元素的框中的一个可用节点与Ai交换,重新执行第二步 if (newgroup.Count < k) { if (step == 3) goto STEP3FAIL; else if (step == 4) goto STEP4FAIL; } //原始框最左边没有充满,新分出一个框来 if (origFrame.start < start) { Frame newframe3 = new Frame(origFrame.start, start - 1); newframe3.leftbound = origFrame.start; newframe3.rightbound = origFrame.end; newframe3.parent = origFrame; for (int i = origFrame.start; i <= start - 1; i++) lnodes[i].belongedFrameId = newframe3.frameId; lframes.Add(newframe3); lallframes.Add(newframe3); } //否则考察右边界 Frame endframe = frameIdIndexMapping[lnodes[end].belongedFrameId]; //如果在原框内,则原框分出两个框来 if (origFrame.end > end) { Frame newframe1 = new Frame(start, end); newframe1.leftbound = origFrame.start; newframe1.rightbound = origFrame.end; newframe1.parent = origFrame; for (int i = newframe1.start; i <= newframe1.end; i++) lnodes[i].belongedFrameId = newframe1.frameId; lframes.Add(newframe1); lallframes.Add(newframe1); Frame newframe2 = new Frame(end + 1, origFrame.end); FrameNode nnode = nodes[end]; Frame nframe = frameIdIndexMapping[nnode.belongedFrameId]; newframe2.leftbound = origFrame.start; newframe2.rightbound = nframe.rightbound; newframe2.parent = nframe; for (int i = newframe2.start; i <= newframe2.end; i++) lnodes[i].belongedFrameId = newframe2.frameId; lframes.Add(newframe2); lallframes.Add(newframe2); lframes.Remove(origFrame); } else { //否则,原框不变,寻找右边界所在的框,需要新建两个子框 //建立一个虚拟的框,作为新建框的父框 Frame virtualFrame = new Frame(start, end); virtualFrame.leftbound = endframe.leftbound; virtualFrame.rightbound = endframe.rightbound; virtualFrame.parent = endframe.parent; lallframes.Add(virtualFrame); //找到虚拟框下面的框,该框需要改变结构 foreach (Frame oframe in lallframes) { //如果存在一个框的父节点为虚拟框的父节点,则将其置于虚拟框之下 if (oframe.parent!= null && oframe.parent.frameId == endframe.parent.frameId && oframe.frameId != endframe.frameId) { oframe.parent = virtualFrame; oframe.leftbound = virtualFrame.start; oframe.rightbound = virtualFrame.end; break; } } //原框作为新框的子框,其边和边界需要变化 for (int j = start; j < end;) { FrameNode onode = nodes[j]; Frame oframe = frameIdIndexMapping[onode.belongedFrameId]; if (oframe.end > end) { //新纳入的框边界变成 Frame newframe1 = new Frame(oframe.start, end); newframe1.leftbound = start; newframe1.rightbound = end; newframe1.parent = virtualFrame; for (int i = newframe1.start; i <= newframe1.end; i++) lnodes[i].belongedFrameId = newframe1.frameId; lframes.Add(newframe1); lallframes.Add(newframe1); //剩下的框边界不变 Frame newframe2 = new Frame(end + 1, oframe.end); newframe2.leftbound = endframe.leftbound; newframe2.rightbound = endframe.rightbound; newframe2.parent = endframe.parent; for (int i = newframe2.start; i <= newframe2.end; i++) lnodes[i].belongedFrameId = newframe2.frameId; lframes.Add(newframe2); lallframes.Add(newframe2); lframes.Remove(oframe); lallframes.Remove(oframe); } j = oframe.end + 1; } } DONE: //重新复制回去 for (int i = 0; i < nodes.Count; i++) { nodes[i] = lnodes[i]; } DumpFrames(lframes, lnodes, currentId); this.frames = new HashSet<Frame>(); this.allframes = new HashSet<Frame>(); foreach(Frame frame in lframes) frames.Add(frame); foreach (Frame frame in lallframes) allframes.Add(frame); return newgroup; //如果第三步不成功,说明原框中没有足够的可用节点,则进行第四步 STEP3FAIL: //第四步:选择有最多可用元素的框中的一个可用节点与Ai交换,重新执行第二步 step = 4; Frame mostFreeNodeFrame = FindMostFreeNodeFrame(lnodes[origIndex], lframes); if (mostFreeNodeFrame == null) goto STEP4FAIL; int fnodeIndex = FindAFreeNode(mostFreeNodeFrame); swapList.Add(lnodes[fnodeIndex].nodeId); SwapNodes(origIndex, fnodeIndex, lnodes, nodeIndexMapping, nodeIdIndexMapping); origIndex = nodeIdIndexMapping[origId]; DumpFrames(lframes, lnodes, frameIdIndexMapping, currentId); goto STEP2; //第四步不成功,说明Am没有足够多的可用节点构造k-匿名组 STEP4FAIL: //第五步中将Ai退出所有组,将请求发送给Am的父节点 step = 5; return null; }
bool IsAllFreeFrame(Frame frame, List<FrameNode> lnodes) { bool isFreeFrame = true; for (int i = frame.start; i <= frame.end; i++) { FrameNode node1 = lnodes[i]; //if (node1.anchor == true && IsNodeAvailable(node1.nodeId)) if (node1.anchor == true) { isFreeFrame = false; break; } } return isFreeFrame; }
int GetFreeNodes(Frame frame) { int fnodes = 0; for(int i = frame.start;i<frame.end;i++) { if(nodes[i].anchor == false) fnodes ++; } return fnodes; }
int GetAvailFrameNodeCount(Frame frame, List<FrameNode> lnodes, int k) { int count = 0; for (int i = frame.start; i <= frame.end; i++) { if (IsNodeAvailable(i)) count++; } return count; }
int FindAFreeNode(Frame frame) { for (int i = frame.start; i < frame.end; i++) { if (nodes[i].anchor == false) return i; } return -1; }
public void SwapFrames(Frame frame1, Frame frame2, Dictionary<FrameNode, int> nodeIndexMapping, Dictionary<int, int> nodeIdIndexMapping, Dictionary<int, Frame> frameIdIndexMapping, HashSet<Frame> lframes, List<FrameNode> lnodes) { if (frame1.frameId == frame2.frameId) return; Frame foreframe, backframe = null; if (frame1.start < frame2.start) { foreframe = frame1; backframe = frame2; } else { foreframe = frame2; backframe = frame1; } HashSet<Frame> checkedframes = new HashSet<Frame>(); //先把两个frame腾出地方来 List<FrameNode> oforeframe = new List<FrameNode>(); List<FrameNode> obackframe = new List<FrameNode>(); for (int i = foreframe.start; i <= foreframe.end; i++) oforeframe.Add(lnodes[i]); for (int i = backframe.start; i <= backframe.end; i++) obackframe.Add(lnodes[i]); int forestart = foreframe.start; int backend = backframe.end; int forecount = foreframe.end-foreframe.start; int backcount = backframe.end-backframe.start; if (forecount<backcount) { int offset = backcount - forecount; for (int i = backframe.start-1; i > foreframe.end; i--) { lnodes[i + offset] = lnodes[i]; Frame framex = frameIdIndexMapping[lnodes[i].belongedFrameId]; if (!checkedframes.Contains(framex)) { checkedframes.Add(framex); framex.start = framex.start + offset; framex.end = framex.end + offset; } } } else { int offset = forecount - backcount; for (int i = foreframe.end+1; i < backframe.start; i++) { lnodes[i-offset] = lnodes[i]; Frame framex = frameIdIndexMapping[lnodes[i].belongedFrameId]; if (!checkedframes.Contains(framex)) { checkedframes.Add(framex); framex.start = framex.start - offset; framex.end = framex.end - offset; } } } //DumpNodes(); //将前面的框放到后面 for (int i = backframe.end-forecount, j = 0; i <= backframe.end; i++, j++) { lnodes[i] = oforeframe[j]; } //DumpNodes(); //将后面的框放到前面 for (int i = foreframe.start, j = 0; i <= foreframe.start+backcount; i++, j++) { lnodes[i] = obackframe[j]; } //DumpNodes(); //新的框的起始位置 foreframe.start = backend - (oforeframe.Count - 1); foreframe.end = backend; backframe.start = forestart; backframe.end = forestart + (obackframe.Count - 1); //update indexes for (int i = 0; i < lnodes.Count; i++) { FrameNode tnode = lnodes[i]; nodeIndexMapping[tnode] = i; nodeIdIndexMapping[tnode.nodeId] = i; } }
public void Init(HashSet<int> list, int initNodeId, bool IsStrictPolicy) { Frame newFrame = new Frame(0, list.Count-1); this.frames.Add(newFrame); this.allframes.Add(newFrame); this.nodes.Add(new FrameNode(initNodeId, true, newFrame.frameId)); foreach (int nodeId in list) { if(nodeId != initNodeId) this.nodes.Add(new FrameNode(nodeId, false, newFrame.frameId)); } this.IsStrictPolicy = IsStrictPolicy; }
public Frame GetNextNotAllFreeFrame(Frame frame, List<FrameNode> lnodes, HashSet<Frame> lframes, Dictionary<int, Frame> frameIdIndexMapping, int rightbound) { if (frame.end + 1 >= lnodes.Count) return null; int leftbound = frame.end + 1; int currentindex = leftbound; while(currentindex<=rightbound) { FrameNode node = lnodes[currentindex]; Frame nframe = frameIdIndexMapping[node.belongedFrameId]; bool isAllFreeFrame = IsAllFreeFrame(frame, lnodes); if (!isAllFreeFrame) return nframe; currentindex = nframe.end + 1; continue; } return null; }
public object Clone() { Frame newFrame = new Frame(this.start, this.end, this.leftbound, this.rightbound, this.parent, this.frameId); return newFrame; }